Skip to content

Commit

Permalink
Add basic prior notification list & filters Backend
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangabriele committed Mar 13, 2024
1 parent f86c2bb commit e45eb46
Show file tree
Hide file tree
Showing 48 changed files with 2,044 additions and 752 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ data class LogbookMessage(
val tripNumber: String? = null,
val referencedReportId: String? = null,
var isCorrected: Boolean? = false,
val isEnriched: Boolean,
val operationType: LogbookOperationType,
// TODO What's the difference between `operationDateTime`, `integrationDateTime` and `reportDateTime`? Is it in UTC?
val operationDateTime: ZonedDateTime,
val internalReferenceNumber: String? = null,
val externalReferenceNumber: String? = null,
Expand All @@ -30,4 +32,6 @@ data class LogbookMessage(
val transmissionFormat: LogbookTransmissionFormat,
val software: String? = null,
var isSentByFailoverSoftware: Boolean = false,
val tripGears: List<LogbookTripGear>? = listOf(),
val tripSegments: List<LogbookTripSegment>? = listOf(),
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package fr.gouv.cnsp.monitorfish.domain.entities.logbook

enum class LogbookOperationType {
/** Transmission. */
DAT,

/** Correction. */
COR,

/** Suppression. */
DEL,

/** Acquittement. */
RET,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package fr.gouv.cnsp.monitorfish.domain.entities.logbook

data class LogbookTripGear(
val gear: String,
val mesh: Int,
val dimensions: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package fr.gouv.cnsp.monitorfish.domain.entities.logbook

import com.fasterxml.jackson.annotation.JsonProperty

data class LogbookTripSegment(
val segment: String,
@JsonProperty("segment_name")
val segmentName: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class PNO() : LogbookMessageValue {

@JsonProperty("predictedArrivalDatetimeUtc")
var predictedArrivalDateTime: ZonedDateTime? = null
@JsonProperty("predictedLandingDatetimeUtc")
var predictedLandingDatetime: ZonedDateTime? = null

var tripStartDate: ZonedDateTime? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package fr.gouv.cnsp.monitorfish.domain.entities.vessel

data class VesselId(
val identifier: VesselIdentifier,
val value: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package fr.gouv.cnsp.monitorfish.domain.filters

import fr.gouv.cnsp.monitorfish.domain.entities.vessel.VesselId

data class LogbookReportFilter(
val flagStates: List<String>? = null,
val integratedAfter: String? = null,
val integratedBefore: String? = null,
val portLocodes: List<String>? = null,
val searchQuery: String? = null,
val specyCodes: List<String>? = null,
val tripSegmentSegments: List<String>? = null,
val tripGearCodes: List<String>? = null,
val vesselId: VesselId? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package fr.gouv.cnsp.monitorfish.domain.filters

data class PriorNotificationFilter(
val countryCodes: List<String>? = null,
val fleetSegmentSegments: List<String>? = null,
val gearCodes: List<String>? = listOf(),
val hasOneOrMoreReportings: Boolean? = null,
val isLessThanTwelveMetersVessel: Boolean? = null,
val isSent: Boolean? = null,
val isVesselPretargeted: Boolean? = null,
val lastControlStartDate: String? = null,
val lastControlEndDate: String? = null,
val portLocodes: List<String>? = null,
val query: String? = null,
val receivedAtStartDate: String? = null,
val receivedAtEndDate: String? = null,
// val seaFrontGroup: SeaFrontGroup | 'EXTRA',
val specyCodes: List<String>? = null,
val searchQuery: String? = null,
// val types: PriorNotification.PriorNotificationType[]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package fr.gouv.cnsp.monitorfish.domain.filters

import fr.gouv.cnsp.monitorfish.domain.entities.reporting.ReportingType

data class ReportingFilter(
val isArchived: Boolean? = null,
val isDeleted: Boolean? = null,
val types: List<ReportingType>? = null,
val vesselId: Int? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ package fr.gouv.cnsp.monitorfish.domain.repositories
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessage
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.VoyageDatesAndTripNumber
import fr.gouv.cnsp.monitorfish.domain.exceptions.NoLogbookFishingTripFound
import fr.gouv.cnsp.monitorfish.domain.filters.LogbookReportFilter
import fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification.dtos.PriorNotification
import java.time.ZonedDateTime

interface LogbookReportRepository {
fun findAllPriorNotifications(filter: LogbookReportFilter? = null): List<PriorNotification>

@Throws(NoLogbookFishingTripFound::class)
fun findLastTripBeforeDateTime(
internalReferenceNumber: String,
Expand All @@ -25,7 +29,11 @@ interface LogbookReportRepository {
): VoyageDatesAndTripNumber

@Throws(NoLogbookFishingTripFound::class)
fun findTripAfterTripNumber(internalReferenceNumber: String, tripNumber: String): VoyageDatesAndTripNumber
fun findTripAfterTripNumber(
internalReferenceNumber: String,
tripNumber: String,
): VoyageDatesAndTripNumber

fun findAllMessagesByTripNumberBetweenDates(
internalReferenceNumber: String,
afterDate: ZonedDateTime,
Expand All @@ -34,16 +42,25 @@ interface LogbookReportRepository {
): List<LogbookMessage>

fun findLANAndPNOMessagesNotAnalyzedBy(ruleType: String): List<Pair<LogbookMessage, LogbookMessage?>>
fun updateLogbookMessagesAsProcessedByRule(ids: List<Long>, ruleType: String)

fun updateLogbookMessagesAsProcessedByRule(
ids: List<Long>,
ruleType: String,
)

fun findById(id: Long): LogbookMessage

fun findLastMessageDate(): ZonedDateTime

fun findLastTwoYearsTripNumbers(internalReferenceNumber: String): List<String>

fun findFirstAndLastOperationsDatesOfTrip(
internalReferenceNumber: String,
tripNumber: String,
): VoyageDatesAndTripNumber

// For test purpose
fun deleteAll()

fun save(message: LogbookMessage)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,37 @@ import fr.gouv.cnsp.monitorfish.domain.entities.reporting.InfractionSuspicion
import fr.gouv.cnsp.monitorfish.domain.entities.reporting.Observation
import fr.gouv.cnsp.monitorfish.domain.entities.reporting.Reporting
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.VesselIdentifier
import fr.gouv.cnsp.monitorfish.domain.filters.ReportingFilter
import java.time.ZonedDateTime

interface ReportingRepository {
fun save(alert: PendingAlert, validationDate: ZonedDateTime?)
fun save(
alert: PendingAlert,
validationDate: ZonedDateTime?,
)

fun save(reporting: Reporting): Reporting
fun update(reportingId: Int, updatedInfractionSuspicion: InfractionSuspicion): Reporting
fun update(reportingId: Int, updatedObservation: Observation): Reporting
fun findAll(): List<Reporting>

fun update(
reportingId: Int,
updatedInfractionSuspicion: InfractionSuspicion,
): Reporting

fun update(
reportingId: Int,
updatedObservation: Observation,
): Reporting

fun findAll(filter: ReportingFilter? = null): List<Reporting>

fun findById(reportingId: Int): Reporting
fun findAllCurrent(): List<Reporting>

fun findCurrentAndArchivedByVesselIdentifierEquals(
vesselIdentifier: VesselIdentifier,
value: String,
fromDate: ZonedDateTime,
): List<Reporting>

fun findCurrentAndArchivedByVesselIdEquals(
vesselId: Int,
fromDate: ZonedDateTime,
Expand All @@ -33,5 +49,6 @@ interface ReportingRepository {
): List<Reporting>

fun archive(id: Int)

fun delete(id: Int)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ package fr.gouv.cnsp.monitorfish.domain.repositories
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel

interface VesselRepository {
fun findVessel(internalReferenceNumber: String, externalReferenceNumber: String, ircs: String): Vessel?
fun findVessel(
internalReferenceNumber: String? = null,
externalReferenceNumber: String? = null,
ircs: String? = null,
): Vessel?

fun findVesselsByIds(ids: List<Int>): List<Vessel>

fun findVessel(vesselId: Int): Vessel?

fun search(searched: String): List<Vessel>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import fr.gouv.cnsp.monitorfish.config.UseCase
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.use_cases.prior_notification.dtos.PriorNotification
import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.*
import org.locationtech.jts.geom.Coordinate
import org.locationtech.jts.geom.GeometryFactory

@UseCase
class GetPriorNotifications(
private val facadeAreasRepository: JpaFacadeAreasRepository,
private val logbookReportRepository: JpaLogbookReportRepository,
private val portRepository: JpaPortRepository,
private val reportingRepository: JpaReportingRepository,
private val riskFactorRepository: JpaRiskFactorsRepository,
private val vesselRepository: JpaVesselRepository,
) {
fun execute(filter: LogbookReportFilter): List<PriorNotification> {
val priorNotifications =
logbookReportRepository.findAllPriorNotifications(filter).map { priorNotification ->
val port =
try {
priorNotification.portLocode?.let {
portRepository.find(it)
}
} catch (e: CodeNotFoundException) {
null
}

// TODO Doesn't seem to work.
val seaFront =
port?.latitude?.let { latitude ->
port.longitude?.let { longitude ->
val point = GeometryFactory().createPoint(Coordinate(longitude, latitude))

facadeAreasRepository.findByIncluding(point).firstOrNull()?.facade
}
}

val vessel =
vesselRepository.findVessel(
priorNotification.logbookMessage?.internalReferenceNumber,
priorNotification.logbookMessage?.externalReferenceNumber,
priorNotification.logbookMessage?.ircs,
)

val reportingsCount =
vessel?.id.let { vesselId ->
val reportingsFilter =
ReportingFilter(
isArchived = false,
isDeleted = false,
vesselId = vesselId,
)

reportingRepository.findAll(reportingsFilter).count()
}

val vesselRiskFactor =
priorNotification.logbookMessage?.internalReferenceNumber?.let {
riskFactorRepository.findVesselRiskFactors(it)
}

priorNotification.copy(
port = port,
reportingsCount = reportingsCount,
seaFront = seaFront,
vessel = vessel,
vesselRiskFactor = vesselRiskFactor,
)
}

return priorNotifications
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification.dtos

import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessage
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.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 logbookMessage: LogbookMessage?,
// TODO It's only used for later use case resolution and not exposed in the data outpur. Maybe find a way to remove it from the DTO?
val portLocode: String?,
val reportingsCount: Int? = null,
val tripGears: List<LogbookTripGear>,
val tripSegments: List<LogbookTripSegment>,
val port: Port? = null,
val seaFront: String? = null,
val vessel: Vessel? = null,
val vesselRiskFactor: VesselRiskFactor? = null,
)
Loading

0 comments on commit e45eb46

Please sign in to comment.