diff --git a/app/controllers/ImportController.scala b/app/controllers/ImportController.scala index b10b9357..439adc52 100644 --- a/app/controllers/ImportController.scala +++ b/app/controllers/ImportController.scala @@ -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( @@ -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 } } diff --git a/app/models/company/Company.scala b/app/models/company/Company.scala index 4967ac73..7e51e93d 100644 --- a/app/models/company/Company.scala +++ b/app/models/company/Company.scala @@ -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") @@ -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( diff --git a/app/orchestrators/ImportOrchestrator.scala b/app/orchestrators/ImportOrchestrator.scala index 88e784d2..d2fb5da9 100644 --- a/app/orchestrators/ImportOrchestrator.scala +++ b/app/orchestrators/ImportOrchestrator.scala @@ -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( @@ -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)) @@ -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)) @@ -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 () diff --git a/app/tasks/company/CompanySyncService.scala b/app/tasks/company/CompanySyncService.scala index 663d466f..90108f18 100644 --- a/app/tasks/company/CompanySyncService.scala +++ b/app/tasks/company/CompanySyncService.scala @@ -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]] } @@ -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]]) diff --git a/test/orchestrators/ImportOrchestratorSpec.scala b/test/orchestrators/ImportOrchestratorSpec.scala index f05e8afc..e504453a 100644 --- a/test/orchestrators/ImportOrchestratorSpec.scala +++ b/test/orchestrators/ImportOrchestratorSpec.scala @@ -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( @@ -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 ()) } } }