Skip to content

Commit

Permalink
[TRELLO-2149] Implement create website manually endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
charlescd committed Jan 29, 2024
1 parent 0130462 commit ee07f5e
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 7 deletions.
13 changes: 13 additions & 0 deletions app/controllers/WebsiteController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import play.api.mvc.AnyContent
import play.api.mvc.ControllerComponents
import repositories.company.CompanyRepositoryInterface
import authentication.actions.UserAction.WithRole
import utils.URL

import java.time.OffsetDateTime
import scala.concurrent.ExecutionContext
Expand All @@ -36,6 +37,18 @@ class WebsiteController(
implicit val timeout: akka.util.Timeout = 5.seconds
val logger: Logger = Logger(this.getClass)

def create() = SecuredAction.andThen(WithRole(UserRole.Admin)).async(parse.json) { request =>
request.body
.validate[WebsiteCreation]
.fold(
errors => Future.successful(BadRequest(JsError.toJson(errors))),
websiteCreation =>
websitesOrchestrator
.create(URL(websiteCreation.host), websiteCreation.company.toCompany())
.map(website => Ok(Json.toJson(website)))
)
}

def fetchWithCompanies(
maybeHost: Option[String],
maybeIdentificationStatus: Option[Seq[IdentificationStatus]],
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/error/AppError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -507,4 +507,9 @@ object AppError {
override val titleForLogs: String = "different_user_from_request"
}

final case class CreateWebsiteError(override val details: String) extends BadRequestError {
override val `type`: String = "SC-0054"
override val title: String = "Can't create website"
override val titleForLogs: String = "cant_create_website"
}
}
10 changes: 10 additions & 0 deletions app/models/website/WebsiteCreation.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package models.website

import models.company.CompanyCreation
import play.api.libs.json.Json
import play.api.libs.json.Reads

case class WebsiteCreation(host: String, company: CompanyCreation)
object WebsiteCreation {
implicit val reads: Reads[WebsiteCreation] = Json.reads[WebsiteCreation]
}
55 changes: 48 additions & 7 deletions app/orchestrators/WebsitesOrchestrator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package orchestrators
import cats.implicits.catsSyntaxMonadError
import cats.implicits.catsSyntaxOption
import controllers.error.AppError.CannotDeleteWebsite
import controllers.error.AppError.CreateWebsiteError
import controllers.error.AppError.MalformedHost
import controllers.error.AppError.WebsiteHostIsAlreadyIdentified
import controllers.error.AppError.WebsiteNotFound
Expand Down Expand Up @@ -42,6 +43,26 @@ class WebsitesOrchestrator(

val logger: Logger = Logger(this.getClass)

def create(url: URL, company: Company): Future[Website] =
for {
host <- url.getHost.liftTo[Future](MalformedHost(url.value))
createdCompany <- companyRepository.getOrCreate(company.siret, company)
identified <- repository.listIdentified(host)
notAssociatedToCompany <- repository.listNotAssociatedToCompany(host)
_ <-
if (notAssociatedToCompany.nonEmpty || identified.flatMap(_.companyId).contains(createdCompany.id))
Future.failed(CreateWebsiteError("Impossible de créer un site web s'il est déjà associé mais pas identifié"))
else
Future.unit
website = Website(
host = host,
companyCountry = None,
companyId = Some(createdCompany.id),
identificationStatus = IdentificationStatus.Identified
)
createdWebsite <- repository.create(website)
} yield createdWebsite

def searchByHost(host: String): Future[Seq[Country]] =
for {
validHost <- URL(host).getHost.liftTo[Future](MalformedHost(host))
Expand Down Expand Up @@ -82,7 +103,14 @@ class WebsitesOrchestrator(
newIdentificationStatus: IdentificationStatus,
user: User
): Future[Website] = for {
website <- findWebsite(websiteId)
website <- findWebsite(websiteId)
identified <- repository.listIdentified(website.host)
_ <-
if (identified.length > 1)
Future.failed(
CreateWebsiteError("Le status ne peut pas être modifié si plus d'un siret est associé au site web")
)
else Future.unit
_ = if (website.companyCountry.isEmpty && website.companyId.isEmpty) {
throw WebsiteNotIdentified(website.host)
}
Expand All @@ -102,7 +130,7 @@ class WebsitesOrchestrator(
_ = logger.debug(s"Company Siret is ${maybeCompany.map(_.siret)}")
_ <- maybeCompany
.map(company => updatePreviousReportsAssociatedToWebsite(website.host, company, user.id))
.getOrElse(Future.successful(()))
.getOrElse(Future.unit)
} yield ()
} else Future.unit
} yield updatedWebsite
Expand All @@ -122,9 +150,16 @@ class WebsitesOrchestrator(
for {
company <- {
logger.debug(s"Updating website (id ${websiteId}) with company siret : ${companyToAssign.siret}")
getOrCreateCompay(companyToAssign)
getOrCreateCompany(companyToAssign)
}
website <- findWebsite(websiteId)
website <- findWebsite(websiteId)
identified <- repository.listIdentified(website.host)
_ <-
if (identified.length > 1 && identified.flatMap(_.companyId).contains(company.id)) {
Future.failed(
CreateWebsiteError("L'entreprise ne peut pas être modifiée si plus d'un siret est associé au site web")
)
} else Future.unit
websiteToUpdate = website.copy(
companyCountry = None,
companyId = Some(company.id)
Expand All @@ -135,9 +170,14 @@ class WebsitesOrchestrator(

def updateCompanyCountry(websiteId: WebsiteId, companyCountry: String, user: User): Future[WebsiteAndCompany] = for {
website <- {
logger.debug(s"Updating website (id ${websiteId.value}) with company country : ${companyCountry}")
logger.debug(s"Updating website (id ${websiteId.value}) with company country : $companyCountry")
findWebsite(websiteId)
}
identified <- repository.listIdentified(website.host)
_ <-
if (identified.length > 1)
Future.failed(CreateWebsiteError("Le pays ne peut pas être modifié si plus d'un siret est associé au site web"))
else Future.unit
websiteToUpdate = website.copy(
companyCountry = Some(companyCountry),
companyId = None
Expand All @@ -162,10 +202,11 @@ class WebsitesOrchestrator(
for {
maybeWebsite <- repository.get(websiteId)
website <- maybeWebsite.liftTo[Future](WebsiteNotFound(websiteId))
identified <- repository.listIdentified(website.host)
isWebsiteUnderInvestigation = website.investigationStatus != NotProcessed
isWebsiteIdentified = website.identificationStatus == Identified
_ <-
if (isWebsiteIdentified || isWebsiteUnderInvestigation) {
if (identified.length < 2 && (isWebsiteIdentified || isWebsiteUnderInvestigation)) {
logger.debug(s"Cannot delete identified / under investigation website")
Future.failed(CannotDeleteWebsite(website.host))
} else {
Expand All @@ -184,7 +225,7 @@ class WebsitesOrchestrator(

def listInvestigationStatus(): Seq[InvestigationStatus] = InvestigationStatus.values

private[this] def getOrCreateCompay(companyCreate: CompanyCreation): Future[Company] = companyRepository
private[this] def getOrCreateCompany(companyCreate: CompanyCreation): Future[Company] = companyRepository
.getOrCreate(
companyCreate.siret,
companyCreate.toCompany()
Expand Down
19 changes: 19 additions & 0 deletions app/repositories/website/WebsiteRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,23 @@ class WebsiteRepository(
.result
)

def listNotAssociatedToCompany(host: String): Future[Seq[Website]] =
db.run(
table
.filter(_.host === host)
.filter(website =>
website.companyCountry.isDefined || (website.identificationStatus inSet List(
IdentificationStatus.NotIdentified
))
)
.result
)

def listIdentified(host: String): Future[Seq[Website]] =
db.run(
table
.filter(_.host === host)
.filter(_.identificationStatus inSet List(IdentificationStatus.Identified))
.result
)
}
4 changes: 4 additions & 0 deletions app/repositories/website/WebsiteRepositoryInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ trait WebsiteRepositoryInterface extends TypedCRUDRepositoryInterface[Website, W
start: Option[LocalDate] = None,
end: Option[LocalDate] = None
): Future[List[(String, Int)]]

def listNotAssociatedToCompany(host: String): Future[Seq[Website]]

def listIdentified(host: String): Future[Seq[Website]]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE websites DROP CONSTRAINT company_host
1 change: 1 addition & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ GET /api/resources/investigation-status controll
POST /api/website-investigations controllers.WebsiteController.updateInvestigation()
# Websites API
GET /api/websites controllers.WebsiteController.fetchWithCompanies(host: Option[String], identificationStatus: Option[Seq[IdentificationStatus]], offset: Option[Long], limit: Option[Int],investigationStatus: Option[Seq[InvestigationStatus]],start: Option[OffsetDateTime],end: Option[OffsetDateTime],hasAssociation: Option[Boolean],isOpen: Option[Boolean])
POST /api/websites controllers.WebsiteController.create()
GET /api/websites/search-url controllers.WebsiteController.searchByHost(url: String)
GET /api/websites/unregistered controllers.WebsiteController.fetchUnregisteredHost(q: Option[String], start: Option[String], end: Option[String])
GET /api/websites/unregistered/extract controllers.WebsiteController.extractUnregisteredHost(q: Option[String], start: Option[String], end: Option[String])
Expand Down

0 comments on commit ee07f5e

Please sign in to comment.