From fd969322ba13300acdb318861821bcb8f7c77ba0 Mon Sep 17 00:00:00 2001 From: niladic Date: Tue, 26 Jan 2021 19:55:26 +0100 Subject: [PATCH] Ajoute un champ de commentaire pour le support (utilisateur et groupe) (#938) --- app/controllers/CSVImportController.scala | 17 +++++++++----- app/controllers/GroupController.scala | 4 ++++ app/controllers/UserController.scala | 15 +++++++++---- app/models/User.scala | 17 ++++++++++++-- app/models/UserGroup.scala | 16 ++++++++++++-- app/models/formModels.scala | 3 ++- app/services/UserGroupService.scala | 6 +++-- app/services/UserService.scala | 6 +++-- app/views/editGroup.scala.html | 16 ++++++++++++++ app/views/editUser.scala.html | 17 ++++++++++++++ conf/evolutions/default/47.sql | 7 ++++++ public/stylesheets/main.css | 4 ---- test/browser/AnswerSpec.scala | 6 +++-- test/browser/ApplicationAccessSpec.scala | 27 +++++++++++++++-------- test/browser/ApplicationSpec.scala | 9 +++++--- test/browser/LoginSpec.scala | 3 ++- test/csv/CSVSpec.scala | 3 ++- 17 files changed, 138 insertions(+), 38 deletions(-) create mode 100644 conf/evolutions/default/47.sql diff --git a/app/controllers/CSVImportController.scala b/app/controllers/CSVImportController.scala index a72bae994..45c3ae831 100644 --- a/app/controllers/CSVImportController.scala +++ b/app/controllers/CSVImportController.scala @@ -136,7 +136,8 @@ case class CSVImportController @Inject() ( areaIds = group.group.areaIds, organisation = group.group.organisation, email = group.group.email, - publicNote = None + publicNote = None, + internalSupportComment = None ), users = group.users.map(user => CSVUserFormData( @@ -185,8 +186,12 @@ case class CSVImportController @Inject() ( }, Option.apply ), - "name" -> text(maxLength = 60), - "description" -> optional(text), + "name" -> text(maxLength = 60) + .transform[String](commonStringInputNormalization, commonStringInputNormalization), + "description" -> optional(text).transform[Option[String]]( + _.map(commonStringInputNormalization).filter(_.nonEmpty), + _.map(commonStringInputNormalization).filter(_.nonEmpty) + ), "insee-code" -> list(text), "creationDate" -> ignored(date), "area-ids" -> list(uuid) @@ -196,7 +201,8 @@ case class CSVImportController @Inject() ( _.exists(Organisation.isValidId) ), "email" -> optional(email), - "publicNote" -> ignored(Option.empty[String]) + "publicNote" -> ignored(Option.empty[String]), + "internalSupportComment" -> ignored(Option.empty[String]) )(UserGroup.apply)(UserGroup.unapply) private def importUsersAfterReviewForm(date: ZonedDateTime): Form[List[CSVUserGroupFormData]] = @@ -332,7 +338,8 @@ case class CSVImportController @Inject() ( newsletterAcceptationDate = None, phoneNumber = userData.user.phoneNumber, observableOrganisationIds = Nil, - sharedAccount = userData.user.name.nonEmpty + sharedAccount = userData.user.name.nonEmpty, + internalSupportComment = None ) ) } diff --git a/app/controllers/GroupController.scala b/app/controllers/GroupController.scala index c5887182c..03bcd5c23 100644 --- a/app/controllers/GroupController.scala +++ b/app/controllers/GroupController.scala @@ -228,6 +228,10 @@ case class GroupController @Inject() ( "publicNote" -> optional(text).transform[Option[String]]( _.map(commonStringInputNormalization).filter(_.nonEmpty), _.map(commonStringInputNormalization).filter(_.nonEmpty) + ), + "internalSupportComment" -> optional(text).transform[Option[String]]( + _.map(commonStringInputNormalization).filter(_.nonEmpty), + _.map(commonStringInputNormalization).filter(_.nonEmpty) ) )(UserGroup.apply)(UserGroup.unapply) ) diff --git a/app/controllers/UserController.scala b/app/controllers/UserController.scala index 65f21ec48..e26fec331 100644 --- a/app/controllers/UserController.scala +++ b/app/controllers/UserController.scala @@ -450,7 +450,8 @@ case class UserController @Inject() ( groupIds = user.groupIds, phoneNumber = user.phoneNumber, observableOrganisationIds = user.observableOrganisationIds, - sharedAccount = user.sharedAccount + sharedAccount = user.sharedAccount, + internalSupportComment = user.internalSupportComment ) ) val groups = groupService.allGroups @@ -565,7 +566,8 @@ case class UserController @Inject() ( groupIds = updatedUserData.groupIds.distinct, phoneNumber = updatedUserData.phoneNumber, observableOrganisationIds = updatedUserData.observableOrganisationIds.distinct, - sharedAccount = updatedUserData.sharedAccount + sharedAccount = updatedUserData.sharedAccount, + internalSupportComment = updatedUserData.internalSupportComment ) userService.update(userToUpdate).map { updateHasBeenDone => if (updateHasBeenDone) { @@ -649,7 +651,8 @@ case class UserController @Inject() ( newsletterAcceptationDate = None, phoneNumber = userToAdd.phoneNumber, observableOrganisationIds = Nil, - sharedAccount = userToAdd.sharedAccount + sharedAccount = userToAdd.sharedAccount, + internalSupportComment = None ) ) userService @@ -922,7 +925,11 @@ case class UserController @Inject() ( "groupIds" -> default(list(uuid), Nil), "phoneNumber" -> optional(text), "observableOrganisationIds" -> list(of[Organisation.Id]), - Keys.User.sharedAccount -> boolean + Keys.User.sharedAccount -> boolean, + "internalSupportComment" -> optional(text).transform[Option[String]]( + _.map(commonStringInputNormalization).filter(_.nonEmpty), + _.map(commonStringInputNormalization).filter(_.nonEmpty) + ) )(EditUserFormData.apply)(EditUserFormData.unapply) ) diff --git a/app/models/User.scala b/app/models/User.scala index eaa91ff1a..84cde14b8 100644 --- a/app/models/User.scala +++ b/app/models/User.scala @@ -42,7 +42,9 @@ case class User( // * can see all users, // * can see one user but not edit it observableOrganisationIds: List[Organisation.Id] = Nil, - sharedAccount: Boolean = false + sharedAccount: Boolean = false, + // This is a comment only visible by the admins + internalSupportComment: Option[String] ) extends AgeModel { def nameWithQualite = s"$name ( $qualite )" @@ -93,6 +95,9 @@ case class User( lazy val observableOrganisationIdsLog: String = observableOrganisationIds.map(_.id).mkString(", ") lazy val sharedAccountLog: String = sharedAccount.toString + lazy val internalSupportCommentLog: String = + internalSupportComment.map(withQuotes).getOrElse("") + lazy val toLogString: String = "[" + List[(String, String)]( ("Id", id.toString), @@ -114,6 +119,7 @@ case class User( ("Date CGU", cguAcceptationDateLog), ("Newsletter", newsletterAcceptationDateLog), ("Observation des organismes", observableOrganisationIdsLog), + ("Information Support", internalSupportCommentLog), ).map { case (fieldName, value) => s"$fieldName : $value" }.mkString(" | ") + "]" def toDiffLogString(other: User): String = { @@ -157,6 +163,12 @@ case class User( observableOrganisationIdsLog, other.observableOrganisationIdsLog ), + ( + "Information Support", + internalSupportCommentLog =!= other.internalSupportCommentLog, + internalSupportCommentLog, + other.internalSupportCommentLog + ), ).collect { case (name, true, thisValue, thatValue) => s"$name : $thisValue -> $thatValue" } "[" + diffs.mkString(" | ") + "]" } @@ -180,7 +192,8 @@ object User { ZonedDateTime.parse("2017-11-01T00:00+01:00"), "75056", groupAdmin = false, - disabled = true + disabled = true, + internalSupportComment = None ) } diff --git a/app/models/UserGroup.scala b/app/models/UserGroup.scala index b6fdaba4b..ddc46c54e 100644 --- a/app/models/UserGroup.scala +++ b/app/models/UserGroup.scala @@ -15,7 +15,9 @@ case class UserGroup( organisation: Option[Organisation.Id] = None, email: Option[String] = None, // This is a note displayed to users trying to select this group - publicNote: Option[String] + publicNote: Option[String], + // This is a comment only visible by the admins + internalSupportComment: Option[String] ) { def canHaveUsersAddedBy(user: User): Boolean = @@ -35,6 +37,9 @@ case class UserGroup( lazy val areaIdsLog: String = areaIds.mkString(", ") lazy val publicNoteLog: String = publicNote.map(withQuotes).getOrElse("") + lazy val internalSupportCommentLog: String = + internalSupportComment.map(withQuotes).getOrElse("") + lazy val toLogString: String = "[" + List[(String, String)]( ("Id", id.toString), @@ -43,7 +48,8 @@ case class UserGroup( ("BAL", emailLog), ("Organisme", organisationLog), ("Territoires", areaIdsLog), - ("Notice", publicNoteLog) + ("Notice", publicNoteLog), + ("Information Support", internalSupportCommentLog), ).map { case (fieldName, value) => s"$fieldName : $value" }.mkString(" | ") + "]" def toDiffLogString(other: UserGroup): String = { @@ -55,6 +61,12 @@ case class UserGroup( ("Organisme", organisation =!= other.organisation, organisationLog, other.organisationLog), ("Territoires", areaIds =!= other.areaIds, areaIdsLog, other.areaIdsLog), ("Notice", publicNote =!= other.publicNote, publicNoteLog, other.publicNoteLog), + ( + "Information Support", + internalSupportCommentLog =!= other.internalSupportCommentLog, + internalSupportCommentLog, + other.internalSupportCommentLog + ), ).collect { case (name, true, thisValue, thatValue) => s"$name : $thisValue -> $thatValue" } "[" + diffs.mkString(" | ") + "]" } diff --git a/app/models/formModels.scala b/app/models/formModels.scala index c6c4b78ed..fefc92e24 100644 --- a/app/models/formModels.scala +++ b/app/models/formModels.scala @@ -130,7 +130,8 @@ object formModels { groupIds: List[UUID], phoneNumber: Option[String], observableOrganisationIds: List[Organisation.Id], - sharedAccount: Boolean + sharedAccount: Boolean, + internalSupportComment: Option[String] ) case class CSVReviewUserFormData( diff --git a/app/services/UserGroupService.scala b/app/services/UserGroupService.scala index fca894eba..a999ea8a3 100644 --- a/app/services/UserGroupService.scala +++ b/app/services/UserGroupService.scala @@ -32,7 +32,8 @@ class UserGroupService @Inject() ( "area_ids", "organisation", "email", - "public_note" + "public_note", + "internal_support_comment" ) .map(a => a.copy(creationDate = a.creationDate.withZoneSameInstant(Time.timeZoneParis))) @@ -81,7 +82,8 @@ class UserGroupService @Inject() ( organisation = ${group.organisation.map(_.id)}, area_ids = array[${group.areaIds}]::uuid[], email = ${group.email}, - public_note = ${group.publicNote} + public_note = ${group.publicNote}, + internal_support_comment = ${group.internalSupportComment} WHERE id = ${group.id}::uuid """.executeUpdate() === 1 //TODO: insee_code = array[${group.inseeCode}]::character varying(5)[], have been remove temporary diff --git a/app/services/UserService.scala b/app/services/UserService.scala index b01863f8a..61c4c3f02 100644 --- a/app/services/UserService.scala +++ b/app/services/UserService.scala @@ -46,7 +46,8 @@ class UserService @Inject() ( "newsletter_acceptation_date", "phone_number", "observable_organisation_ids", - "shared_account" + "shared_account", + "internal_support_comment" ) .map(a => a.copy(creationDate = a.creationDate.withZoneSameInstant(Time.timeZoneParis))) @@ -229,7 +230,8 @@ class UserService @Inject() ( phone_number = ${user.phoneNumber}, disabled = ${user.disabled}, observable_organisation_ids = array[${observableOrganisationIds.distinct}]::varchar[], - shared_account = ${user.sharedAccount} + shared_account = ${user.sharedAccount}, + internal_support_comment = ${user.internalSupportComment} WHERE id = ${user.id}::uuid """.executeUpdate() === 1 }) diff --git a/app/views/editGroup.scala.html b/app/views/editGroup.scala.html index b6a844b51..c692b808c 100644 --- a/app/views/editGroup.scala.html +++ b/app/views/editGroup.scala.html @@ -51,6 +51,22 @@ } + + + @if(currentUser.admin) { + +
+ + +
+ + } else { + + } + @if(currentUser.admin) {
+ @if(currentUser.admin) { + @helper.input(form("internalSupportComment"), + "label" -> "Commentaire interne pour le support (visible uniquement par les administrateurs)", + "class" -> "single--width-100pc") { (id, name, value, args) => + + } + } else { + + } + @if(unused && canEditUser) {
diff --git a/conf/evolutions/default/47.sql b/conf/evolutions/default/47.sql new file mode 100644 index 000000000..3cf5a434d --- /dev/null +++ b/conf/evolutions/default/47.sql @@ -0,0 +1,7 @@ +# --- !Ups +ALTER TABLE "user" ADD internal_support_comment text NULL; +ALTER TABLE user_group ADD internal_support_comment text NULL; + +# --- !Downs +ALTER TABLE user_group DROP internal_support_comment; +ALTER TABLE "user" DROP internal_support_comment; diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css index 811f6bd5c..463078bad 100644 --- a/public/stylesheets/main.css +++ b/public/stylesheets/main.css @@ -719,10 +719,6 @@ a { height: auto !important; } -.single--width-100pc { - width: 100%; -} - .single--width-unset { width: unset; } diff --git a/test/browser/AnswerSpec.scala b/test/browser/AnswerSpec.scala index 6344bb8cc..005996c9a 100644 --- a/test/browser/AnswerSpec.scala +++ b/test/browser/AnswerSpec.scala @@ -23,7 +23,8 @@ class AnswerSpec extends Specification with Tables with BaseSpec { inseeCode = List("0"), creationDate = Time.nowParis(), areaIds = area :: Nil, - publicNote = None + publicNote = None, + internalSupportComment = None ) groupService.add(group) group @@ -64,7 +65,8 @@ class AnswerSpec extends Specification with Tables with BaseSpec { disabled = false, expert = isExpert, cguAcceptationDate = Some(Time.nowParis()), - groupIds = groups.map(_.id) + groupIds = groups.map(_.id), + internalSupportComment = None ) val result = userService.add(List(user)) result.isRight must beTrue diff --git a/test/browser/ApplicationAccessSpec.scala b/test/browser/ApplicationAccessSpec.scala index 93b3ee4b6..81bfebee4 100644 --- a/test/browser/ApplicationAccessSpec.scala +++ b/test/browser/ApplicationAccessSpec.scala @@ -107,7 +107,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { inseeCode = List("0"), creationDate = Time.nowParis(), areaIds = area :: Nil, - publicNote = None + publicNote = None, + internalSupportComment = None ) groupService.add(instructorGroup) val helperGroup = UserGroup( @@ -117,7 +118,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { inseeCode = List("0"), creationDate = Time.nowParis(), areaIds = area :: Nil, - publicNote = None + publicNote = None, + internalSupportComment = None ) groupService.add(helperGroup) @@ -138,7 +140,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = List(instructorGroup.id) + groupIds = List(instructorGroup.id), + internalSupportComment = None ) val unrelatedInstructorUser = User( UUIDHelper.namedFrom(s"instructor-test-unrelated$number"), @@ -157,7 +160,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = Nil + groupIds = Nil, + internalSupportComment = None ) val helperUser = User( UUIDHelper.namedFrom(s"helper-test$number"), @@ -176,7 +180,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = List(helperGroup.id) + groupIds = List(helperGroup.id), + internalSupportComment = None ) val helperFriendUser = User( UUIDHelper.namedFrom(s"helper-test-friend$number"), @@ -195,7 +200,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = List(helperGroup.id) + groupIds = List(helperGroup.id), + internalSupportComment = None ) val unrelatedHelperUser = User( UUIDHelper.namedFrom(s"helper-test-unrelated$number"), @@ -214,7 +220,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = List(helperGroup.id) + groupIds = List(helperGroup.id), + internalSupportComment = None ) val unrelatedExpertUser = User( UUIDHelper.namedFrom(s"expert-test-unrelated$number"), @@ -233,7 +240,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = List(helperGroup.id) + groupIds = List(helperGroup.id), + internalSupportComment = None ) val managerUser = User( UUIDHelper.namedFrom(s"helper-test-manager$number"), @@ -252,7 +260,8 @@ class ApplicationAccessSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = List(helperGroup.id) + groupIds = List(helperGroup.id), + internalSupportComment = None ) val users = List( diff --git a/test/browser/ApplicationSpec.scala b/test/browser/ApplicationSpec.scala index e38e8c3f2..9fed46fca 100644 --- a/test/browser/ApplicationSpec.scala +++ b/test/browser/ApplicationSpec.scala @@ -32,7 +32,8 @@ class ApplicationSpec extends Specification with BaseSpec { inseeCode = List("0"), creationDate = Time.nowParis(), areaIds = area :: Nil, - publicNote = None + publicNote = None, + internalSupportComment = None ) groupService.add(instructorGroup) val instructorUser = User( @@ -52,7 +53,8 @@ class ApplicationSpec extends Specification with BaseSpec { groupAdmin = false, disabled = false, cguAcceptationDate = Some(Time.nowParis()), - groupIds = List(instructorGroup.id) + groupIds = List(instructorGroup.id), + internalSupportComment = None ) val helperUser = User( UUIDHelper.randomUUID, @@ -70,7 +72,8 @@ class ApplicationSpec extends Specification with BaseSpec { "0", groupAdmin = false, disabled = false, - cguAcceptationDate = Some(Time.nowParis()) + cguAcceptationDate = Some(Time.nowParis()), + internalSupportComment = None ) userService.add(List(instructorUser, helperUser)) userService.validateCGU(helperUser.id) diff --git a/test/browser/LoginSpec.scala b/test/browser/LoginSpec.scala index 7dcea61ac..0569eeba9 100644 --- a/test/browser/LoginSpec.scala +++ b/test/browser/LoginSpec.scala @@ -30,7 +30,8 @@ class LoginSpec extends Specification with Tables with BaseSpec with BeforeAfter ZonedDateTime.parse("2017-11-01T00:00+01:00"), "75056", groupAdmin = true, - disabled = false + disabled = false, + internalSupportComment = None ) def beforeAll(): Unit = { diff --git a/test/csv/CSVSpec.scala b/test/csv/CSVSpec.scala index 4fb35bfd2..0ac1f883f 100644 --- a/test/csv/CSVSpec.scala +++ b/test/csv/CSVSpec.scala @@ -72,7 +72,8 @@ class CSVSpec extends Specification { areaIds = List(Area.fromId(UUIDHelper.namedFrom("ardennes"))).flatten.map(_.id), organisation = None, email = Some("sip.laon@dgfip.finances.gouv.fr"), - publicNote = None + publicNote = None, + internalSupportComment = None ) val dgfip = data.find(formData => formData.group.name.eqv(expectedUserGroup.name))