Skip to content

Commit

Permalink
TRELLO-2442: pro comment api (#1716)
Browse files Browse the repository at this point in the history
* TRELLO-2442: pro comment api
  • Loading branch information
ssedoudbgouv authored Aug 26, 2024
1 parent 9d93ec6 commit 9093284
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 19 deletions.
11 changes: 9 additions & 2 deletions app/controllers/ReportController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import controllers.error.AppError.SpammerEmailBlocked
import models._
import models.report._
import models.report.delete.ReportAdminAction
import models.report.reportmetadata.ReportComment
import orchestrators._
import play.api.Logger
import play.api.i18n.Lang
Expand Down Expand Up @@ -261,10 +262,16 @@ class ReportController(
}

def updateReportAssignedUser(uuid: UUID, userId: UUID) =
SecuredAction.andThen(WithRole(UserRole.Professionnel)).async { implicit request =>
SecuredAction.andThen(WithRole(UserRole.Professionnel)).async(parse.json) { implicit request =>
for {
reportComment <- request.parseBody[ReportComment]()
updatedReportWithMetadata <- reportAssignmentOrchestrator
.assignReportToUser(reportId = uuid, assigningUser = request.identity, newAssignedUserId = userId)
.assignReportToUser(
reportId = uuid,
assigningUser = request.identity,
newAssignedUserId = userId,
reportComment
)
} yield Ok(Json.toJson(updatedReportWithMetadata))
}

Expand Down
2 changes: 0 additions & 2 deletions app/models/event/Event.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,4 @@ object Event {

implicit val eventFormat: OFormat[Event] = Json.format[Event]
def stringToDetailsJsValue(value: String): JsValue = Json.obj("description" -> value)
def jsValueToString(jsValue: Option[JsValue]) =
jsValue.flatMap(_.as[JsObject].value.get("description").map(_.toString))
}
10 changes: 10 additions & 0 deletions app/models/report/reportmetadata/ReportComment.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package models.report.reportmetadata

import play.api.libs.json.Json
import play.api.libs.json.OFormat

case class ReportComment(comment: Option[String])

object ReportComment {
implicit val ReportCommentFormat: OFormat[ReportComment] = Json.format[ReportComment]
}
35 changes: 27 additions & 8 deletions app/orchestrators/ReportAssignmentOrchestrator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import cats.implicits.catsSyntaxOption
import controllers.error.AppError
import models.User
import models.event.Event
import models.event.Event.stringToDetailsJsValue
import models.report.Report
import models.report.reportmetadata.ReportComment
import models.report.reportmetadata.ReportWithMetadata
import play.api.Logger
import play.api.libs.json.Json
import repositories.event.EventRepositoryInterface
import repositories.reportmetadata.ReportMetadataRepositoryInterface
import repositories.user.UserRepositoryInterface
Expand All @@ -32,19 +33,29 @@ class ReportAssignmentOrchestrator(
) {
val logger = Logger(this.getClass)

def assignReportToUser(reportId: UUID, assigningUser: User, newAssignedUserId: UUID): Future[User] = {
def assignReportToUser(
reportId: UUID,
assigningUser: User,
newAssignedUserId: UUID,
reportComment: ReportComment
): Future[User] = {
val assigningToSelf = assigningUser.id == newAssignedUserId
for {
maybeReportWithMetadata <- reportOrchestrator.getVisibleReportForUser(reportId, assigningUser)
reportWithMetadata <- maybeReportWithMetadata.liftTo[Future](AppError.ReportNotFound(reportId))
newAssignedUser <- checkAssignableToUser(reportWithMetadata, newAssignedUserId)
_ <- reportMetadataRepository.setAssignedUser(reportId, newAssignedUserId)
_ <- createAssignmentEvent(reportWithMetadata.report, assigningUser, newAssignedUser)
_ <- createAssignmentEvent(reportWithMetadata.report, assigningUser, newAssignedUser, reportComment)
_ <-
if (assigningToSelf) Future.unit
else
mailService.send(
ProReportAssignedNotification.Email(reportWithMetadata.report, assigningUser, newAssignedUser)
ProReportAssignedNotification.Email(
reportWithMetadata.report,
assigningUser,
newAssignedUser,
reportComment.comment
)
)
} yield newAssignedUser
}
Expand All @@ -71,7 +82,12 @@ class ReportAssignmentOrchestrator(
} yield user
}

private def createAssignmentEvent(report: Report, assigningUser: User, assignedUser: User) =
private def createAssignmentEvent(
report: Report,
assigningUser: User,
assignedUser: User,
reportComment: ReportComment
) =
eventRepository
.create(
Event(
Expand All @@ -82,10 +98,13 @@ class ReportAssignmentOrchestrator(
OffsetDateTime.now(),
Constants.EventType.PRO,
Constants.ActionEvent.REPORT_ASSIGNED,
stringToDetailsJsValue(
s"Affectation du signalement à ${assignedUser.firstName} ${assignedUser.lastName} (${assignedUser.email})"
)
formatEventDesc(assignedUser, reportComment)
)
)

private def formatEventDesc(assignedUser: User, reportComment: ReportComment) =
Json.obj(
"description" -> s"Affectation du signalement à ${assignedUser.fullName} (${assignedUser.email})"
) ++ reportComment.comment.filterNot(_.isBlank).map(c => Json.obj("comment" -> c)).getOrElse(Json.obj())

}
14 changes: 11 additions & 3 deletions app/services/emails/EmailDefinitionsPro.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package services.emails

import cats.data.NonEmptyList
import cats.implicits.catsSyntaxOptionId
import models.User
import models.company.Company
import models.report.ExistingReportResponse
Expand Down Expand Up @@ -241,17 +242,24 @@ object EmailDefinitionsPro {
override def examples =
Seq(
"report_assignement_to_other" -> ((recipient, _) =>
Email(report = genReport, assigningUser = genUser, assignedUser = genUser.copy(email = recipient))
Email(
report = genReport,
assigningUser = genUser.copy(firstName = "Max", lastName = "Payne"),
assignedUser = genUser.copy(email = recipient),
"Bonjour,Je t’affecte ce ticket car ton expertise sur ce type de problématique est bien reconnue. La tâche nécessite une attention particulière, et je suis convaincu que tu pourras gérer cela efficacement. De plus, ta connaissance approfondie sera un atout précieux pour résoudre ce problème rapidement et de manière optimale.\n\nMerci pour ton aide et n’hésite pas à me contacter si tu as besoin de plus d’informations.Cordialement,".some
)
)
)

final case class Email(report: Report, assigningUser: User, assignedUser: User)
final case class Email(report: Report, assigningUser: User, assignedUser: User, reportComment: Option[String])
extends ProFilteredEmailSingleReport {
override val recipients: List[EmailAddress] = List(assignedUser.email)
override val subject: String = EmailSubjects.REPORT_ASSIGNED

override def getBody: (FrontRoute, EmailAddress) => String = { (frontRoute, _) =>
views.html.mails.professional.reportAssigned(report, assigningUser, assignedUser)(frontRoute).toString
views.html.mails.professional
.reportAssigned(report, assigningUser, assignedUser, reportComment)(frontRoute)
.toString
}
}
}
Expand Down
27 changes: 23 additions & 4 deletions app/views/mails/professional/reportAssigned.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,37 @@
@import models.report.Report
@import models.User

@(report: Report, assigningUser: User, assignedUser: User)(implicit frontRoute: FrontRoute)
@(report: Report, assigningUser: User, assignedUser: User, comment: Option[String])(implicit frontRoute: FrontRoute)

@views.html.mails.layout(s"Signalement affecté") {
<p>
Bonjour @assignedUser.firstName @assignedUser.lastName,
Bonjour @assignedUser.fullName,
</p>

<p>Un signalement vous a été affecté par @assigningUser.firstName @assigningUser.lastName.</p>

@if(comment.isDefined) {
<p>
@assigningUser.fullName vous a laissé un commentaire :
</p>
<blockquote style="
font-style: italic;
color: #555;
border-left: 5px solid #ccc;
padding-left: 20px;
margin: 20px 0;
background: #f9f9f9;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
position: relative;
">
@comment.getOrElse("")
</blockquote>
}

<p>
Pour le consulter et y apporter une réponse, il vous suffit de vous connecter sur votre <a href="@frontRoute.dashboard.url(s"/suivi-des-signalements/report/${report.id.toString}")">
Espace Professionnel</a> à l'aide de votre adresse e-mail et du mot de passe que vous avez créé à votre première connexion sur SignalConso.
Pour consulter le signalement et y apporter une réponse, il vous suffit de vous connecter sur votre <a href="@frontRoute.dashboard.url(s"/suivi-des-signalements/report/${report.id.toString}")">
Espace Professionnel</a>
à l'aide de votre adresse e-mail et du mot de passe que vous avez créé à votre première connexion sur SignalConso.
</p>

<p>Cordialement,</p>
Expand Down

0 comments on commit 9093284

Please sign in to comment.