Skip to content

Commit

Permalink
Clean and optimize prior notification relations in Backend
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangabriele committed Mar 26, 2024
1 parent 03093d4 commit 363a954
Show file tree
Hide file tree
Showing 24 changed files with 430 additions and 277 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages

import com.fasterxml.jackson.annotation.JsonProperty
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.Catch
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationType
import java.time.ZonedDateTime

class PNO() : LogbookMessageValue {
Expand All @@ -11,7 +12,10 @@ class PNO() : LogbookMessageValue {
var statisticalRectangle: String? = null
var latitude: Double? = null
var longitude: Double? = null
var pnoTypes: List<PriorNotificationType> = listOf()
var purpose: String? = null

/** Port locode. */
var port: String? = null
var portName: String? = null
var catchOnboard: List<Catch> = listOf()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
package fr.gouv.cnsp.monitorfish.domain.entities.prior_notification

import fr.gouv.cnsp.monitorfish.domain.entities.logbook.Catch
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookTripGear
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookTripSegment
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessage
import fr.gouv.cnsp.monitorfish.domain.entities.port.Port
import fr.gouv.cnsp.monitorfish.domain.entities.risk_factor.VesselRiskFactor
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel

data class PriorNotification(
val id: Long,
val expectedArrivalDate: String?,
val expectedLandingDate: String?,
val notificationTypeLabel: String? = null,
val onboardCatches: List<Catch>,
val portLocode: String?,
val portName: String? = null,
val purposeCode: String?,
val logbookMessage: LogbookMessage,
val port: Port? = null,
val reportingsCount: Int? = null,
val seaFront: String? = null,
val sentAt: String?,
val tripGears: List<LogbookTripGear>,
val tripSegments: List<LogbookTripSegment>,
val types: List<PriorNotificationType>,
val vessel: Vessel,
val vesselLastControlDate: String?,
val vesselRiskFactor: Double?,
val vesselRiskFactorImpact: Double?,
val vesselRiskFactorProbability: Double?,
val vesselRiskFactorDetectability: Double?,
val vesselRiskFactor: VesselRiskFactor?,
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ data class ReportingFilter(
val isArchived: Boolean? = null,
val isDeleted: Boolean? = null,
val types: List<ReportingType>? = null,
val vesselInternalReferenceNumbers: List<String>? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ import fr.gouv.cnsp.monitorfish.domain.entities.facade.FacadeArea
import org.locationtech.jts.geom.Point

interface FacadeAreasRepository {
fun findAll(): List<FacadeArea>

fun findByIncluding(point: Point): List<FacadeArea>
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.PNO
import fr.gouv.cnsp.monitorfish.domain.entities.port.Port
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.exceptions.CodeNotFoundException
import fr.gouv.cnsp.monitorfish.domain.filters.LogbookReportFilter
import fr.gouv.cnsp.monitorfish.domain.filters.ReportingFilter
import fr.gouv.cnsp.monitorfish.domain.repositories.*
import org.locationtech.jts.geom.Coordinate
import org.locationtech.jts.geom.GeometryFactory
import java.time.ZonedDateTime

@UseCase
class GetPriorNotifications(
Expand All @@ -18,10 +20,10 @@ class GetPriorNotifications(
private val reportingRepository: ReportingRepository,
) {
fun execute(filter: LogbookReportFilter): List<PriorNotification> {
val priorNotifications =
val priorNotificationsWithoutReportingsCount =
logbookReportRepository.findAllPriorNotifications(filter).map { priorNotification ->
val port = try {
priorNotification.portLocode?.let {
(priorNotification.logbookMessage.message as PNO).port?.let {
portRepository.find(it)
}
} catch (e: CodeNotFoundException) {
Expand All @@ -30,29 +32,51 @@ class GetPriorNotifications(

val seaFront = getSeaFrontFromPort(port)

val reportingsCount = reportingRepository.findCurrentAndArchivedByVesselIdEquals(
priorNotification.vessel.id,
// TODO Fix that.
fromDate = ZonedDateTime.now().minusYears(2),
).count()

priorNotification.copy(
portName = port?.name,
reportingsCount = reportingsCount,
port = port,
seaFront = seaFront,
)
}

val priorNotifications = enrichPriorNotificationsWithReportingCount(priorNotificationsWithoutReportingsCount)

return priorNotifications
}

private fun enrichPriorNotificationsWithReportingCount(
priorNotifications: List<PriorNotification>,
): List<PriorNotification> {
val currentReportings = reportingRepository.findAll(
ReportingFilter(
vesselInternalReferenceNumbers = priorNotifications.mapNotNull { it.vessel.internalReferenceNumber },
isArchived = false,
isDeleted = false,
types = listOf(ReportingType.INFRACTION_SUSPICION),
),
)

val priorNotificationsWithReportingCount = priorNotifications.map { priorNotification ->
val reportingsCount = currentReportings.count { reporting ->
reporting.internalReferenceNumber == priorNotification.vessel.internalReferenceNumber
}

priorNotification.copy(reportingsCount = reportingsCount)
}

return priorNotificationsWithReportingCount
}

private fun getSeaFrontFromPort(port: Port?): String? {
if (port?.latitude == null || port.longitude == null) {
return null
}

// Cached call
val facadeAreas = facadeAreasRepository.findAll()
val point = GeometryFactory().createPoint(Coordinate(port.longitude, port.latitude))

return facadeAreasRepository.findByIncluding(point).firstOrNull()?.facade
return facadeAreas.find { facadeArea ->
facadeArea.geometry.contains(point)
}?.facade
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.outputs

import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.PNO
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotification

class PriorNotificationDataOutput(
val id: Long,
val expectedArrivalDate: String?,
val expectedLandingDate: String?,
val notificationTypeLabel: String?,
val onBoardCatches: List<LogbookMessageCatchDataOutput>,
val portLocode: String?,
val portName: String?,
Expand All @@ -17,46 +17,58 @@ class PriorNotificationDataOutput(
val tripGears: List<LogbookMessageTripGearDataOutput>,
val tripSegments: List<LogbookMessageTripSegmentDataOutput>,
val types: List<PriorNotificationTypeDataOutput>,
val vessel: VesselDataOutput,
val vesselId: Int?,
val vesselExternalReferenceNumber: String?,
val vesselFlagCountryCode: String?,
val vesselInternalReferenceNumber: String?,
val vesselIrcs: String?,
val vesselLastControlDate: String?,
val vesselLength: Double?,
val vesselMmsi: String?,
val vesselName: String?,
val vesselRiskFactorImpact: Double?,
val vesselRiskFactorProbability: Double?,
val vesselRiskFactorDetectability: Double?,
val vesselRiskFactor: Double?,
) {
companion object {
fun fromPriorNotification(priorNotification: PriorNotification): PriorNotificationDataOutput {
val onBoardCatches = priorNotification.onboardCatches.map { LogbookMessageCatchDataOutput.fromCatch(it) }
val tripGears = priorNotification.tripGears.map { LogbookMessageTripGearDataOutput.fromLogbookTripGear(it) }
val tripSegments =
priorNotification.tripSegments.map {
LogbookMessageTripSegmentDataOutput.fromLogbookTripSegment(
it,
)
}
val types = priorNotification.types.map { PriorNotificationTypeDataOutput.fromPriorNotificationType(it) }
val message = priorNotification.logbookMessage.message as PNO

val onBoardCatches = message.catchOnboard.map { LogbookMessageCatchDataOutput.fromCatch(it) }
val tripGears = priorNotification.logbookMessage.tripGears?.map {
LogbookMessageTripGearDataOutput.fromLogbookTripGear(it)
} ?: emptyList()
val tripSegments = priorNotification.logbookMessage.tripSegments?.map {
LogbookMessageTripSegmentDataOutput.fromLogbookTripSegment(it)
} ?: emptyList()
val types = message.pnoTypes.map { PriorNotificationTypeDataOutput.fromPriorNotificationType(it) }

return PriorNotificationDataOutput(
id = priorNotification.id,
expectedArrivalDate = priorNotification.expectedArrivalDate,
expectedLandingDate = priorNotification.expectedLandingDate,
notificationTypeLabel = priorNotification.notificationTypeLabel,
expectedArrivalDate = message.predictedArrivalDateTime.toString(),
expectedLandingDate = message.predictedLandingDatetime.toString(),
onBoardCatches,
portLocode = priorNotification.portLocode,
portName = priorNotification.portName,
purposeCode = priorNotification.purposeCode,
portLocode = priorNotification.port?.locode,
portName = priorNotification.port?.name,
purposeCode = message.purpose,
reportingsCount = priorNotification.reportingsCount,
seaFront = priorNotification.seaFront,
sentAt = priorNotification.sentAt,
sentAt = priorNotification.logbookMessage.reportDateTime.toString(),
tripGears,
tripSegments,
types,
vessel = VesselDataOutput.fromVessel(priorNotification.vessel),
vesselLastControlDate = priorNotification.vesselLastControlDate,
vesselRiskFactorImpact = priorNotification.vesselRiskFactorImpact,
vesselRiskFactorProbability = priorNotification.vesselRiskFactorProbability,
vesselRiskFactorDetectability = priorNotification.vesselRiskFactorDetectability,
vesselRiskFactor = priorNotification.vesselRiskFactor,
vesselId = priorNotification.vessel.id,
vesselExternalReferenceNumber = priorNotification.vessel.externalReferenceNumber,
vesselFlagCountryCode = priorNotification.vessel.flagState.toString(),
vesselInternalReferenceNumber = priorNotification.vessel.internalReferenceNumber,
vesselIrcs = priorNotification.vessel.ircs,
vesselLastControlDate = priorNotification.vesselRiskFactor?.lastControlDatetime?.toString(),
vesselLength = priorNotification.vessel.length,
vesselMmsi = priorNotification.vessel.mmsi,
vesselName = priorNotification.vessel.vesselName,
vesselRiskFactorImpact = priorNotification.vesselRiskFactor?.impactRiskFactor,
vesselRiskFactorProbability = priorNotification.vesselRiskFactor?.probabilityRiskFactor,
vesselRiskFactorDetectability = priorNotification.vesselRiskFactor?.detectabilityRiskFactor,
)
}
}
Expand Down
Loading

0 comments on commit 363a954

Please sign in to comment.