Skip to content

Commit

Permalink
[TRELLO-1953] Some improvments
Browse files Browse the repository at this point in the history
  • Loading branch information
charlescd committed Jan 8, 2024
1 parent 98d6bb0 commit 3f69d00
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 21 deletions.
19 changes: 13 additions & 6 deletions app/controllers/ImportController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,21 @@ import utils.EmailAddress
import utils.SIREN
import utils.SIRET
import authentication.actions.UserAction.WithRole
import models.company.AccessLevel

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

case class ImportInput(siren: Option[SIREN], sirets: List[SIRET], emails: List[EmailAddress])
case class ImportInput(
siren: Option[SIREN],
sirets: List[SIRET],
emails: List[EmailAddress],
onlyHeadOffice: Boolean,
level: AccessLevel
)

object ImportInput {
implicit val test: OFormat[ImportInput] = Json.format[ImportInput]
implicit val importInputFormat: OFormat[ImportInput] = Json.format[ImportInput]
}

class ImportController(
Expand All @@ -33,14 +40,14 @@ class ImportController(
(input.siren, input.sirets, input.emails) match {
case (_, _, Nil) => Future.failed(EmptyEmails)
case (None, Nil, _) => Future.failed(EmptyEmails)
case (siren, sirets, emails) => Future.successful((siren, sirets, emails))
case (siren, sirets, emails) => Future.successful((siren, sirets, emails, input.onlyHeadOffice, input.level))
}

def importUsers = SecuredAction.andThen(WithRole(UserRole.Admin)).async(parse.json) { implicit request =>
for {
importInput <- request.parseBody[ImportInput]()
(siren, sirets, emails) <- validateInput(importInput)
_ <- importOrchestrator.importUsers(siren, sirets, emails)
importInput <- request.parseBody[ImportInput]()
(siren, sirets, emails, onlyHeadOffice, level) <- validateInput(importInput)
_ <- importOrchestrator.importUsers(siren, sirets, emails, onlyHeadOffice, level)
} yield NoContent
}
}
7 changes: 4 additions & 3 deletions app/models/company/Company.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import java.time.LocalDate
import java.time.OffsetDateTime
import java.util.UUID
import scala.util.Try
sealed case class AccessLevel(value: String)

case class AccessLevel(value: String) extends AnyVal

object AccessLevel {
val NONE = AccessLevel("none")
Expand All @@ -17,8 +18,8 @@ object AccessLevel {

def fromValue(v: String) =
List(NONE, MEMBER, ADMIN).find(_.value == v).getOrElse(NONE)
implicit val reads: Reads[AccessLevel] = (json: JsValue) => json.validate[String].map(fromValue)
implicit val writes: Writes[AccessLevel] = (level: AccessLevel) => Json.toJson(level.value)
implicit val reads: Reads[AccessLevel] = Json.valueReads[AccessLevel]
implicit val writes: Writes[AccessLevel] = Json.valueWrites[AccessLevel]
}

case class UserAccess(
Expand Down
24 changes: 17 additions & 7 deletions app/orchestrators/ImportOrchestrator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ import scala.concurrent.ExecutionContext
import scala.concurrent.Future

trait ImportOrchestratorInterface {
def importUsers(siren: Option[SIREN], sirets: List[SIRET], emails: List[EmailAddress]): Future[Unit]
def importUsers(
siren: Option[SIREN],
sirets: List[SIRET],
emails: List[EmailAddress],
onlyHeadOffice: Boolean,
level: AccessLevel
): Future[Unit]
}

class ImportOrchestrator(
Expand All @@ -36,7 +42,13 @@ class ImportOrchestrator(
brand = c.brand
)

def importUsers(siren: Option[SIREN], sirets: List[SIRET], emails: List[EmailAddress]): Future[Unit] =
def importUsers(
siren: Option[SIREN],
sirets: List[SIRET],
emails: List[EmailAddress],
onlyHeadOffice: Boolean,
level: AccessLevel
): Future[Unit] =
for {
existingCompanies <- companyRepository.findBySirets(sirets)
missingSirets = sirets.diff(existingCompanies.map(_.siret))
Expand All @@ -46,7 +58,7 @@ class ImportOrchestrator(
)

companiesFromSiren <- siren match {
case Some(siren) => companySyncService.companyBySiren(siren)
case Some(siren) => companySyncService.companyBySiren(siren, onlyHeadOffice)
case None => Future.successful(List.empty)
}
existingCompaniesFromSiren <- companyRepository.findBySirets(companiesFromSiren.map(_.siret))
Expand All @@ -59,12 +71,10 @@ class ImportOrchestrator(
missingUsers = emails.diff(existingUsers.map(_.email))
allCompanies = existingCompanies ++ createdCompanies ++ existingCompaniesFromSiren ++ createdCompaniesFromSiren
_ <- Future.sequence(
missingUsers.map(email => proAccessTokenOrchestrator.sendInvitations(allCompanies, email, AccessLevel.ADMIN))
missingUsers.map(email => proAccessTokenOrchestrator.sendInvitations(allCompanies, email, level))
)
_ <- Future.sequence(
existingUsers.map(user =>
proAccessTokenOrchestrator.addInvitedUserAndNotify(user, allCompanies, AccessLevel.ADMIN)
)
existingUsers.map(user => proAccessTokenOrchestrator.addInvitedUserAndNotify(user, allCompanies, level))
)
} yield ()

Expand Down
6 changes: 3 additions & 3 deletions app/tasks/company/CompanySyncService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import scala.concurrent.Future
trait CompanySyncServiceInterface {
def syncCompanies(companies: Seq[Company], lastUpdated: OffsetDateTime): Future[List[CompanySearchResult]]
def companyBySiret(siret: SIRET): Future[Option[CompanySearchResult]]
def companyBySiren(siren: SIREN): Future[List[CompanySearchResult]]
def companyBySiren(siren: SIREN, onlyHeadOffice: Boolean): Future[List[CompanySearchResult]]
def companiesBySirets(sirets: List[SIRET]): Future[List[CompanySearchResult]]
}

Expand Down Expand Up @@ -106,13 +106,13 @@ class CompanySyncService(companyUpdateConfiguration: CompanyUpdateTaskConfigurat
}
}

override def companyBySiren(siren: SIREN): Future[List[CompanySearchResult]] = {
override def companyBySiren(siren: SIREN, onlyHeadOffice: Boolean): Future[List[CompanySearchResult]] = {
val request = basicRequest
.headers(Header("X-Api-Key", companyUpdateConfiguration.etablissementApiKey))
.post(
uri"${companyUpdateConfiguration.etablissementApiUrl}"
.withWholePath(SirenSearchEndpoint)
.addParam("onlyHeadOffice", Some("false"))
.addParam("onlyHeadOffice", Some(s"$onlyHeadOffice"))
)
.body(List(siren))
.response(asJson[List[CompanySearchResult]])
Expand Down
6 changes: 4 additions & 2 deletions test/orchestrators/ImportOrchestratorSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class ImportOrchestratorSpec extends Specification with FutureMatchers {

when(companyRepository.findBySirets(List.empty)).thenReturn(Future.successful(List.empty))
when(companySyncService.companiesBySirets(List.empty)).thenReturn(Future.successful(List.empty))
when(companySyncService.companyBySiren(siren)).thenReturn(Future.successful(companySearchResults))
when(companySyncService.companyBySiren(siren, false)).thenReturn(Future.successful(companySearchResults))
when(companyRepository.findBySirets(companySearchResults.map(_.siret)))
.thenReturn(Future.successful(List(existingCompany1, existingCompany2)))
when(
Expand Down Expand Up @@ -80,7 +80,9 @@ class ImportOrchestratorSpec extends Specification with FutureMatchers {
)
).thenReturn(Future.unit)

importOrchestrator.importUsers(Some(siren), List.empty, users.map(_.email)).map(res => res shouldEqual ())
importOrchestrator
.importUsers(Some(siren), List.empty, users.map(_.email), false, AccessLevel.ADMIN)
.map(res => res shouldEqual ())
}
}
}
Expand Down

0 comments on commit 3f69d00

Please sign in to comment.