Skip to content

Commit

Permalink
[Signalement] Ajout de plusieurs sources à un signalement (#1585)
Browse files Browse the repository at this point in the history
## Related Pull Requests & Issues

- Resolve #1325 

----

- [x] Tests E2E (Cypress)
  • Loading branch information
maximeperraultdev committed Aug 7, 2024
2 parents 6ae66cf + 84f8078 commit f0217bc
Show file tree
Hide file tree
Showing 68 changed files with 1,808 additions and 1,355 deletions.
2 changes: 2 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ target/

### IntelliJ IDEA ###
.idea
.kotlin

*.iws
*.iml
*.ipr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import java.util.UUID
data class ReportingEntity(
val id: Int? = null,
val reportingId: Long? = null,
val sourceType: SourceTypeEnum? = null,
val semaphoreId: Int? = null,
val controlUnitId: Int? = null,
val sourceName: String? = null,
val reportingSources: List<ReportingSourceEntity>,
val targetType: TargetTypeEnum? = null,
val vehicleType: VehicleTypeEnum? = null,
val targetDetails: List<TargetDetailsEntity>? = listOf(),
Expand All @@ -38,23 +35,6 @@ data class ReportingEntity(
val isInfractionProven: Boolean,
) {
fun validate() {
when (sourceType) {
SourceTypeEnum.SEMAPHORE -> {
require(semaphoreId != null && controlUnitId == null && sourceName == null) {
"SemaphoreId must be set and controlUnitId and sourceName must be null"
}
}
SourceTypeEnum.CONTROL_UNIT -> {
require(controlUnitId != null && semaphoreId == null && sourceName == null) {
"ControlUnitId must be set and semaphoreId and sourceName must be null"
}
}
SourceTypeEnum.OTHER -> {
require(sourceName != null && semaphoreId == null && controlUnitId == null) {
"SourceName must be set and semaphoreId and controlUnitId must be null"
}
}
else -> {}
}
reportingSources.forEach { it.validate() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package fr.gouv.cacem.monitorenv.domain.entities.reporting

import java.util.UUID

data class ReportingSourceEntity(
val id: UUID?,
val reportingId: Int?,
val sourceType: SourceTypeEnum,
val semaphoreId: Int?,
val controlUnitId: Int?,
val sourceName: String?,
) {
fun validate() {
when (sourceType) {
SourceTypeEnum.SEMAPHORE -> {
require(semaphoreId != null && controlUnitId == null && sourceName == null) {
"SemaphoreId must be set and controlUnitId and sourceName must be null"
}
}

SourceTypeEnum.CONTROL_UNIT -> {
require(controlUnitId != null && semaphoreId == null && sourceName == null) {
"ControlUnitId must be set and semaphoreId and sourceName must be null"
}
}

SourceTypeEnum.OTHER -> {
require(sourceName != null && semaphoreId == null && controlUnitId == null) {
"SourceName must be set and semaphoreId and controlUnitId must be null"
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package fr.gouv.cacem.monitorenv.domain.repositories

import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingSourceEntity
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingSourceDTO

interface IReportingSourceRepository {

fun save(reportingSourceEntity: ReportingSourceEntity): ReportingSourceDTO
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import fr.gouv.cacem.monitorenv.domain.exceptions.CouldNotDeleteException
import fr.gouv.cacem.monitorenv.domain.repositories.IControlUnitRepository
import fr.gouv.cacem.monitorenv.domain.repositories.IMissionRepository
import fr.gouv.cacem.monitorenv.domain.repositories.IReportingRepository
import fr.gouv.cacem.monitorenv.domain.repositories.IReportingSourceRepository

@UseCase
class DeleteControlUnit(
private val controlUnitRepository: IControlUnitRepository,
private val canDeleteControlUnit: CanDeleteControlUnit,
private val missionRepository: IMissionRepository,
private val reportingRepository: IReportingRepository,
private val reportingSourceRepository: IReportingSourceRepository,
) {
fun execute(controlUnitId: Int) {
if (!canDeleteControlUnit.execute(controlUnitId)) {
Expand All @@ -24,23 +26,22 @@ class DeleteControlUnit(
val deletedReportings = reportingRepository.findByControlUnitId(controlUnitId).filter { it.isDeleted }

deletedMissions.forEach { deletedMission ->
// TODO: use saveAll
missionRepository.save(
deletedMission.copy(
controlUnits =
deletedMission.controlUnits.filter {
controlUnit ->
deletedMission.controlUnits.filter { controlUnit ->
controlUnit.id != controlUnitId
},
),
)
}

deletedReportings.forEach { deletedReporting ->
reportingRepository.save(
deletedReporting.copy(
controlUnitId = null,
),
)
deletedReporting.reportingSources.forEach {
// TODO: use saveAll
reportingSourceRepository.save(it.copy(controlUnitId = null))
}
}

return controlUnitRepository.deleteById(controlUnitId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ class CreateOrUpdateReporting(
private val logger: Logger = LoggerFactory.getLogger(CreateOrUpdateReporting::class.java)

@Throws(IllegalArgumentException::class)
fun execute(reporting: ReportingEntity?): ReportingDTO {
require(reporting != null) { "No reporting to create or update" }
fun execute(reporting: ReportingEntity): ReportingDTO {
logger.info("Create or update reporting: $reporting.id")
reporting.validate()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity
import fr.gouv.cacem.monitorenv.domain.entities.mission.envAction.ActionTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.ControlStatusEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingEntity
import fr.gouv.cacem.monitorenv.domain.entities.semaphore.SemaphoreEntity
import fr.gouv.cacem.monitorenv.domain.use_cases.controlUnit.dtos.FullControlUnitDTO

data class ReportingDTO(
val reporting: ReportingEntity,
val semaphore: SemaphoreEntity? = null,
val controlUnit: FullControlUnitDTO? = null,
val reportingSources: List<ReportingSourceDTO>,
val attachedMission: MissionEntity? = null,
val detachedMission: MissionEntity? = null,
) {
Expand All @@ -22,14 +19,17 @@ data class ReportingDTO(
?.find { it.id == this.reporting.attachedEnvActionId }
?.actionType == ActionTypeEnum.SURVEILLANCE ->
ControlStatusEnum.SURVEILLANCE_DONE

this.reporting.attachedEnvActionId != null &&
this.attachedMission?.envActions
?.find { it.id == this.reporting.attachedEnvActionId }
?.actionType == ActionTypeEnum.CONTROL ->
ControlStatusEnum.CONTROL_DONE

this.reporting.attachedEnvActionId == null &&
this.reporting.isControlRequired == true ->
ControlStatusEnum.CONTROL_TO_BE_DONE

else -> null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos

import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingSourceEntity
import fr.gouv.cacem.monitorenv.domain.entities.semaphore.SemaphoreEntity
import fr.gouv.cacem.monitorenv.domain.use_cases.controlUnit.dtos.FullControlUnitDTO

data class ReportingSourceDTO(
val reportingSource: ReportingSourceEntity,
val semaphore: SemaphoreEntity?,
val controlUnit: FullControlUnitDTO?,
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs
package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.reportings

import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingEntity
import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.SourceTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetDetailsEntity
import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetTypeEnum
import org.locationtech.jts.geom.Geometry
Expand All @@ -13,10 +12,7 @@ import java.util.UUID
data class CreateOrUpdateReportingDataInput(
val id: Int? = null,
val reportingId: Long? = null,
val sourceType: SourceTypeEnum? = null,
val semaphoreId: Int? = null,
val controlUnitId: Int? = null,
val sourceName: String? = null,
val reportingSources: List<ReportingSourceDataInput>,
val targetType: TargetTypeEnum? = null,
val vehicleType: VehicleTypeEnum? = null,
val targetDetails: List<TargetDetailsEntity>? = listOf(),
Expand Down Expand Up @@ -44,10 +40,7 @@ data class CreateOrUpdateReportingDataInput(
return ReportingEntity(
id = this.id,
reportingId = this.reportingId,
sourceType = this.sourceType,
semaphoreId = this.semaphoreId,
controlUnitId = this.controlUnitId,
sourceName = this.sourceName,
reportingSources = reportingSources.map { it.toReportingSourceEntity() },
targetType = this.targetType,
vehicleType = this.vehicleType,
targetDetails = this.targetDetails,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.inputs.reportings

import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingSourceEntity
import fr.gouv.cacem.monitorenv.domain.entities.reporting.SourceTypeEnum
import java.util.UUID

data class ReportingSourceDataInput(
val id: UUID?,
val reportingId: Int?,
val sourceType: SourceTypeEnum,
val semaphoreId: Int?,
val controlUnitId: Int?,
val sourceName: String?,
) {
fun toReportingSourceEntity(): ReportingSourceEntity {
return ReportingSourceEntity(
id = this.id,
reportingId = this.reportingId,
sourceType = this.sourceType,
semaphoreId = this.semaphoreId,
controlUnitId = this.controlUnitId,
sourceName = this.sourceName,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,19 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs

import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.SourceTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetDetailsEntity
import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetTypeEnum
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO
import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.publicapi.outputs.ControlUnitDataOutput
import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.reportings.ReportingSourceDataOutput
import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.reportings.ReportingSourceDataOutput.Companion.fromReportingSourceDTO
import org.locationtech.jts.geom.Geometry
import java.time.ZonedDateTime
import java.util.UUID

data class AttachedReportingDataOutput(
val id: Int,
val reportingId: Long? = null,
val sourceType: SourceTypeEnum? = null,
val semaphoreId: Int? = null,
val semaphore: SemaphoreDataOutput? = null,
val controlUnitId: Int? = null,
val controlUnit: ControlUnitDataOutput? = null,
val sourceName: String? = null,
val reportingSources: List<ReportingSourceDataOutput>,
val targetType: TargetTypeEnum? = null,
val vehicleType: VehicleTypeEnum? = null,
val targetDetails: List<TargetDetailsEntity>? = listOf(),
Expand Down Expand Up @@ -50,26 +45,7 @@ data class AttachedReportingDataOutput(
return AttachedReportingDataOutput(
id = dto.reporting.id,
reportingId = dto.reporting.reportingId,
sourceType = dto.reporting.sourceType,
semaphoreId = dto.reporting.semaphoreId,
semaphore =
if (dto.semaphore != null) {
SemaphoreDataOutput.fromSemaphoreEntity(
dto.semaphore,
)
} else {
null
},
controlUnitId = dto.reporting.controlUnitId,
controlUnit =
if (dto.controlUnit != null) {
ControlUnitDataOutput.fromFullControlUnit(
dto.controlUnit,
)
} else {
null
},
sourceName = dto.reporting.sourceName,
reportingSources = dto.reportingSources.map { fromReportingSourceDTO(it) },
targetType = dto.reporting.targetType,
vehicleType = dto.reporting.vehicleType,
targetDetails = dto.reporting.targetDetails,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,19 @@ package fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.mission

import fr.gouv.cacem.monitorenv.domain.entities.VehicleTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.SourceTypeEnum
import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetDetailsEntity
import fr.gouv.cacem.monitorenv.domain.entities.reporting.TargetTypeEnum
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO
import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.SemaphoreDataOutput
import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.publicapi.outputs.ControlUnitDataOutput
import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.reportings.ReportingSourceDataOutput
import fr.gouv.cacem.monitorenv.infrastructure.api.adapters.bff.outputs.reportings.ReportingSourceDataOutput.Companion.fromReportingSourceDTO
import org.locationtech.jts.geom.Geometry
import java.time.ZonedDateTime
import java.util.UUID

data class MissionAttachedReportingDataOutput(
val id: Int,
val reportingId: Long? = null,
val sourceType: SourceTypeEnum? = null,
val semaphoreId: Int? = null,
val semaphore: SemaphoreDataOutput? = null,
val controlUnitId: Int? = null,
val controlUnit: ControlUnitDataOutput? = null,
val displayedSource: String? = null,
val sourceName: String? = null,
val reportingSources: List<ReportingSourceDataOutput>,
val targetType: TargetTypeEnum? = null,
val vehicleType: VehicleTypeEnum? = null,
val targetDetails: List<TargetDetailsEntity>? = listOf(),
Expand Down Expand Up @@ -51,37 +44,7 @@ data class MissionAttachedReportingDataOutput(
return MissionAttachedReportingDataOutput(
id = dto.reporting.id,
reportingId = dto.reporting.reportingId,
sourceType = dto.reporting.sourceType,
semaphoreId = dto.reporting.semaphoreId,
semaphore =
if (dto.semaphore != null) {
SemaphoreDataOutput.fromSemaphoreEntity(
dto.semaphore,
)
} else {
null
},
controlUnitId = dto.reporting.controlUnitId,
controlUnit =
if (dto.controlUnit != null) {
ControlUnitDataOutput.fromFullControlUnit(
dto.controlUnit,
)
} else {
null
},
displayedSource =
when (dto.reporting.sourceType) {
SourceTypeEnum.SEMAPHORE ->
dto.semaphore?.unit
?: dto.semaphore?.name
// TODO This is really strange : `fullControlUnit?.controlUnit`
// can't be null and I have to add another `?`...
SourceTypeEnum.CONTROL_UNIT -> dto.controlUnit?.controlUnit?.name
SourceTypeEnum.OTHER -> dto.reporting.sourceName
else -> ""
},
sourceName = dto.reporting.sourceName,
reportingSources = dto.reportingSources.map { fromReportingSourceDTO(it) },
targetType = dto.reporting.targetType,
vehicleType = dto.reporting.vehicleType,
targetDetails = dto.reporting.targetDetails,
Expand Down
Loading

0 comments on commit f0217bc

Please sign in to comment.