Skip to content

Commit

Permalink
Ajout d'infos de balises VMS et JPE (#3227)
Browse files Browse the repository at this point in the history
## Linked issues

- Resolve #3208
- Resolve #3223
  • Loading branch information
louptheron authored Jun 5, 2024
2 parents 54ec887 + cd383b7 commit 78ba0ea
Show file tree
Hide file tree
Showing 72 changed files with 1,331 additions and 529 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package fr.gouv.cnsp.monitorfish.domain.entities.beacon_malfunctions

import java.time.ZonedDateTime

data class Beacon(
val beaconNumber: String,
val vesselId: Int?,
val beaconStatus: BeaconStatus? = null,
val satelliteOperatorId: Int? = null,
val isCoastal: Boolean? = null,
val loggingDatetimeUtc: ZonedDateTime? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ data class LogbookMessage(
enrichGearPortAndSpecyNames(allGears, allPorts, allSpecies)
}

enrichAknowledgeCorrectionAndDeletion(contextMessages)
enrichAcknowledgeCorrectionAndDeletion(contextMessages)
}

fun enrichGearPortAndSpecyNames(
Expand Down Expand Up @@ -175,7 +175,7 @@ data class LogbookMessage(

private fun enrichAcnkowledge(relatedLogbookMessages: List<LogbookMessage>) {
if (this.transmissionFormat == LogbookTransmissionFormat.FLUX ||
software !== null && software.contains(LogbookSoftware.VISIOCAPTURE.software)
LogbookSoftware.isVisioCapture(software)
) {
this.setAcknowledgeAsSuccessful()

Expand Down Expand Up @@ -213,7 +213,7 @@ data class LogbookMessage(
}
}

private fun enrichAknowledgeCorrectionAndDeletion(contextLogbookMessages: List<LogbookMessage>) {
private fun enrichAcknowledgeCorrectionAndDeletion(contextLogbookMessages: List<LogbookMessage>) {
val referenceLogbookMessage = findReferencedLogbookMessage(contextLogbookMessages)
val relatedLogbookMessages = filterRelatedLogbookMessages(contextLogbookMessages)

Expand All @@ -234,7 +234,7 @@ data class LogbookMessage(
}

(transmissionFormat == LogbookTransmissionFormat.FLUX),
(software !== null && software.contains(LogbookSoftware.VISIOCAPTURE.software)),
(LogbookSoftware.isVisioCapture(software)),
-> {
setAcknowledgeAsSuccessful()
}
Expand All @@ -250,7 +250,7 @@ data class LogbookMessage(
}

private fun enrichIsSentByFailoverSoftware() {
if (software !== null && software.contains(LogbookSoftware.E_SACAPT.software)) {
if (LogbookSoftware.isESacapt(software)) {
isSentByFailoverSoftware = true
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,45 @@
package fr.gouv.cnsp.monitorfish.domain.entities.logbook

enum class LogbookSoftware(val software: String) {
/**
* Examples:
* - JP/05883989/VISIOCaptures V1.7.6
* - FP/01641449/VISIOCaptures 2.1.6
* - JP/07210344/VISIOCaptures 2.1.6
*/
VISIOCAPTURE("VISIOCaptures"),

/**
* Examples:
* - e-Sacapt Secours ERSV3 V 1.3.1
*/
E_SACAPT("e-Sacapt"),
;

companion object {
/**
* True for:
* - VisioCaptures in real time (JP and JT)
* - VisioCaptures in sheets (FP)
*/
fun isVisioCapture(software: String?): Boolean {
val isVisioCapture = software?.contains(VISIOCAPTURE.software)

return isVisioCapture ?: false
}

fun isESacapt(software: String?): Boolean {
val isESacapt = software?.contains(E_SACAPT.software)

return isESacapt ?: false
}

fun isVisioCaptureInRealTime(software: String?): Boolean {
val isVisioCapture = software?.let {
it.startsWith("FT") || it.startsWith("JT")
}

return isVisioCapture ?: false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ data class Vessel(
val proprietorEmails: List<String>? = null,
val vesselPhones: List<String>? = null,
val vesselEmails: List<String>? = null,
val beaconNumber: String? = null,
val underCharter: Boolean? = null,
val logbookEquipmentStatus: String? = null,
val hasLogbookEsacapt: Boolean,
val hasVisioCaptures: Boolean? = null,
) {
fun isLessThanTwelveMetersVessel(): Boolean {
return length?.let { it < 12.0 } ?: false
Expand Down Expand Up @@ -107,3 +109,5 @@ val LIKELY_CONTROLLED_COUNTRY_CODES =
CountryCode.SE.alpha3,
CountryCode.GB.alpha3,
)

val UNKNOWN_VESSEL = Vessel(id = -1, flagState = CountryCode.UNDEFINED, hasLogbookEsacapt = false)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package fr.gouv.cnsp.monitorfish.domain.entities.vessel

import fr.gouv.cnsp.monitorfish.domain.entities.beacon_malfunctions.Beacon

data class VesselAndBeacon(
val vessel: Vessel,
val beacon: Beacon? = null,
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package fr.gouv.cnsp.monitorfish.domain.entities.vessel

import fr.gouv.cnsp.monitorfish.domain.entities.beacon_malfunctions.Beacon
import fr.gouv.cnsp.monitorfish.domain.entities.position.Position
import fr.gouv.cnsp.monitorfish.domain.entities.risk_factor.VesselRiskFactor

data class VesselInformation(
val vessel: Vessel?,
val beacon: Beacon?,
val positions: List<Position>,
val vesselRiskFactor: VesselRiskFactor,
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import fr.gouv.cnsp.monitorfish.domain.entities.beacon_malfunctions.Beacon

interface BeaconRepository {
fun search(searched: String): List<Beacon>
fun findBeaconNumberByVesselId(vesselId: Int): String?
fun findBeaconByVesselId(vesselId: Int): Beacon?
fun findActivatedBeaconNumbers(): List<String>
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ interface LogbookReportRepository {

fun findDistinctPriorNotificationTypes(): List<String>

fun findLastReportSoftware(internalReferenceNumber: String): String?

// For test purpose
fun deleteAll()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import com.neovisionaries.i18n.CountryCode
import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.facade.Seafront
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessageTyped
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.PNO
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotification
import fr.gouv.cnsp.monitorfish.domain.entities.reporting.ReportingType
import fr.gouv.cnsp.monitorfish.domain.entities.reporting.filters.ReportingFilter
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.UNKNOWN_VESSEL
import fr.gouv.cnsp.monitorfish.domain.exceptions.CodeNotFoundException
import fr.gouv.cnsp.monitorfish.domain.exceptions.NoERSMessagesFound
import fr.gouv.cnsp.monitorfish.domain.repositories.*
Expand Down Expand Up @@ -62,7 +61,7 @@ class GetPriorNotification(
val vessel = priorNotification.logbookMessageTyped.logbookMessage
.internalReferenceNumber?.let { vesselInternalReferenceNumber ->
allVessels.find { it.internalReferenceNumber == vesselInternalReferenceNumber }
} ?: Vessel(id = -1, flagState = CountryCode.UNDEFINED)
} ?: UNKNOWN_VESSEL

val vesselRiskFactor = vessel.internalReferenceNumber?.let { vesselInternalReferenceNumber ->
allRiskFactors.find { it.internalReferenceNumber == vesselInternalReferenceNumber }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import com.neovisionaries.i18n.CountryCode
import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.facade.Seafront
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.filters.LogbookReportFilter
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.sorters.LogbookReportSortColumn
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotification
import fr.gouv.cnsp.monitorfish.domain.entities.reporting.ReportingType
import fr.gouv.cnsp.monitorfish.domain.entities.reporting.filters.ReportingFilter
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.UNKNOWN_VESSEL
import fr.gouv.cnsp.monitorfish.domain.exceptions.CodeNotFoundException
import fr.gouv.cnsp.monitorfish.domain.repositories.*
import org.springframework.data.domain.Sort
Expand Down Expand Up @@ -49,7 +48,7 @@ class GetPriorNotifications(
val vessel = priorNotification.logbookMessageTyped.logbookMessage
.internalReferenceNumber?.let { vesselInternalReferenceNumber ->
allVessels.find { it.internalReferenceNumber == vesselInternalReferenceNumber }
} ?: Vessel(id = -1, flagState = CountryCode.UNDEFINED)
} ?: UNKNOWN_VESSEL

val vesselRiskFactor = vessel.internalReferenceNumber?.let { vesselInternalReferenceNumber ->
allRiskFactors.find { it.internalReferenceNumber == vesselInternalReferenceNumber }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.vessel

import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookSoftware
import fr.gouv.cnsp.monitorfish.domain.entities.risk_factor.VesselRiskFactor
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.VesselIdentifier
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.VesselInformation
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.VesselTrackDepth
Expand Down Expand Up @@ -58,23 +60,26 @@ class GetVessel(
}

val vessel = vesselFuture.await()
val vesselWithBeaconNumber =
vessel?.id?.let { vesselId ->
val beaconNumber = beaconRepository.findBeaconNumberByVesselId(vesselId)

beaconNumber?.let {
vessel.copy(beaconNumber = it)
}
} ?: vessel
val beacon = vessel?.id?.let { vesselId -> beaconRepository.findBeaconByVesselId(vesselId) }
val hasVisioCaptures = hasVisioCaptures(vessel)

Pair(
vesselTrackHasBeenModified,
VesselInformation(
vesselWithBeaconNumber,
vessel?.copy(hasVisioCaptures = hasVisioCaptures),
beacon,
positions.await(),
vesselRiskFactorsFuture.await() ?: VesselRiskFactor(),
),
)
}
}

private fun hasVisioCaptures(vessel: Vessel?) = vessel?.internalReferenceNumber?.let {
val software = logbookReportRepository.findLastReportSoftware(
it,
)

return@let LogbookSoftware.isVisioCaptureInRealTime(software)
} ?: false
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.vessel

import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.VesselAndBeacon
import fr.gouv.cnsp.monitorfish.domain.repositories.BeaconRepository
import fr.gouv.cnsp.monitorfish.domain.repositories.VesselRepository

Expand All @@ -10,21 +10,28 @@ class SearchVessels(
private val vesselRepository: VesselRepository,
private val beaconRepository: BeaconRepository,
) {
fun execute(searched: String): List<Vessel> {
fun execute(searched: String): List<VesselAndBeacon> {
val vessels = vesselRepository.search(searched).filter {
!(
it.internalReferenceNumber.isNullOrEmpty() &&
it.externalReferenceNumber.isNullOrEmpty() &&
it.ircs.isNullOrEmpty() &&
it.mmsi.isNullOrEmpty() &&
it.beaconNumber.isNullOrEmpty()
it.mmsi.isNullOrEmpty()
)
}
}.map { VesselAndBeacon(vessel = it) }

val vesselIdsFromBeacons = beaconRepository.search(searched).mapNotNull { it.vesselId }
val vesselsFromBeacons = vesselRepository.findVesselsByIds(vesselIdsFromBeacons)
val beacons = beaconRepository.search(searched)
val beaconsVesselId = beacons.mapNotNull { it.vesselId }

return (vessels + vesselsFromBeacons)
.distinctBy { it.id }
val vesselsFromBeacons = vesselRepository
.findVesselsByIds(beaconsVesselId)
.map { vessel ->
val beacon = beacons.find { beacon -> beacon.vesselId == vessel.id }

return@map VesselAndBeacon(vessel, beacon)
}

return (vesselsFromBeacons + vessels)
.distinctBy { it.vessel.id }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class VesselController(

val returnCode = if (vesselTrackHasBeenModified) HttpStatus.ACCEPTED else HttpStatus.OK

ResponseEntity.status(returnCode).body(VesselAndPositionsDataOutput.fromVesselWithData(vesselWithData))
ResponseEntity.status(returnCode).body(VesselAndPositionsDataOutput.fromVesselInformation(vesselWithData))
}
}

Expand Down Expand Up @@ -213,7 +213,7 @@ class VesselController(
searched: String,
): List<VesselIdentityDataOutput> {
return searchVessels.execute(searched).map {
VesselIdentityDataOutput.fromVessel(it)
VesselIdentityDataOutput.fromVesselAndBeacon(it)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ data class VesselAndPositionsDataOutput(
return VesselAndPositionsDataOutput(
vessel = VesselDataOutput.fromVessel(
vesselInformation.vessel,
vesselInformation.beacon,
),
positions = vesselInformation.positions.map {
PositionDataOutput.fromPosition(it)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.light.outputs

import com.neovisionaries.i18n.CountryCode
import fr.gouv.cnsp.monitorfish.domain.entities.beacon_malfunctions.Beacon
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel
import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.BeaconDataOutput
import java.util.*

data class VesselDataOutput(
Expand Down Expand Up @@ -34,11 +36,14 @@ data class VesselDataOutput(
val proprietorEmails: List<String>? = null,
val vesselPhones: List<String>? = null,
val vesselEmails: List<String>? = null,
val beaconNumber: String? = null,
val beacon: BeaconDataOutput? = null,
val underCharter: Boolean? = null,
val logbookEquipmentStatus: String? = null,
val hasLogbookEsacapt: Boolean,
val hasVisioCaptures: Boolean? = null,
) {
companion object {
fun fromVessel(vessel: Vessel?): VesselDataOutput? {
fun fromVessel(vessel: Vessel?, beacon: Beacon?): VesselDataOutput? {
if (vessel == null) {
return null
}
Expand Down Expand Up @@ -73,8 +78,11 @@ data class VesselDataOutput(
proprietorEmails = vessel.proprietorEmails,
vesselPhones = vessel.vesselPhones,
vesselEmails = vessel.vesselEmails,
beaconNumber = vessel.beaconNumber,
beacon = beacon?.let { BeaconDataOutput.fromBeacon(it) },
underCharter = vessel.underCharter,
logbookEquipmentStatus = vessel.logbookEquipmentStatus,
hasLogbookEsacapt = vessel.hasLogbookEsacapt,
hasVisioCaptures = vessel.hasVisioCaptures,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.outputs

import fr.gouv.cnsp.monitorfish.domain.entities.beacon_malfunctions.Beacon
import java.time.ZonedDateTime

data class BeaconDataOutput(
val beaconNumber: String,
val isCoastal: Boolean? = null,
val loggingDatetimeUtc: ZonedDateTime? = null,
) {
companion object {
fun fromBeacon(beacon: Beacon): BeaconDataOutput {
return BeaconDataOutput(
beaconNumber = beacon.beaconNumber,
isCoastal = beacon.isCoastal,
loggingDatetimeUtc = beacon.loggingDatetimeUtc,
)
}
}
}
Loading

0 comments on commit 78ba0ea

Please sign in to comment.