diff --git a/Makefile b/Makefile index 79666b35e3..574d5c4758 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,10 @@ run-back: run-stubbed-apis docker compose up -d --quiet-pull --wait db keycloak cd backend && ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)' +run-back-for-cypress: run-stubbed-apis + docker compose up -d --quiet-pull --wait db keycloak + cd backend && MONITORFISH_OIDC_ENABLED=false ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)' + run-back-with-monitorenv: run-monitorenv docker compose up -d --quiet-pull --wait db cd backend && MONITORENV_URL=http://localhost:9880 ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)' diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessage.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessage.kt index a3888b1eb0..b8e947625c 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessage.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessage.kt @@ -4,7 +4,6 @@ import fr.gouv.cnsp.monitorfish.domain.entities.gear.Gear import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.* import fr.gouv.cnsp.monitorfish.domain.entities.port.Port import fr.gouv.cnsp.monitorfish.domain.entities.species.Species -import fr.gouv.cnsp.monitorfish.domain.exceptions.EntityConversionException import org.slf4j.LoggerFactory import java.time.ZonedDateTime @@ -44,45 +43,6 @@ data class LogbookMessage( ) { private val logger = LoggerFactory.getLogger(LogbookMessage::class.java) - /** - * Returns the reference logbook message `reportId` (= the original DAT operation `reportId`). - */ - fun getReferenceReportId(): String? { - return referencedReportId ?: reportId - } - - fun toConsolidatedLogbookMessageAndValue( - relatedLogbookMessages: List, - clazz: Class, - ): LogbookMessageAndValue { - if (reportId == null) { - throw EntityConversionException( - "Logbook report $id has no `reportId`. You can only enrich a DAT or an orphan COR operation with a `reportId`.", - ) - } - if (operationType !in listOf(LogbookOperationType.DAT, LogbookOperationType.COR)) { - throw EntityConversionException( - "Logbook report $id has operationType '$operationType'. You can only enrich a DAT or an orphan COR operation.", - ) - } - - val historicallySortedRelatedLogbookMessages = relatedLogbookMessages.sortedBy { it.reportDateTime } - val maybeLastLogbookMessageCorrection = historicallySortedRelatedLogbookMessages - .lastOrNull { it.operationType == LogbookOperationType.COR } - - val logbookMessageBase = maybeLastLogbookMessageCorrection ?: this - logbookMessageBase.enrichAcnkowledge(relatedLogbookMessages) - val finalLogbookMessage = logbookMessageBase.copy( - isCorrectedByNewerMessage = false, - isDeleted = historicallySortedRelatedLogbookMessages.any { it.operationType == LogbookOperationType.DEL }, - ) - - return LogbookMessageAndValue( - logbookMessage = finalLogbookMessage, - clazz = clazz, - ) - } - fun setAcknowledge(newLogbookMessageAcknowledgement: LogbookMessage) { val currentAcknowledgement = this.acknowledgment val newAcknowledgement = newLogbookMessageAcknowledgement.message as Acknowledgment @@ -172,46 +132,6 @@ data class LogbookMessage( } } - private fun enrichAcnkowledge(relatedLogbookMessages: List) { - if (this.transmissionFormat == LogbookTransmissionFormat.FLUX || - LogbookSoftware.isVisioCapture(software) - ) { - this.setAcknowledgeAsSuccessful() - - return - } - - val historycallyOrderedRetLogbookMessages = relatedLogbookMessages - .filter { it.operationType == LogbookOperationType.RET && it.referencedReportId == reportId } - .sortedBy { it.reportDateTime } - - val maybeLastSuccessfulRetLogbookMessage = historycallyOrderedRetLogbookMessages.lastOrNull { - val message = it.message as Acknowledgment - - message.returnStatus == RETReturnErrorCode.SUCCESS.number - } - // If there is at least one successful RET message, we consider the report as acknowledged - if (maybeLastSuccessfulRetLogbookMessage != null) { - val lastSucessfulRetMessage = maybeLastSuccessfulRetLogbookMessage.message as Acknowledgment - this.acknowledgment = lastSucessfulRetMessage.also { - it.dateTime = maybeLastSuccessfulRetLogbookMessage.reportDateTime - it.isSuccess = true - } - - return - } - - // Else we consider the last (failure) RET message as the final acknowledgement - val maybeLastRetLogbookMessage = historycallyOrderedRetLogbookMessages.lastOrNull() - if (maybeLastRetLogbookMessage != null) { - val lastRetMessage = maybeLastRetLogbookMessage.message as Acknowledgment - this.acknowledgment = lastRetMessage.also { - it.dateTime = maybeLastRetLogbookMessage.reportDateTime - it.isSuccess = lastRetMessage.returnStatus == RETReturnErrorCode.SUCCESS.number - } - } - } - private fun enrichAcknowledgeCorrectionAndDeletion(contextLogbookMessages: List) { val referenceLogbookMessage = findReferencedLogbookMessage(contextLogbookMessages) val relatedLogbookMessages = filterRelatedLogbookMessages(contextLogbookMessages) diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/prior_notification/PriorNotification.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/prior_notification/PriorNotification.kt index 5a53876cf9..c1ee89b178 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/prior_notification/PriorNotification.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/prior_notification/PriorNotification.kt @@ -2,13 +2,16 @@ package fr.gouv.cnsp.monitorfish.domain.entities.prior_notification import fr.gouv.cnsp.monitorfish.domain.entities.facade.Seafront import fr.gouv.cnsp.monitorfish.domain.entities.gear.Gear +import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessage import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessageAndValue +import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.Acknowledgment 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.reporting.ReportingType import fr.gouv.cnsp.monitorfish.domain.entities.reporting.filters.ReportingFilter import fr.gouv.cnsp.monitorfish.domain.entities.risk_factor.VesselRiskFactor import fr.gouv.cnsp.monitorfish.domain.entities.species.Species +import fr.gouv.cnsp.monitorfish.domain.entities.vessel.UNKNOWN_VESSEL import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel import fr.gouv.cnsp.monitorfish.domain.exceptions.BackendInternalErrorCode import fr.gouv.cnsp.monitorfish.domain.exceptions.NoERSMessagesFound @@ -136,20 +139,52 @@ data class PriorNotification( reportingCount = currentReportings?.count() ?: 0 } + fun markAsAcknowledged() { + logbookMessageAndValue = LogbookMessageAndValue( + logbookMessageAndValue.logbookMessage.copy(acknowledgment = Acknowledgment(isSuccess = true)), + PNO::class.java, + ) + } + companion object { private val logger = LoggerFactory.getLogger(PriorNotification::class.java) + fun fromLogbookMessage(logbookMessage: LogbookMessage): PriorNotification { + val logbookMessageAndValue = LogbookMessageAndValue( + logbookMessage = logbookMessage, + clazz = PNO::class.java, + ) + + return PriorNotification( + reportId = logbookMessage.reportId, + createdAt = logbookMessage.operationDateTime, + didNotFishAfterZeroNotice = false, + isManuallyCreated = false, + logbookMessageAndValue = logbookMessageAndValue, + sentAt = logbookMessageAndValue.logbookMessage.reportDateTime, + updatedAt = logbookMessage.operationDateTime, + + // These props need to be calculated in the use case + port = null, + reportingCount = null, + seafront = null, + // For practical reasons `vessel` can't be `null`, so we temporarily set it to "Navire inconnu" + vessel = UNKNOWN_VESSEL, + lastControlDateTime = null, + ) + } + /** * Next initial state of the prior notification once it will be created or updated. * * Used within the prior notification form to display the next state of the prior notification in real-time. */ fun getNextState( - isInverificationScope: Boolean, + isInVerificationScope: Boolean, isPartOfControlUnitSubscriptions: Boolean, ): PriorNotificationState { return when { - isInverificationScope -> PriorNotificationState.PENDING_VERIFICATION + isInVerificationScope -> PriorNotificationState.PENDING_VERIFICATION isPartOfControlUnitSubscriptions -> PriorNotificationState.AUTO_SEND_REQUESTED else -> PriorNotificationState.OUT_OF_VERIFICATION_SCOPE } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/repositories/LogbookReportRepository.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/repositories/LogbookReportRepository.kt index 8769073298..82f4671eac 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/repositories/LogbookReportRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/repositories/LogbookReportRepository.kt @@ -10,7 +10,7 @@ import fr.gouv.cnsp.monitorfish.domain.exceptions.NoLogbookFishingTripFound import java.time.ZonedDateTime interface LogbookReportRepository { - fun findAllPriorNotifications(filter: PriorNotificationsFilter): List + fun findAllAcknowledgedPriorNotifications(filter: PriorNotificationsFilter): List @Throws(NoLogbookFishingTripFound::class) fun findLastTripBeforeDateTime( @@ -46,7 +46,7 @@ interface LogbookReportRepository { // Only used in tests fun findById(id: Long): LogbookMessage - fun findPriorNotificationByReportId(reportId: String, operationDate: ZonedDateTime): PriorNotification? + fun findAcknowledgedPriorNotificationByReportId(reportId: String, operationDate: ZonedDateTime): PriorNotification? fun findLastMessageDate(): ZonedDateTime diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotification.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotification.kt index 30aba7b34a..1577a276e7 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotification.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotification.kt @@ -29,7 +29,7 @@ class GetPriorNotification( val priorNotification = if (isManuallyCreated) { manualPriorNotificationRepository.findByReportId(reportId) } else { - logbookReportRepository.findPriorNotificationByReportId(reportId, operationDate) + logbookReportRepository.findAcknowledgedPriorNotificationByReportId(reportId, operationDate) } ?: throw BackendUsageException(BackendUsageErrorCode.NOT_FOUND) @@ -55,6 +55,7 @@ class GetPriorNotification( } else { null } + false -> if (priorNotification.logbookMessageAndValue.logbookMessage.internalReferenceNumber != null) { vesselRepository.findFirstByInternalReferenceNumber( priorNotification.logbookMessageAndValue.logbookMessage.internalReferenceNumber!!, diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotifications.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotifications.kt index 5e04c42b9f..83a0d0d346 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotifications.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotifications.kt @@ -43,7 +43,7 @@ class GetPriorNotifications( val allSpecies = speciesRepository.findAll() val (automaticPriorNotifications, findAllPriorNotificationsTimeTaken) = measureTimedValue { - logbookReportRepository.findAllPriorNotifications(filter) + logbookReportRepository.findAllAcknowledgedPriorNotifications(filter) } logger.info( "TIME_RECORD - 'logbookReportRepository.findAllPriorNotifications()' took $findAllPriorNotificationsTimeTaken.", @@ -58,11 +58,8 @@ class GetPriorNotifications( val incompletePriorNotifications = automaticPriorNotifications + manualPriorNotifications - val undeletedPriorNotifications = incompletePriorNotifications - .filter { !it.logbookMessageAndValue.logbookMessage.isDeleted } - val (priorNotifications, enrichedPriorNotificationsTimeTaken) = measureTimedValue { - undeletedPriorNotifications + incompletePriorNotifications .map { priorNotification -> priorNotification.enrich(allRiskFactors, allPorts, priorNotification.isManuallyCreated) priorNotification.logbookMessageAndValue.logbookMessage diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationDetailDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationDetailDataOutput.kt index 206d5d5847..f4c6eef0ae 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationDetailDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationDetailDataOutput.kt @@ -19,6 +19,10 @@ class PriorNotificationDetailDataOutput( ) { companion object { fun fromPriorNotification(priorNotification: PriorNotification): PriorNotificationDetailDataOutput { + val reportId = requireNotNull(priorNotification.reportId) { + "`reportId` is null." + } + val isLessThanTwelveMetersVessel = requireNotNull(priorNotification.vessel) { "`priorNotification.vessel` is null." }.isLessThanTwelveMetersVessel() @@ -26,13 +30,11 @@ class PriorNotificationDetailDataOutput( "`priorNotification.vessel` is null." }.underCharter val logbookMessage = priorNotification.logbookMessageAndValue.logbookMessage - val referenceReportId = requireNotNull(logbookMessage.getReferenceReportId()) { - "`logbookMessage.getReferenceReportId()` returned null." - } + val logbookMessageDataOutput = LogbookMessageDataOutput.fromLogbookMessage(logbookMessage) return PriorNotificationDetailDataOutput( - reportId = referenceReportId, + reportId, fingerprint = priorNotification.fingerprint, isLessThanTwelveMetersVessel = isLessThanTwelveMetersVessel, isManuallyCreated = priorNotification.isManuallyCreated, diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationListItemDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationListItemDataOutput.kt index 7f78e74564..f6c2a6debe 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationListItemDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PriorNotificationListItemDataOutput.kt @@ -10,8 +10,7 @@ import org.slf4j.LoggerFactory import java.time.ZonedDateTime data class PriorNotificationListItemDataOutput( - /** Reference logbook message (report) `reportId`. */ - val id: String, + val reportId: String, val acknowledgment: AcknowledgmentDataOutput?, val createdAt: ZonedDateTime?, val expectedArrivalDate: ZonedDateTime?, @@ -51,13 +50,13 @@ data class PriorNotificationListItemDataOutput( val logger: Logger = LoggerFactory.getLogger(PriorNotificationListItemDataOutput::class.java) fun fromPriorNotification(priorNotification: PriorNotification): PriorNotificationListItemDataOutput? { - val logbookMessage = priorNotification.logbookMessageAndValue.logbookMessage - val referenceReportId = logbookMessage.getReferenceReportId() - if (referenceReportId == null) { - logger.warn("Prior notification has neither `reportId` nor `referencedReportId`: $priorNotification.") + if (priorNotification.reportId == null) { + logger.warn("Prior notification has no `reportId`: $priorNotification.") return null } + + val logbookMessage = priorNotification.logbookMessageAndValue.logbookMessage val message = priorNotification.logbookMessageAndValue.value val acknowledgment = logbookMessage.acknowledgment?.let { AcknowledgmentDataOutput.fromAcknowledgment(it) } @@ -73,7 +72,7 @@ data class PriorNotificationListItemDataOutput( val vessel = requireNotNull(priorNotification.vessel) { "`vessel` is null." } return PriorNotificationListItemDataOutput( - id = referenceReportId, + reportId = priorNotification.reportId, acknowledgment = acknowledgment, createdAt = priorNotification.createdAt, expectedArrivalDate = message.predictedArrivalDatetimeUtc, diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/LogbookReportEntity.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/LogbookReportEntity.kt index 560043db78..7a39b334a3 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/LogbookReportEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/LogbookReportEntity.kt @@ -2,9 +2,6 @@ package fr.gouv.cnsp.monitorfish.infrastructure.database.entities import com.fasterxml.jackson.databind.ObjectMapper import fr.gouv.cnsp.monitorfish.domain.entities.logbook.* -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.vessel.UNKNOWN_VESSEL import fr.gouv.cnsp.monitorfish.domain.mappers.ERSMapper.getERSMessageValueFromJSON import io.hypersistence.utils.hibernate.type.json.JsonBinaryType import jakarta.persistence.* @@ -140,35 +137,6 @@ data class LogbookReportEntity( ) } - fun toPriorNotification(mapper: ObjectMapper, relatedModels: List): PriorNotification { - val referenceLogbookMessage = toLogbookMessage(mapper) - val relatedLogbookMessages = relatedModels - .map { it.toLogbookMessage(mapper) } - .sortedBy { it.operationDateTime } - val consolidatedLogbookMessageAndValue = referenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - val updatedAt = relatedLogbookMessages.lastOrNull()?.operationDateTime ?: operationDateTime.atZone(UTC) - // For practical reasons `vessel` can't be `null`, so we temporarily set it to "Navire inconnu" - val vessel = UNKNOWN_VESSEL - - return PriorNotification( - reportId = reportId, - createdAt = operationDateTime.atZone(UTC), - didNotFishAfterZeroNotice = false, - isManuallyCreated = false, - logbookMessageAndValue = consolidatedLogbookMessageAndValue, - sentAt = consolidatedLogbookMessageAndValue.logbookMessage.reportDateTime, - updatedAt = updatedAt, - - // These props need to be calculated in the use case - port = null, - reportingCount = null, - seafront = null, - vessel = vessel, - lastControlDateTime = null, - ) - } - private fun deserializeJSONList( mapper: ObjectMapper, json: String?, diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepository.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepository.kt index 3469e22f79..1dcd32c13b 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepository.kt @@ -9,14 +9,16 @@ import fr.gouv.cnsp.monitorfish.domain.entities.logbook.VoyageDatesAndTripNumber 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.prior_notification.filters.PriorNotificationsFilter -import fr.gouv.cnsp.monitorfish.domain.exceptions.* +import fr.gouv.cnsp.monitorfish.domain.exceptions.BackendUsageErrorCode +import fr.gouv.cnsp.monitorfish.domain.exceptions.BackendUsageException +import fr.gouv.cnsp.monitorfish.domain.exceptions.NoERSMessagesFound +import fr.gouv.cnsp.monitorfish.domain.exceptions.NoLogbookFishingTripFound import fr.gouv.cnsp.monitorfish.domain.repositories.LogbookReportRepository import fr.gouv.cnsp.monitorfish.infrastructure.database.entities.LogbookReportEntity import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.interfaces.DBLogbookReportRepository import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.utils.toSqlArrayString import fr.gouv.cnsp.monitorfish.utils.CustomZonedDateTime import jakarta.transaction.Transactional -import org.slf4j.LoggerFactory import org.springframework.cache.annotation.CacheEvict import org.springframework.cache.annotation.Cacheable import org.springframework.dao.EmptyResultDataAccessException @@ -31,96 +33,76 @@ class JpaLogbookReportRepository( private val dbLogbookReportRepository: DBLogbookReportRepository, private val objectMapper: ObjectMapper, ) : LogbookReportRepository { - private val logger = LoggerFactory.getLogger(JpaLogbookReportRepository::class.java) - - override fun findAllPriorNotifications(filter: PriorNotificationsFilter): List { - val allLogbookReportModels = dbLogbookReportRepository.findAllEnrichedPnoReferencesAndRelatedOperations( - flagStates = filter.flagStates ?: emptyList(), - hasOneOrMoreReportings = filter.hasOneOrMoreReportings, - isLessThanTwelveMetersVessel = filter.isLessThanTwelveMetersVessel, - lastControlledAfter = filter.lastControlledAfter, - lastControlledBefore = filter.lastControlledBefore, - portLocodes = filter.portLocodes ?: emptyList(), - priorNotificationTypesAsSqlArrayString = toSqlArrayString(filter.priorNotificationTypes), - searchQuery = filter.searchQuery, - specyCodesAsSqlArrayString = toSqlArrayString(filter.specyCodes), - tripGearCodesAsSqlArrayString = toSqlArrayString(filter.tripGearCodes), - tripSegmentCodesAsSqlArrayString = toSqlArrayString(filter.tripSegmentCodes), - willArriveAfter = filter.willArriveAfter, - willArriveBefore = filter.willArriveBefore, - ) + override fun findAllAcknowledgedPriorNotifications(filter: PriorNotificationsFilter): List { + // Acknowledged "DAT", "COR" and "DEL" operations + val logbookReportsWithDatCorAndDel = + dbLogbookReportRepository.findAllEnrichedPnoReferencesAndRelatedOperations( + flagStates = filter.flagStates ?: emptyList(), + hasOneOrMoreReportings = filter.hasOneOrMoreReportings, + isLessThanTwelveMetersVessel = filter.isLessThanTwelveMetersVessel, + lastControlledAfter = filter.lastControlledAfter, + lastControlledBefore = filter.lastControlledBefore, + portLocodes = filter.portLocodes ?: emptyList(), + priorNotificationTypesAsSqlArrayString = toSqlArrayString(filter.priorNotificationTypes), + searchQuery = filter.searchQuery, + specyCodesAsSqlArrayString = toSqlArrayString(filter.specyCodes), + tripGearCodesAsSqlArrayString = toSqlArrayString(filter.tripGearCodes), + tripSegmentCodesAsSqlArrayString = toSqlArrayString(filter.tripSegmentCodes), + willArriveAfter = filter.willArriveAfter, + willArriveBefore = filter.willArriveBefore, + ) - return mapToReferenceWithRelatedModels(allLogbookReportModels) - .mapNotNull { (referenceLogbookReportModel, relatedLogbookReportModels) -> - try { - referenceLogbookReportModel.toPriorNotification(objectMapper, relatedLogbookReportModels) - } catch (e: Exception) { - logger.warn( - "Error while converting logbook report models to prior notifications (reportId = ${referenceLogbookReportModel.reportId}).", - e, - ) + val referencedReportIds = logbookReportsWithDatCorAndDel + .filter { it.referencedReportId != null } + .map { it.referencedReportId } + .toSet() - null - } + return logbookReportsWithDatCorAndDel + .filter { report -> + // Exclude reports that are referenced by other reports or have a DEL operation type + report.operationType != LogbookOperationType.DEL && report.reportId !in referencedReportIds + } + .map { report -> + val pno = PriorNotification.fromLogbookMessage(report.toLogbookMessage(objectMapper)) + // All messages returned from the SQL query are acknowledged + pno.markAsAcknowledged() + + return@map pno } } @Cacheable(value = ["pno_to_verify"]) override fun findAllPriorNotificationsToVerify(): List { - val allLogbookReportModels = dbLogbookReportRepository.findAllEnrichedPnoReferencesAndRelatedOperations( - flagStates = emptyList(), - hasOneOrMoreReportings = null, - isLessThanTwelveMetersVessel = null, - lastControlledAfter = null, - lastControlledBefore = null, - portLocodes = emptyList(), - priorNotificationTypesAsSqlArrayString = null, - searchQuery = null, - specyCodesAsSqlArrayString = null, - tripGearCodesAsSqlArrayString = null, - tripSegmentCodesAsSqlArrayString = null, + val filter = PriorNotificationsFilter( willArriveAfter = CustomZonedDateTime(ZonedDateTime.now()).toString(), willArriveBefore = CustomZonedDateTime(ZonedDateTime.now().plusHours(24)).toString(), ) - return mapToReferenceWithRelatedModels(allLogbookReportModels) - .mapNotNull { (referenceLogbookReportModel, relatedLogbookReportModels) -> - try { - referenceLogbookReportModel.toPriorNotification(objectMapper, relatedLogbookReportModels) - } catch (e: Exception) { - logger.warn( - "Error while converting logbook report models to prior notifications (reportId = ${referenceLogbookReportModel.reportId}).", - e, - ) - - null - } - }.filter { - it.logbookMessageAndValue.value.isInVerificationScope == true && - it.logbookMessageAndValue.value.isVerified == false && - it.logbookMessageAndValue.value.isInvalidated != true - } + return findAllAcknowledgedPriorNotifications(filter).filter { + it.logbookMessageAndValue.value.isInVerificationScope == true && + it.logbookMessageAndValue.value.isVerified == false && + it.logbookMessageAndValue.value.isInvalidated != true + } } - override fun findPriorNotificationByReportId(reportId: String, operationDate: ZonedDateTime): PriorNotification? { - val allLogbookReportModels = dbLogbookReportRepository.findEnrichedPnoReferenceAndRelatedOperationsByReportId( - reportId, - operationDate.toString(), - ) - if (allLogbookReportModels.isEmpty()) { - return null - } + /** + * Return null if the logbook report: + * - is not found + * - is deleted by an acknowledged "DEL" operation + * - is corrected by an acknowledged "COR" operation + */ + override fun findAcknowledgedPriorNotificationByReportId( + reportId: String, + operationDate: ZonedDateTime, + ): PriorNotification? { + val logbookReport = dbLogbookReportRepository + .findAcknowledgedNonDeletedPnoDatAndCorsByReportId(reportId, operationDate.toString()).firstOrNull() - try { - val (referenceLogbookReportModel, relatedLogbookReportModels) = - mapToReferenceWithRelatedModels(allLogbookReportModels).first() - - return referenceLogbookReportModel.toPriorNotification(objectMapper, relatedLogbookReportModels) - } catch (e: Exception) { - throw EntityConversionException( - "Error while converting logbook report models to prior notification (reoportId = $reportId).", - e, - ) + return logbookReport?.let { + val pno = PriorNotification.fromLogbookMessage(it.toLogbookMessage(objectMapper)) + pno.markAsAcknowledged() + + return@let pno } } @@ -352,9 +334,11 @@ class JpaLogbookReportRepository( @Modifying @Transactional override fun savePriorNotification(logbookMessageAndValue: LogbookMessageAndValue): PriorNotification { - return dbLogbookReportRepository - .save(LogbookReportEntity.fromLogbookMessage(objectMapper, logbookMessageAndValue.logbookMessage)) - .toPriorNotification(objectMapper, emptyList()) + return PriorNotification.fromLogbookMessage( + dbLogbookReportRepository + .save(LogbookReportEntity.fromLogbookMessage(objectMapper, logbookMessageAndValue.logbookMessage)) + .toLogbookMessage(objectMapper), + ) } @Transactional @@ -367,29 +351,23 @@ class JpaLogbookReportRepository( isSent: Boolean, isVerified: Boolean, ) { - val logbookReportEntities = - dbLogbookReportRepository.findEnrichedPnoReferenceAndRelatedOperationsByReportId( + val logbookReport = dbLogbookReportRepository + .findAcknowledgedNonDeletedPnoDatAndCorsByReportId( reportId, operationDate.withZoneSameInstant(UTC).toString(), - ) - if (logbookReportEntities.isEmpty()) { - throw BackendUsageException(BackendUsageErrorCode.NOT_FOUND) - } + ).firstOrNull() + ?: throw BackendUsageException(BackendUsageErrorCode.NOT_FOUND) - // We need to update both DAT and related COR operations (which also covers orphan COR cases) - logbookReportEntities - .filter { it.operationType in listOf(LogbookOperationType.DAT, LogbookOperationType.COR) } - .map { logbookReportEntity -> - val pnoMessage = objectMapper.readValue(logbookReportEntity.message, PNO::class.java) - pnoMessage.isBeingSent = isBeingSent - pnoMessage.isSent = isSent - pnoMessage.isVerified = isVerified + val pnoValue = objectMapper.readValue(logbookReport.message, PNO::class.java) - val nextMessage = objectMapper.writeValueAsString(pnoMessage) - val updatedEntity = logbookReportEntity.copy(message = nextMessage) + val nextPnoValue = pnoValue.apply { + this.isBeingSent = isBeingSent + this.isSent = isSent + this.isVerified = isVerified + } + val updatedLogbookReport = logbookReport.copy(message = objectMapper.writeValueAsString(nextPnoValue)) - dbLogbookReportRepository.save(updatedEntity) - } + dbLogbookReportRepository.save(updatedLogbookReport) } @Transactional @@ -400,106 +378,59 @@ class JpaLogbookReportRepository( authorTrigram: String?, note: String?, ) { - val logbookReportEntities = - dbLogbookReportRepository.findEnrichedPnoReferenceAndRelatedOperationsByReportId( + val logbookReport = dbLogbookReportRepository + .findAcknowledgedNonDeletedPnoDatAndCorsByReportId( reportId, operationDate.withZoneSameInstant(UTC).toString(), - ) - if (logbookReportEntities.isEmpty()) { - throw BackendUsageException(BackendUsageErrorCode.NOT_FOUND) + ).firstOrNull() + ?: throw BackendUsageException(BackendUsageErrorCode.NOT_FOUND) + + val pnoValue = objectMapper.readValue(logbookReport.message, PNO::class.java) + if ( + Utils.areStringsEqual(authorTrigram, pnoValue.authorTrigram) && + Utils.areStringsEqual(note, pnoValue.note) + ) { + return } - // We need to update both DAT and related COR operations (which also covers orphan COR cases) - logbookReportEntities - .filter { it.operationType in listOf(LogbookOperationType.DAT, LogbookOperationType.COR) } - .map { logbookReportEntity -> - val pnoMessage = objectMapper.readValue(logbookReportEntity.message, PNO::class.java) - if ( - !Utils.areStringsEqual(authorTrigram, pnoMessage.authorTrigram) || - !Utils.areStringsEqual(note, pnoMessage.note) - ) { - pnoMessage.authorTrigram = authorTrigram - pnoMessage.note = note - - /** - * The PNO states are re-initialized: - * - the PDF will be re-generated (done in the use case by deleting the old one) - * - the PNO will require another verification before sending - */ - pnoMessage.isBeingSent = false - pnoMessage.isSent = false - pnoMessage.isVerified = false - - val nextMessage = objectMapper.writeValueAsString(pnoMessage) - - val updatedEntity = logbookReportEntity.copy(message = nextMessage) - - dbLogbookReportRepository.save(updatedEntity) - } - } + val nextPnoValue = pnoValue.apply { + this.authorTrigram = authorTrigram + this.note = note + /** + * The PNO states are re-initialized: + * - the PDF will be re-generated (done in the use case by deleting the old one) + * - the PNO will require another verification before sending + */ + this.isBeingSent = false + this.isSent = false + this.isVerified = false + } + val updatedLogbookReport = logbookReport.copy(message = objectMapper.writeValueAsString(nextPnoValue)) + + dbLogbookReportRepository.save(updatedLogbookReport) } @Transactional @CacheEvict(value = ["pno_to_verify"], allEntries = true) override fun invalidate(reportId: String, operationDate: ZonedDateTime) { - val logbookReportEntities = - dbLogbookReportRepository.findEnrichedPnoReferenceAndRelatedOperationsByReportId( + val logbookReport = dbLogbookReportRepository + .findAcknowledgedNonDeletedPnoDatAndCorsByReportId( reportId, operationDate.withZoneSameInstant(UTC).toString(), - ) - if (logbookReportEntities.isEmpty()) { - throw BackendUsageException(BackendUsageErrorCode.NOT_FOUND) - } + ).firstOrNull() + ?: throw BackendUsageException(BackendUsageErrorCode.NOT_FOUND) - // We need to update both DAT and related COR operations (which also covers orphan COR cases) - logbookReportEntities - .filter { it.operationType in listOf(LogbookOperationType.DAT, LogbookOperationType.COR) } - .map { logbookReportEntity -> - val pnoMessage = objectMapper.readValue(logbookReportEntity.message, PNO::class.java) - pnoMessage.isInvalidated = true + val pnoValue = objectMapper.readValue(logbookReport.message, PNO::class.java) - val nextMessage = objectMapper.writeValueAsString(pnoMessage) + val nextPnoValue = pnoValue.apply { + this.isInvalidated = true + } - val updatedEntity = logbookReportEntity.copy(message = nextMessage) + val updatedLogbookReport = logbookReport.copy(message = objectMapper.writeValueAsString(nextPnoValue)) - dbLogbookReportRepository.save(updatedEntity) - } + dbLogbookReportRepository.save(updatedLogbookReport) } private fun getAllMessagesExceptionMessage(internalReferenceNumber: String) = "No messages found for the vessel. (internalReferenceNumber: \"$internalReferenceNumber\")" - - companion object { - fun mapToReferenceWithRelatedModels( - allLogbookReportModels: List, - ): List>> { - // DAT operations are references by definition - val datLogbookReportModels = allLogbookReportModels.filter { it.operationType == LogbookOperationType.DAT } - // Orphan COR operations are also considered as references for lack of anything better - // They can be orphan for various reasons, like an error along the external JPE flow. - val orphanCorLogbookReportModels = allLogbookReportModels - .filter { it.operationType == LogbookOperationType.COR } - .filter { corOperation -> - corOperation.referencedReportId == null || - datLogbookReportModels.none { it.reportId == corOperation.referencedReportId } - } - val referenceLogbookReportModels = datLogbookReportModels + orphanCorLogbookReportModels - - return referenceLogbookReportModels.map { referenceLogbookReportModel -> - val directlyAssociatedLogbookReportModels = allLogbookReportModels.filter { - it.referencedReportId == referenceLogbookReportModel.reportId - } - // COR operation also have their own `reportId` which can also be associated to their own operations - // For example, a RET (aknlowledgement) operation can be associated to a COR operation. - val directlyAssociatedReportIds = directlyAssociatedLogbookReportModels.mapNotNull { it.reportId } - val indirectlyAssociatedLogbookReportModels = allLogbookReportModels.filter { - it.referencedReportId in directlyAssociatedReportIds - } - val associatedLogbookReportModels = directlyAssociatedLogbookReportModels + - indirectlyAssociatedLogbookReportModels - - Pair(referenceLogbookReportModel, associatedLogbookReportModels) - } - } - } } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBLogbookReportRepository.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBLogbookReportRepository.kt index a61a713910..8e92415885 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBLogbookReportRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBLogbookReportRepository.kt @@ -136,16 +136,9 @@ interface DBLogbookReportRepository : AND lr.operation_type = 'DEL' ), - ret_pno_logbook_reports AS ( - SELECT - lr.*, - CAST(NULL AS TEXT[]) AS prior_notification_type_names, - CAST(NULL AS TEXT[]) AS specy_codes, - CAST(NULL AS TEXT[]) AS trip_gear_codes, - CAST(NULL AS TEXT[]) AS trip_segment_codes, - CAST(NULL AS INTEGER) AS reporting_count + acknowledged_report_ids AS ( + SELECT DISTINCT referenced_report_id FROM logbook_reports lr - JOIN filtered_dat_and_cor_pno_logbook_reports fdacplr ON lr.referenced_report_id = fdacplr.report_id WHERE -- This filter helps Timescale optimize the query since `operation_datetime_utc` is indexed lr.operation_datetime_utc @@ -153,20 +146,22 @@ interface DBLogbookReportRepository : AND CAST(:willArriveBefore AS TIMESTAMP) + INTERVAL '48 hours' AND lr.operation_type = 'RET' + AND lr.value->>'returnStatus' = '000' ) SELECT * FROM filtered_dat_and_cor_pno_logbook_reports + WHERE + report_id IN (SELECT referenced_report_id FROM acknowledged_report_ids) + OR flag_state NOT IN ('FRA', 'GUF', 'VEN') -- flag_states for which we received RET messages - UNION + UNION ALL SELECT * FROM del_pno_logbook_reports - - UNION - - SELECT * - FROM ret_pno_logbook_reports; + WHERE + operation_number IN (SELECT referenced_report_id FROM acknowledged_report_ids) + OR flag_state NOT IN ('FRA', 'GUF', 'VEN') -- flag_states for which we received RET messages """, nativeQuery = true, ) @@ -186,90 +181,93 @@ interface DBLogbookReportRepository : willArriveBefore: String, ): List + /** + * This query either returns: + * - 1 element if the report id is found, not corrected and not deleted + * - 0 element + */ @Query( """ WITH - dats_cors AS ( - -- Get the logbook report reference (DAT operation) - -- It may not exist while a COR operation would still exist (orphan COR case) + searched_pno AS ( SELECT * FROM logbook_reports WHERE - -- This filter helps Timescale optimize the query since `operation_datetime_utc` is indexed operation_datetime_utc - BETWEEN CAST(:operationDate AS TIMESTAMP) - INTERVAL '48 hours' - AND CAST(:operationDate AS TIMESTAMP) + INTERVAL '48 hours' - + BETWEEN CAST(:operationDate AS TIMESTAMP) - INTERVAL '4 hours' + AND CAST(:operationDate AS TIMESTAMP) + INTERVAL '4 hours' AND report_id = :reportId AND log_type = 'PNO' - AND operation_type = 'DAT' AND enriched = TRUE + ), - UNION ALL - - -- Get the logbook report corrections which may be used as base for the "final" report - SELECT * - FROM logbook_reports - WHERE - -- This filter helps Timescale optimize the query since `operation_datetime_utc` is indexed - operation_datetime_utc - BETWEEN CAST(:operationDate AS TIMESTAMP) - INTERVAL '48 hours' - AND CAST(:operationDate AS TIMESTAMP) + INTERVAL '48 hours' + dels_targeting_searched_pno AS ( - AND referenced_report_id = :reportId - AND log_type = 'PNO' - AND operation_type = 'COR' - AND enriched = TRUE + -- A DEL message has no flag_state, which we need to acknowledge messages of non french vessels. + -- So we use the flag_state of the deleted message. + SELECT del.referenced_report_id, del.operation_number, searched_pno.flag_state + FROM logbook_reports del + JOIN searched_pno + ON del.referenced_report_id = searched_pno.report_id + WHERE + del.operation_datetime_utc + BETWEEN CAST(:operationDate AS TIMESTAMP) - INTERVAL '48 hours' + AND CAST(:operationDate AS TIMESTAMP) + INTERVAL '48 hours' + AND del.operation_type = 'DEL' ), - dels AS ( + cors_targeting_searched_pno AS ( SELECT * FROM logbook_reports WHERE - -- This filter helps Timescale optimize the query since `operation_datetime_utc` is indexed operation_datetime_utc BETWEEN CAST(:operationDate AS TIMESTAMP) - INTERVAL '48 hours' AND CAST(:operationDate AS TIMESTAMP) + INTERVAL '48 hours' - - AND operation_type = 'DEL' - AND referenced_report_id IN (SELECT report_id FROM dats_cors) + AND operation_type = 'COR' + AND referenced_report_id = :reportId ), - rets AS ( - SELECT * + acknowledged_cors_and_dels AS ( + SELECT DISTINCT referenced_report_id FROM logbook_reports WHERE - -- This filter helps Timescale optimize the query since `operation_datetime_utc` is indexed operation_datetime_utc BETWEEN CAST(:operationDate AS TIMESTAMP) - INTERVAL '48 hours' AND CAST(:operationDate AS TIMESTAMP) + INTERVAL '48 hours' - AND operation_type = 'RET' + AND value->>'returnStatus' = '000' AND referenced_report_id IN ( - SELECT report_id FROM dats_cors + SELECT operation_number FROM dels_targeting_searched_pno UNION ALL - SELECT report_id FROM dels + SELECT report_id FROM cors_targeting_searched_pno ) - ) - - SELECT * - FROM dats_cors - - UNION ALL + ), - SELECT * - FROM dels + acknowledged_dels_targeting_searched_pno AS ( + SELECT referenced_report_id + FROM dels_targeting_searched_pno + WHERE + operation_number IN (SELECT referenced_report_id FROM acknowledged_cors_and_dels) + OR flag_state NOT IN ('FRA', 'GUF', 'VEN') -- flag_states for which we received RET messages + ), - UNION ALL + acknowledged_cors_targeting_searched_pno AS ( + SELECT referenced_report_id + FROM cors_targeting_searched_pno + WHERE + report_id IN (SELECT referenced_report_id FROM acknowledged_cors_and_dels) + OR flag_state NOT IN ('FRA', 'GUF', 'VEN') -- flag_states for which we received RET messages + ) SELECT * - FROM rets - - ORDER BY report_datetime_utc; + FROM searched_pno + WHERE + report_id NOT IN (SELECT referenced_report_id FROM acknowledged_dels_targeting_searched_pno) AND + report_id NOT IN (SELECT referenced_report_id FROM acknowledged_cors_targeting_searched_pno) """, nativeQuery = true, ) - fun findEnrichedPnoReferenceAndRelatedOperationsByReportId( + fun findAcknowledgedNonDeletedPnoDatAndCorsByReportId( reportId: String, operationDate: String, ): List diff --git a/backend/src/main/resources/db/testdata/V666.2.1__Insert_more_dummy_vessels.sql b/backend/src/main/resources/db/testdata/V666.2.1__Insert_more_dummy_vessels.sql index 8baa4fa623..959ae227e7 100644 --- a/backend/src/main/resources/db/testdata/V666.2.1__Insert_more_dummy_vessels.sql +++ b/backend/src/main/resources/db/testdata/V666.2.1__Insert_more_dummy_vessels.sql @@ -19,8 +19,6 @@ INSERT INTO vessels (id, cfr, mmsi, ircs, external_immatriculation, vessel_name, INSERT INTO vessels (id, cfr, mmsi, ircs, external_immatriculation, vessel_name, flag_state, length, under_charter) VALUES (109, 'CFR109', 'MMSI109', 'IRCS109', 'EXTIMM109', 'LE POISSON D''AVRIL', 'FR', 25, false); -INSERT INTO vessels (id, cfr, mmsi, ircs, external_immatriculation, vessel_name, flag_state, length, under_charter) VALUES (1109, 'CFR109', 'MMSI109_DUPLICATE', 'IRCS109_DUPLICATE', 'EXTIMM109_DUPLICATE', 'LE POISSON D''AVRIL DUPLIQUÉ', 'FR', 50, true); - INSERT INTO vessels (id, cfr, mmsi, ircs, external_immatriculation, vessel_name, flag_state, length, under_charter) VALUES (110, 'CFR110', 'MMSI110', 'IRCS110', 'EXTIMM110', 'LA MER À BOIRE', 'FR', 12.5, false); INSERT INTO vessels (id, cfr, mmsi, ircs, external_immatriculation, vessel_name, flag_state, length, under_charter) VALUES (111, 'CFR111', 'MMSI111', 'IRCS111', 'EXTIMM111', 'LE MARIN D''EAU DOUCE', 'FR', 9.5, false); diff --git a/backend/src/main/resources/db/testdata/V666.5.1__Insert_more_pno_logbook_reports.sql b/backend/src/main/resources/db/testdata/V666.5.1__Insert_more_pno_logbook_reports.sql index 931a3ca5cd..4ae7710b6c 100644 --- a/backend/src/main/resources/db/testdata/V666.5.1__Insert_more_pno_logbook_reports.sql +++ b/backend/src/main/resources/db/testdata/V666.5.1__Insert_more_pno_logbook_reports.sql @@ -3,16 +3,28 @@ INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_101', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_101_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_102', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_102_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_103', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_103_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_104', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_104_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_105', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_105_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_106', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_106_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_107', 'Message FLUX xml'); INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_107_RET', 'Message FLUX xml'); @@ -23,95 +35,143 @@ INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_O INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_109', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_109_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_109_COR', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_109_COR_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_110', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_110_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_110_DEL', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_110_DEL_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_111_COR_ORPHAN', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_111_COR_ORPHAN_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_112', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_112_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_113', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_113_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_114', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_114_RET', 'Message FLUX xml'); + INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_115', 'Message FLUX xml'); +INSERT INTO logbook_raw_messages (operation_number, xml_message) VALUES ('FAKE_OPERATION_115_RET', 'Message FLUX xml'); + INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (101, 'FAKE_OPERATION_101', NULL, 'FAK000999999', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_101', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', 'PHENOMENE', '[{"gear":"TBN","mesh":100,"dimensions":"250;180"},{"gear":"OTT","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"SWW04","segmentName":"Chaluts pélagiques"},{"segment":"SWW06","segmentName":"Sennes"}]', '{"riskFactor":2.1,"catchOnboard":[{"weight":25,"nbFish":null,"species":"COD","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":false,"isSent":true,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type A","minimumNotificationPeriod":4,"hasDesignatedPorts":false},{"pnoTypeName":"Préavis type B","minimumNotificationPeriod":8,"hasDesignatedPorts":true}],"port":"FRSML","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 101; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 101; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 101; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (102, 'FAKE_OPERATION_102', NULL, 'ABC000042310', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_102', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', 'COURANT MAIN PROFESSEUR', '[{"gear":"PT","mesh":100,"dimensions":"250;180"},{"gear":"OT","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"SWW10","segmentName":"Palangres ciblant les espèces démersales"},{"segment":"SWW11","segmentName":"Hameçons"}]', '{"riskFactor":2.8,"catchOnboard":[{"weight":25,"nbFish":null,"species":"SOL","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":25,"nbFish":null,"species":"HKE","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":false,"isSent":true,"isVerified":true,"pnoTypes":[{"pnoTypeName":"Préavis type C","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRBES","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, software, transmission_format, value) VALUES (1101, NULL, 'FAKE_OPERATION_101', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_101_RET', 'RET', 'JT/VISIOCaptures V1.4.7', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (102, 'FAKE_OPERATION_102', NULL, 'ABC000042310', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_102', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', 'COURANT MAIN PROFESSEUR', '[{"gear":"PT","mesh":100,"dimensions":"250;180"},{"gear":"OT","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"SWW10","segmentName":"Palangres ciblant les espèces démersales"},{"segment":"SWW11","segmentName":"Hameçons"}]', '{"riskFactor":2.8,"catchOnboard":[{"weight":25,"nbFish":null,"species":"SOL","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":25,"nbFish":null,"species":"HKE","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":false,"isSent":true,"isVerified":true,"pnoTypes":[{"pnoTypeName":"Préavis type C","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRBES","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '4 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 102; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 102; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 102; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (103, 'FAKE_OPERATION_103', NULL, NULL, true, NULL, '2023-12-31 17:00:00', 'PNO', '2023-12-31 17:00:00', 'FAKE_OPERATION_103', 'DAT', '2023-12-31 17:00:00', 'JT/VISIOCaptures V1.4.7', 'ERS', NULL, '[]', '[]', '{"riskFactor":1.8,"catchOnboard":[],"pnoTypes":[],"port":"AEHZP","predictedArrivalDatetimeUtc":"2023-12-31T23:59:00Z","purpose":"GRD","tripStartDate":"2023-12-31T06:00:00Z"}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1102, NULL, 'FAKE_OPERATION_102', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_102_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (103, 'FAKE_OPERATION_103', NULL, NULL, true, NULL, '2023-12-31 17:00:00', 'PNO', '2023-12-31 17:00:00', 'FAKE_OPERATION_103', 'DAT', '2023-12-31 17:00:00', 'ERS', NULL, '[]', '[]', '{"riskFactor":1.8,"catchOnboard":[],"pnoTypes":[],"port":"AEHZP","predictedArrivalDatetimeUtc":"2023-12-31T23:59:00Z","purpose":"GRD","tripStartDate":"2023-12-31T06:00:00Z"}'); -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (104, 'FAKE_OPERATION_104', NULL, 'CFR101', true, 'ESP', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_104', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', 'VIVA ESPANA', '[{"gear":"TB","mesh":100,"dimensions":"250;180"},{"gear":"TBS","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde"},{"segment":"NWW05","segmentName":"Chalut à perche"}]', '{"riskFactor":2.2,"catchOnboard":[{"weight":25,"nbFish":null,"species":"FRF","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":150,"nbFish":null,"species":"AFH","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":250,"nbFish":null,"species":"AFI","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":75,"nbFish":null,"species":"AFT","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":10,"nbFish":null,"species":"AFU","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":430,"nbFish":null,"species":"APX","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":90,"nbFish":null,"species":"AQD","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":true,"isSent":true,"isVerified":true,"pnoTypes":[{"pnoTypeName":"Préavis type A","minimumNotificationPeriod":4,"hasDesignatedPorts":false},{"pnoTypeName":"Préavis type B","minimumNotificationPeriod":8,"hasDesignatedPorts":true}],"port":"FRVNE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1103, NULL, 'FAKE_OPERATION_103', '2023-12-31 17:00:00', '2023-12-31 17:00:00', 'FAKE_OPERATION_103_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (104, 'FAKE_OPERATION_104', NULL, 'CFR101', true, 'ESP', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_104', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', 'VIVA ESPANA', '[{"gear":"TB","mesh":100,"dimensions":"250;180"},{"gear":"TBS","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde"},{"segment":"NWW05","segmentName":"Chalut à perche"}]', '{"riskFactor":2.2,"catchOnboard":[{"weight":25,"nbFish":null,"species":"FRF","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":150,"nbFish":null,"species":"AFH","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":250,"nbFish":null,"species":"AFI","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":75,"nbFish":null,"species":"AFT","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":10,"nbFish":null,"species":"AFU","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":430,"nbFish":null,"species":"APX","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"},{"weight":90,"nbFish":null,"species":"AQD","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":true,"isSent":true,"isVerified":true,"pnoTypes":[{"pnoTypeName":"Préavis type A","minimumNotificationPeriod":4,"hasDesignatedPorts":false},{"pnoTypeName":"Préavis type B","minimumNotificationPeriod":8,"hasDesignatedPorts":true}],"port":"FRVNE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 104; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '4 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 104; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 104; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (105, 'FAKE_OPERATION_105', NULL, 'CFR102', true, 'NLD', '2024-03-01 15:00:00', 'PNO', '2024-03-01 15:00:00', 'FAKE_OPERATION_105', 'DAT', '2024-03-01 15:00:00', 'JT/VISIOCaptures V1.4.7', 'ERS', 'LEVE NEDERLAND', '[{"gear":"DHB","mesh":20.25,"dimensions":"500;500"},{"gear":"DRM","mesh":25.75,"dimensions":"1000;1000"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde ≥100 mm"}]', '{"riskFactor":1.9,"catchOnboard":[{"weight":25,"nbFish":null,"species":"FRF","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type A","minimumNotificationPeriod":4,"hasDesignatedPorts":false},{"pnoTypeName":"Préavis type B","minimumNotificationPeriod":8,"hasDesignatedPorts":true}],"port":"FRVNE","predictedArrivalDatetimeUtc":"2024-03-01T17:00:00Z","predictedLandingDatetimeUtc":"2024-03-01T17:30:00Z","purpose":"LAN","tripStartDate":"2024-03-01T05:00:00Z"}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1104, NULL, 'FAKE_OPERATION_104', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_104_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (105, 'FAKE_OPERATION_105', NULL, 'CFR102', true, 'NLD', '2024-03-01 15:00:00', 'PNO', '2024-03-01 15:00:00', 'FAKE_OPERATION_105', 'DAT', '2024-03-01 15:00:00', 'ERS', 'LEVE NEDERLAND', '[{"gear":"DHB","mesh":20.25,"dimensions":"500;500"},{"gear":"DRM","mesh":25.75,"dimensions":"1000;1000"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde ≥100 mm"}]', '{"riskFactor":1.9,"catchOnboard":[{"weight":25,"nbFish":null,"species":"FRF","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type A","minimumNotificationPeriod":4,"hasDesignatedPorts":false},{"pnoTypeName":"Préavis type B","minimumNotificationPeriod":8,"hasDesignatedPorts":true}],"port":"FRVNE","predictedArrivalDatetimeUtc":"2024-03-01T17:00:00Z","predictedLandingDatetimeUtc":"2024-03-01T17:30:00Z","purpose":"LAN","tripStartDate":"2024-03-01T05:00:00Z"}'); -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (106, 'FAKE_OPERATION_106', NULL, 'CFR103', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_106', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', 'L''OM DU POISSON', '[{"gear":"DHB","mesh":20.25,"dimensions":"500;500"},{"gear":"DRM","mesh":25.75,"dimensions":"1000;1000"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde ≥100 mm"}]', '{"riskFactor":2.5,"catchOnboard":[{"weight":25,"nbFish":null,"species":"FRF","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":true,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type E","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRMRS","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1105, NULL, 'FAKE_OPERATION_105', '2024-03-01 15:00:00', '2024-03-01 15:00:00', 'FAKE_OPERATION_105_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (106, 'FAKE_OPERATION_106', NULL, 'CFR103', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_106', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', 'L''OM DU POISSON', '[{"gear":"DHB","mesh":20.25,"dimensions":"500;500"},{"gear":"DRM","mesh":25.75,"dimensions":"1000;1000"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde ≥100 mm"}]', '{"riskFactor":2.5,"catchOnboard":[{"weight":25,"nbFish":null,"species":"FRF","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":false,"isInVerificationScope":true,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type E","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRMRS","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 106; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '4 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 106; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 106; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (107, 'FAKE_OPERATION_107', NULL, 'CFR104', true, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_107', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', '[{"gear":"DHB","mesh":20.25,"dimensions":"500;500"},{"gear":"DRM","mesh":25.75,"dimensions":"1000;1000"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde ≥100 mm"}]', 'DES BARS', '{"riskFactor":3.4,"catchOnboard":[{"weight":25,"nbFish":null,"species":"COD","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":true,"isInVerificationScope":true,"isSent":false,"isVerified":true,"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRSML","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1106, NULL, 'FAKE_OPERATION_106', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_106_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (107, 'FAKE_OPERATION_107', NULL, 'CFR104', true, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_107', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', '[{"gear":"DHB","mesh":20.25,"dimensions":"500;500"},{"gear":"DRM","mesh":25.75,"dimensions":"1000;1000"}]', '[{"segment":"NWW03","segmentName":"Chalut de fond en eau profonde ≥100 mm"}]', 'DES BARS', '{"riskFactor":3.4,"catchOnboard":[{"weight":25,"nbFish":null,"species":"COD","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"isBeingSent":true,"isInVerificationScope":true,"isSent":false,"isVerified":true,"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRSML","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 107; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 107; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 107; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (1107, NULL, 'FAKE_OPERATION_107', 'CFR104', false, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_107_RET', 'RET', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', NULL, NULL, NULL, '{"returnStatus":"000"}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1107, NULL, 'FAKE_OPERATION_107', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_107_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (108, 'FAKE_OPERATION_108', NULL, 'CFR105', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_108', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'TurboCatch (3.7-1)', 'ERS', NULL, NULL, 'CALAMARO', '{"riskFactor":2.9,"catchOnboard":[{"weight":150,"nbFish":null,"species":"ANF","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRSML","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 108; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 108; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 108; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (1108, NULL, 'FAKE_OPERATION_108', 'CFR105', false, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_108_RET', 'RET', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'TurboCatch (3.7-1)', 'ERS', NULL, NULL, NULL, '{"rejectionCause":"002 MGEN02 Message incorrect : la date/heure de l''événement RTP n° OOF20201105037001 est postérieure à la date/heure courante. Veuillez vérifier la date/heure de l''événement déclaré et renvoyer votre message.","returnStatus":"002"}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1108, NULL, 'FAKE_OPERATION_108', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_108_RET', 'RET', 'ERS', '{"rejectionCause":"002 MGEN02 Message incorrect : la date/heure de l''événement RTP n° OOF20201105037001 est postérieure à la date/heure courante. Veuillez vérifier la date/heure de l''événement déclaré et renvoyer votre message.","returnStatus":"002"}'); -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (109, 'FAKE_OPERATION_109', NULL, 'CFR106', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_109', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', NULL, NULL, 'L''ANCRE SÈCHE', '{"riskFactor":2.2,"catchOnboard":[],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[],"port":"FRSML","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (109, 'FAKE_OPERATION_109', NULL, 'CFR106', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_109', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', NULL, NULL, 'L''ANCRE SÈCHE', '{"riskFactor":2.2,"catchOnboard":[],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[],"port":"FRSML","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 109; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 109; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 109; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (1109, 'FAKE_OPERATION_109_COR', 'FAKE_OPERATION_109', 'CFR106', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_109_COR', 'COR', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', 'L''ANCRE SÈCHE', NULL, NULL, '{"riskFactor":1.7,"catchOnboard":[{"economicZone":"FRA","effortZone":"C","faoZone":"27.8.a","nbFish":null,"species":"BHX","statisticalRectangle":"23E6","weight":32.5}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRVNE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); -UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 1109; -UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 1109; -UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 1109; +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1109, NULL, 'FAKE_OPERATION_109', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_109_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (2109, 'FAKE_OPERATION_109_COR', 'FAKE_OPERATION_109', 'CFR106', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_109_COR', 'COR', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'ERS', 'L''ANCRE SÈCHE', NULL, NULL, '{"riskFactor":1.7,"catchOnboard":[{"economicZone":"FRA","effortZone":"C","faoZone":"27.8.a","nbFish":null,"species":"BHX","statisticalRectangle":"23E6","weight":32.5}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRVNE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 2109; +UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 2109; +UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 2109; + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (3109, NULL, 'FAKE_OPERATION_109_COR', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_109_COR_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (110, 'FAKE_OPERATION_110', NULL, 'CFR107', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_110', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', NULL, NULL, 'MERLU L''ENCHANTEUR', '{"riskFactor":2.1,"catchOnboard":[{"economicZone":"FRA","effortZone":"C","faoZone":"27.8.a","nbFish":null,"species":"COD","statisticalRectangle":"23E6","weight":25}],"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRBES","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (110, 'FAKE_OPERATION_110', NULL, 'CFR107', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_110', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', NULL, NULL, 'MERLU L''ENCHANTEUR', '{"riskFactor":2.1,"catchOnboard":[{"economicZone":"FRA","effortZone":"C","faoZone":"27.8.a","nbFish":null,"species":"COD","statisticalRectangle":"23E6","weight":25}],"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRBES","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 110; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 110; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 110; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (1110, NULL, 'FAKE_OPERATION_110', 'FR263418260', false, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_110_DEL', 'DEL', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', NULL, NULL, NULL, NULL); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1110, NULL, 'FAKE_OPERATION_110', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_110_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (1111, 'FAKE_OPERATION_111_COR_ORPHAN', 'FAKE_OPERATION_111', 'CFR108', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_111_COR_ORPHAN', 'COR', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', 'LE POISSON AMBULANT', NULL, NULL, '{"riskFactor":3.1,"catchOnboard":[{"economicZone":"FRA","effortZone":"C","faoZone":"27.8.a","nbFish":null,"species":"COD","statisticalRectangle":"23E6","weight":25}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRNCE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); -UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 1111; -UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 1111; -UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 1111; +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (2110, 'FAKE_OPERATION_110_DEL', 'FAKE_OPERATION_110', 'CFR107', false, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_110_DEL', 'DEL', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'ERS', NULL, NULL, NULL, NULL); -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (112, 'FAKE_OPERATION_112', NULL, NULL, false, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_112', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'ERS', NULL, NULL, NULL, NULL); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (3110, NULL, 'FAKE_OPERATION_110_DEL', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_110_DEL_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (113, 'FAKE_OPERATION_113', NULL, 'CFR109', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_113', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'JT/VISIOCaptures V1.4.7', 'FLUX', '[{"gear":"DRB","mesh":null,"dimensions":null}]', '[{"segment":"FR_SCE","segmentName":"Scallop fisheries"}]', 'LE POISSON AMBULANT', '{"riskFactor":3.9,"catchOnboard":[{"nbFish":null,"weight":40,"faoZone":"27.7.d","species":"ANF","effortZone":null,"economicZone":"FRA","statisticalRectangle":null},{"nbFish":null,"weight":3,"faoZone":"27.7.d","species":"SOL","effortZone":null,"economicZone":"FRA","statisticalRectangle":null},{"nbFish":null,"weight":16,"faoZone":"27.7.d","species":"TUR","effortZone":null,"economicZone":"FRA","statisticalRectangle":null},{"nbFish":null,"weight":27150,"faoZone":"27.7.d","species":"SCE","effortZone":null,"economicZone":"FRA","statisticalRectangle":null}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Autres espèces soumises à préavis","hasDesignatedPorts":true,"minimumNotificationPeriod":4},{"pnoTypeName":"Préavis navire tiers","hasDesignatedPorts":true,"minimumNotificationPeriod":4}],"port":"FRVNE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (2111, 'FAKE_OPERATION_111_COR_ORPHAN', 'FAKE_OPERATION_111', 'CFR108', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_111_COR_ORPHAN', 'COR', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'ERS', 'LE POISSON AMBULANT', NULL, NULL, '{"riskFactor":3.1,"catchOnboard":[{"economicZone":"FRA","effortZone":"C","faoZone":"27.8.a","nbFish":null,"species":"COD","statisticalRectangle":"23E6","weight":25}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Préavis type Z","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"FRNCE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 2111; +UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 2111; +UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 2111; + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (3111, NULL, 'FAKE_OPERATION_111_COR_ORPHAN', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_111_COR_ORPHAN_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (112, 'FAKE_OPERATION_112', NULL, NULL, false, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_112', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', NULL, NULL, NULL, NULL); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1112, NULL, 'FAKE_OPERATION_112', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_112_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, trip_gears, trip_segments, vessel_name, value) VALUES (113, 'FAKE_OPERATION_113', NULL, 'CFR109', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_113', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FLUX', '[{"gear":"DRB","mesh":null,"dimensions":null}]', '[{"segment":"FR_SCE","segmentName":"Scallop fisheries"}]', 'LE POISSON AMBULANT', '{"riskFactor":3.9,"catchOnboard":[{"nbFish":null,"weight":40,"faoZone":"27.7.d","species":"ANF","effortZone":null,"economicZone":"FRA","statisticalRectangle":null},{"nbFish":null,"weight":3,"faoZone":"27.7.d","species":"SOL","effortZone":null,"economicZone":"FRA","statisticalRectangle":null},{"nbFish":null,"weight":16,"faoZone":"27.7.d","species":"TUR","effortZone":null,"economicZone":"FRA","statisticalRectangle":null},{"nbFish":null,"weight":27150,"faoZone":"27.7.d","species":"SCE","effortZone":null,"economicZone":"FRA","statisticalRectangle":null}],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[{"pnoTypeName":"Autres espèces soumises à préavis","hasDesignatedPorts":true,"minimumNotificationPeriod":4},{"pnoTypeName":"Préavis navire tiers","hasDesignatedPorts":true,"minimumNotificationPeriod":4}],"port":"FRVNE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 113; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3.5 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 113; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 113; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (114, 'FAKE_OPERATION_114', NULL, 'CFR110', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'FAKE_OPERATION_114', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'JT/VISIOCaptures V1.4.7', 'ERS', 'LA MER À BOIRE', '[]', '[]', '{"catchOnboard":[],"pnoTypes":[],"port":null,"predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1113, NULL, 'FAKE_OPERATION_113', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_113_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (114, 'FAKE_OPERATION_114', NULL, 'CFR110', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'FAKE_OPERATION_114', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'ERS', 'LA MER À BOIRE', '[]', '[]', '{"catchOnboard":[],"pnoTypes":[],"port":null,"predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '1 hour', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 114; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '2 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 114; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '20 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 114; -INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, software, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (115, 'FAKE_OPERATION_115', NULL, 'CFR111', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'FAKE_OPERATION_115', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'JT/VISIOCaptures V1.4.7', 'ERS', 'LE MARIN D''EAU DOUCE', '[]', '[]', '{"riskFactor":2.9,"catchOnboard":[],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[],"port":"REZSE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1114, NULL, 'FAKE_OPERATION_114', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_114_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_name, trip_gears, trip_segments, value) VALUES (115, 'FAKE_OPERATION_115', NULL, 'CFR111', true, 'FRA', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'FAKE_OPERATION_115', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours', 'ERS', 'LE MARIN D''EAU DOUCE', '[]', '[]', '{"riskFactor":2.9,"catchOnboard":[],"isBeingSent":false,"isInVerificationScope":false,"isSent":false,"isVerified":false,"pnoTypes":[],"port":"REZSE","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedArrivalDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '1 hour', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 115; UPDATE logbook_reports SET value = JSONB_SET(value, '{predictedLandingDatetimeUtc}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '2 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 115; UPDATE logbook_reports SET value = JSONB_SET(value, '{tripStartDate}', TO_JSONB(TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '20 hours', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')), true) WHERE id = 115; + +INSERT INTO logbook_reports (id, report_id, referenced_report_id, integration_datetime_utc, operation_datetime_utc, operation_number, operation_type, transmission_format, value) VALUES (1115, NULL, 'FAKE_OPERATION_115', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes', 'FAKE_OPERATION_115_RET', 'RET', 'ERS', '{"returnStatus":"000"}'); diff --git a/backend/src/main/resources/db/testdata/json/V666.2.1__Insert_more_dummy_vessels.jsonc b/backend/src/main/resources/db/testdata/json/V666.2.1__Insert_more_dummy_vessels.jsonc index 3085b42dd4..7c989ab746 100644 --- a/backend/src/main/resources/db/testdata/json/V666.2.1__Insert_more_dummy_vessels.jsonc +++ b/backend/src/main/resources/db/testdata/json/V666.2.1__Insert_more_dummy_vessels.jsonc @@ -125,17 +125,18 @@ "length": 25, "under_charter": false }, - { - "id": 1109, - "cfr": "CFR109", - "mmsi": "MMSI109_DUPLICATE", - "ircs": "IRCS109_DUPLICATE", - "external_immatriculation": "EXTIMM109_DUPLICATE", - "vessel_name": "LE POISSON D'AVRIL DUPLIQUÉ", - "flag_state": "FR", - "length": 50, - "under_charter": true - }, + // TODO Check that with Vincent, this breaks the prior notifications SQL query. + // { + // "id": 1109, + // "cfr": "CFR109", + // "mmsi": "MMSI109_DUPLICATE", + // "ircs": "IRCS109_DUPLICATE", + // "external_immatriculation": "EXTIMM109_DUPLICATE", + // "vessel_name": "LE POISSON D'AVRIL DUPLIQUÉ", + // "flag_state": "FR", + // "length": 50, + // "under_charter": true + // }, // - Vessel: LA MER À BOIRE { diff --git a/backend/src/main/resources/db/testdata/json/V666.5.1__Insert_more_pno_logbook_reports.jsonc b/backend/src/main/resources/db/testdata/json/V666.5.1__Insert_more_pno_logbook_reports.jsonc index 17ac1a95ab..004350c2e0 100644 --- a/backend/src/main/resources/db/testdata/json/V666.5.1__Insert_more_pno_logbook_reports.jsonc +++ b/backend/src/main/resources/db/testdata/json/V666.5.1__Insert_more_pno_logbook_reports.jsonc @@ -3,24 +3,39 @@ "table": "logbook_raw_messages", "data": [ { "operation_number": "FAKE_OPERATION_101", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_101_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_102", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_102_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_103", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_103_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_104", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_104_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_105", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_105_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_106", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_106_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_107", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_107_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_108", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_108_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_109", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_109_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_109_COR", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_109_COR_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_110", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_110_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_110_DEL", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_110_DEL_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_111_COR_ORPHAN", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_111_COR_ORPHAN_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_112", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_112_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_113", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_113_RET", "xml_message": "Message FLUX xml" }, { "operation_number": "FAKE_OPERATION_114", "xml_message": "Message FLUX xml" }, - { "operation_number": "FAKE_OPERATION_115", "xml_message": "Message FLUX xml" } + { "operation_number": "FAKE_OPERATION_114_RET", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_115", "xml_message": "Message FLUX xml" }, + { "operation_number": "FAKE_OPERATION_115_RET", "xml_message": "Message FLUX xml" } ] }, { @@ -89,6 +104,20 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 1101, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_101", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_101_RET", + "operation_type": "RET", + "software": "JT/VISIOCaptures V1.4.7", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: COURANT MAIN PROFESSEUR // - With 1 reporting @@ -106,7 +135,6 @@ "operation_number": "FAKE_OPERATION_102", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "COURANT MAIN PROFESSEUR", "trip_gears:jsonb": [ @@ -157,6 +185,19 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 1102, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_102", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_102_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: UNKNOWN // - Purpose: GRD @@ -173,7 +214,6 @@ "operation_number": "FAKE_OPERATION_103", "operation_type": "DAT", "report_datetime_utc": "2023-12-31 17:00:00", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": null, "trip_gears:jsonb": [], @@ -188,6 +228,19 @@ "tripStartDate": "2023-12-31T06:00:00Z" } }, + { + "id": 1103, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_103", + "integration_datetime_utc": "2023-12-31 17:00:00", + "operation_datetime_utc": "2023-12-31 17:00:00", + "operation_number": "FAKE_OPERATION_103_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: VIVA ESPANA // - With 2 reportings @@ -208,7 +261,6 @@ "operation_number": "FAKE_OPERATION_104", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "VIVA ESPANA", "trip_gears:jsonb": [ @@ -309,6 +361,19 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 1104, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_104", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_104_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: LEVE NEDERLAND // - Flag state: NL @@ -325,7 +390,6 @@ "operation_number": "FAKE_OPERATION_105", "operation_type": "DAT", "report_datetime_utc": "2024-03-01 15:00:00", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "LEVE NEDERLAND", "trip_gears:jsonb": [ @@ -371,6 +435,19 @@ "tripStartDate": "2024-03-01T05:00:00Z" } }, + { + "id": 1105, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_105", + "integration_datetime_utc": "2024-03-01 15:00:00", + "operation_datetime_utc": "2024-03-01 15:00:00", + "operation_number": "FAKE_OPERATION_105_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: L'OM DU POISSON // - State: Pending verification (required) @@ -387,7 +464,6 @@ "operation_number": "FAKE_OPERATION_106", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "L'OM DU POISSON", "trip_gears:jsonb": [ @@ -428,10 +504,21 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 1106, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_106", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_106_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: DES BARS - // - With RET - // - Aknowledged // - Flag state: UNKNOWN // - State: Unverified and pending sending { @@ -447,7 +534,6 @@ "operation_number": "FAKE_OPERATION_107", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "trip_gears:jsonb": [ { "gear": "DHB", "mesh": 20.25, "dimensions": "500;500" }, @@ -492,27 +578,17 @@ "id": 1107, "report_id": null, "referenced_report_id": "FAKE_OPERATION_107", - "cfr": "CFR104", - "enriched": false, - "flag_state": null, "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", - "log_type": null, "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", "operation_number": "FAKE_OPERATION_107_RET", "operation_type": "RET", - "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", - "trip_gears": null, - "trip_segments": null, - "vessel_name": null, "value:jsonb": { "returnStatus": "000" } }, // - Vessel: CALAMARO - // - With RET // - NOT Aknowledged { "id": 108, @@ -563,20 +639,11 @@ "id": 1108, "report_id": null, "referenced_report_id": "FAKE_OPERATION_108", - "cfr": "CFR105", - "enriched": false, - "flag_state": null, "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", - "log_type": null, "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", "operation_number": "FAKE_OPERATION_108_RET", "operation_type": "RET", - "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", - "software": "TurboCatch (3.7-1)", "transmission_format": "ERS", - "vessel_name": null, - "trip_gears": null, - "trip_segments": null, "value:jsonb": { "rejectionCause": "002 MGEN02 Message incorrect : la date/heure de l'événement RTP n° OOF20201105037001 est postérieure à la date/heure courante. Veuillez vérifier la date/heure de l'événement déclaré et renvoyer votre message.", "returnStatus": "002" @@ -598,7 +665,6 @@ "operation_number": "FAKE_OPERATION_109", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "trip_gears": null, "trip_segments": null, @@ -620,6 +686,19 @@ }, { "id": 1109, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_109", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_109_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, + { + "id": 2109, "report_id": "FAKE_OPERATION_109_COR", "referenced_report_id": "FAKE_OPERATION_109", "cfr": "CFR106", @@ -631,7 +710,6 @@ "operation_number": "FAKE_OPERATION_109_COR", "operation_type": "COR", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "L'ANCRE SÈCHE", "trip_gears": null, @@ -667,6 +745,19 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 3109, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_109_COR", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_109_COR_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: MERLU L'ENCHANTEUR // - With DEL @@ -683,7 +774,6 @@ "operation_number": "FAKE_OPERATION_110", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "trip_gears": null, "trip_segments": null, @@ -719,7 +809,20 @@ "id": 1110, "report_id": null, "referenced_report_id": "FAKE_OPERATION_110", - "cfr": "FR263418260", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_110_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, + { + "id": 2110, + "report_id": "FAKE_OPERATION_110_DEL", + "referenced_report_id": "FAKE_OPERATION_110", + "cfr": "CFR107", "enriched": false, "flag_state": null, "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", @@ -728,18 +831,30 @@ "operation_number": "FAKE_OPERATION_110_DEL", "operation_type": "DEL", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": null, "trip_gears": null, "trip_segments": null, "value": null }, + { + "id": 3110, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_110_DEL", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_110_DEL_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: LE POISSON AMBULANT // - Orphan COR (no DAT) { - "id": 1111, + "id": 2111, "report_id": "FAKE_OPERATION_111_COR_ORPHAN", // This `referenced_report_id` doesn't exist, this is intentional "referenced_report_id": "FAKE_OPERATION_111", @@ -752,7 +867,6 @@ "operation_number": "FAKE_OPERATION_111_COR_ORPHAN", "operation_type": "COR", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "LE POISSON AMBULANT", "trip_gears": null, @@ -788,6 +902,19 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 3111, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_111_COR_ORPHAN", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_111_COR_ORPHAN_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: UNKNOWN // - NOT Enriched @@ -804,13 +931,25 @@ "operation_number": "FAKE_OPERATION_112", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": null, "trip_gears": null, "trip_segments": null, "value": null }, + { + "id": 1112, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_112", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_112_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: LE POISSON D'AVRIL // - DUPLICATE Vessel CFR (= 2 `vessels` table rows with the same `cfr` value) @@ -827,7 +966,6 @@ "operation_number": "FAKE_OPERATION_113", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "FLUX", "trip_gears:jsonb": [{ "gear": "DRB", "mesh": null, "dimensions": null }], "trip_segments:jsonb": [{ "segment": "FR_SCE", "segmentName": "Scallop fisheries" }], @@ -895,6 +1033,19 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 1113, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_113", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_113_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: LA MER À BOIRE // - Without port (=> without seafront) @@ -911,7 +1062,6 @@ "operation_number": "FAKE_OPERATION_114", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "LA MER À BOIRE", "trip_gears:jsonb": [], @@ -926,6 +1076,19 @@ "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '20 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } }, + { + "id": 1114, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_114", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_114_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } + }, // - Vessel: LE MARIN D'EAU DOUCE // - Port: Saint-Denis De La Réunion (Sud Océan Indien) @@ -942,7 +1105,6 @@ "operation_number": "FAKE_OPERATION_115", "operation_type": "DAT", "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '6 hours'", - "software": "JT/VISIOCaptures V1.4.7", "transmission_format": "ERS", "vessel_name": "LE MARIN D'EAU DOUCE", "trip_gears:jsonb": [], @@ -961,6 +1123,19 @@ "purpose": "LAN", "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '20 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } + }, + { + "id": 1115, + "report_id": null, + "referenced_report_id": "FAKE_OPERATION_115", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '14 minutes'", + "operation_number": "FAKE_OPERATION_115_RET", + "operation_type": "RET", + "transmission_format": "ERS", + "value:jsonb": { + "returnStatus": "000" + } } ] } diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessageUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessageUTests.kt index fb40961f83..bde3151b61 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessageUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/logbook/LogbookMessageUTests.kt @@ -2,7 +2,6 @@ package fr.gouv.cnsp.monitorfish.domain.entities.logbook import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.Acknowledgment import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.LogbookMessageValue -import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.PNO import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -39,432 +38,6 @@ class LogbookMessageUTests { } } - @Test - fun `toConsolidatedLogbookMessageAndValue Should set acknowledge to successful with one successful RET message`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "000"), - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.isSuccess).isTrue() - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should set acknowledge to successful with multiple RET messages of which one is successful, no matter the (historical) order`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "002"), - ), - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "000"), - ), - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 3, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "001"), - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.isSuccess).isTrue() - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should set acknowledge to not successful with one unsuccessful RET message`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "001"), - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.isSuccess).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should set acknowledge to (most recent) not successful with multiple unsucessful RET message`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "001"), - ), - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "002"), - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.isSuccess).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.dateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - - // When - val enrichedLogbookMessageReversed = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages.reversed(), PNO::class.java) - - // Then - assertThat(enrichedLogbookMessageReversed.logbookMessage.acknowledgment?.isSuccess).isFalse() - assertThat(enrichedLogbookMessageReversed.logbookMessage.acknowledgment?.dateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessageReversed.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessageReversed.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should set acknowledge to successful when it comes from FLUX flow`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ).copy( - transmissionFormat = LogbookTransmissionFormat.FLUX, - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(emptyList(), PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.isSuccess).isTrue() - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should set acknowledge to successful when it was generated via VISIOCaptures app`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ).copy( - software = "... VISIOCaptures ...", - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(emptyList(), PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.isSuccess).isTrue() - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should flag it as corrected from an orphan COR message`() { - // Given - val missingDatLogbookMessageReportId = UUID.randomUUID().toString() - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - missingDatLogbookMessageReportId, - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(emptyList(), PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.reportDateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should use the most recent COR message as base and flag it corrected from a DAT with multiple COR messages`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 3, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.reportDateTime).isEqualTo( - ZonedDateTime.of(2024, 1, 1, 0, 0, 3, 0, ZoneOffset.UTC), - ) - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - - // When - val enrichedLogbookMessageReversed = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages.reversed(), PNO::class.java) - - // Then - assertThat(enrichedLogbookMessageReversed.logbookMessage.reportDateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 3, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessageReversed.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessageReversed.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should flag it as deleted from a DAT with a DEL message`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.DEL, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.reportDateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isTrue() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should flag it as corrected and deleted from an orphan COR with a DEL message`() { - // Given - val missingDatLogbookMessageReportId = UUID.randomUUID().toString() - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - missingDatLogbookMessageReportId, - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.DEL, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.reportDateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isTrue() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should use the most recent COR message as base and flag it corrected and deleted from a DAT with COR and DEL messages`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - getFakeLogbookMessage( - LogbookOperationType.DEL, - ZonedDateTime.of(2024, 1, 1, 0, 0, 3, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.reportDateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isTrue() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should use the most recent COR message as base and associate its RET from a DAT, even with a later DAT-RET message`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val corLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - // This first RET message is related to the DAT message. - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "000"), - ), - corLogbookMessage, - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 3, 0, ZoneOffset.UTC), - // This second RET message is related to the COR and not DAT message. - corLogbookMessage.reportId, - Acknowledgment(returnStatus = "002"), - ), - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 4, 0, ZoneOffset.UTC), - // This third RET message is related to the COR and not DAT message. - corLogbookMessage.reportId, - Acknowledgment(returnStatus = "001"), - ), - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 5, 0, ZoneOffset.UTC), - // This fourth RET message is related to the DAT message. - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "000"), - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.reportDateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.isSuccess).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.dateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 4, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment?.returnStatus).isEqualTo("001") - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - - @Test - fun `toConsolidatedLogbookMessageAndValue Should use the most recent COR message as base and skip acknowledgement flagging without a COR-related RET`() { - // Given - val refenceLogbookMessage = getFakeLogbookMessage( - LogbookOperationType.DAT, - ZonedDateTime.of(2024, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), - ) - val relatedLogbookMessages = listOf( - getFakeLogbookMessage( - LogbookOperationType.RET, - ZonedDateTime.of(2024, 1, 1, 0, 0, 1, 0, ZoneOffset.UTC), - // This first RET message is related to the DAT message. - refenceLogbookMessage.reportId, - Acknowledgment(returnStatus = "000"), - ), - getFakeLogbookMessage( - LogbookOperationType.COR, - ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC), - refenceLogbookMessage.reportId, - ), - ) - - // When - val enrichedLogbookMessage = refenceLogbookMessage - .toConsolidatedLogbookMessageAndValue(relatedLogbookMessages, PNO::class.java) - - // Then - assertThat(enrichedLogbookMessage.logbookMessage.reportDateTime) - .isEqualTo(ZonedDateTime.of(2024, 1, 1, 0, 0, 2, 0, ZoneOffset.UTC)) - assertThat(enrichedLogbookMessage.logbookMessage.acknowledgment).isNull() - assertThat(enrichedLogbookMessage.logbookMessage.isCorrectedByNewerMessage).isFalse() - assertThat(enrichedLogbookMessage.logbookMessage.isDeleted).isFalse() - } - @Test fun `setAcknowledge should create a new successful acknowledgment when current is null`() { // Given diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationUTests.kt index 1585ea8421..83813036b3 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationUTests.kt @@ -50,7 +50,7 @@ class GetPriorNotificationUTests { // Given given( - logbookReportRepository.findPriorNotificationByReportId( + logbookReportRepository.findAcknowledgedPriorNotificationByReportId( fakePriorNotification.reportId!!, fakePriorNotification.logbookMessageAndValue.logbookMessage.operationDateTime, ), @@ -108,7 +108,7 @@ class GetPriorNotificationUTests { // Given given( - logbookReportRepository.findPriorNotificationByReportId( + logbookReportRepository.findAcknowledgedPriorNotificationByReportId( fakeLogbookMessageReferenceReportId, fakePriorNotification.logbookMessageAndValue.logbookMessage.operationDateTime, ), diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationsUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationsUTests.kt index f3822d7632..55901ba4cd 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationsUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/GetPriorNotificationsUTests.kt @@ -59,7 +59,7 @@ class GetPriorNotificationsUTests { @Test fun `execute Should return a list of prior notifications with their total length`() { // Given - given(logbookReportRepository.findAllPriorNotifications(defaultFilter)).willReturn( + given(logbookReportRepository.findAllAcknowledgedPriorNotifications(defaultFilter)).willReturn( listOf( PriorNotification( reportId = "FAKE_REPORT_ID_1", diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/VerifyAndSendPriorNotificationUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/VerifyAndSendPriorNotificationUTests.kt index 5b485eaf75..ae4ce40861 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/VerifyAndSendPriorNotificationUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/VerifyAndSendPriorNotificationUTests.kt @@ -27,7 +27,7 @@ class VerifyAndSendPriorNotificationUTests { // Given given( - logbookReportRepository.findPriorNotificationByReportId( + logbookReportRepository.findAcknowledgedPriorNotificationByReportId( fakePriorNotification.reportId!!, fakePriorNotification.logbookMessageAndValue.logbookMessage.operationDateTime, ), @@ -65,7 +65,7 @@ class VerifyAndSendPriorNotificationUTests { // Given given( - logbookReportRepository.findPriorNotificationByReportId( + logbookReportRepository.findAcknowledgedPriorNotificationByReportId( fakePriorNotification.reportId!!, fakePriorNotification.logbookMessageAndValue.logbookMessage.operationDateTime, ), diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerITests.kt index eea8b8bdb9..059d1c4438 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerITests.kt @@ -93,8 +93,8 @@ class PriorNotificationControllerITests { // Then .andExpect(status().isOk) .andExpect(jsonPath("$.data.length()", equalTo(2))) - .andExpect(jsonPath("$.data[0].id", equalTo(firstFakePriorNotification.reportId))) - .andExpect(jsonPath("$.data[1].id", equalTo(secondFakePriorNotification.reportId))) + .andExpect(jsonPath("$.data[0].reportId", equalTo(firstFakePriorNotification.reportId))) + .andExpect(jsonPath("$.data[1].reportId", equalTo(secondFakePriorNotification.reportId))) .andExpect(jsonPath("$.extraData.perSeafrontGroupCount", equalTo(emptyMap()))) .andExpect(jsonPath("$.lastPageNumber", equalTo(0))) .andExpect(jsonPath("$.pageNumber", equalTo(0))) diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepositoryITests.kt index 32bb1cc3bb..21d85bcbc8 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookReportRepositoryITests.kt @@ -5,12 +5,10 @@ import fr.gouv.cnsp.monitorfish.config.MapperConfiguration import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessagePurpose import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookOperationType import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookRawMessage -import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookTransmissionFormat import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.* import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.filters.PriorNotificationsFilter import fr.gouv.cnsp.monitorfish.domain.exceptions.NoLogbookFishingTripFound import fr.gouv.cnsp.monitorfish.domain.use_cases.TestUtils -import fr.gouv.cnsp.monitorfish.infrastructure.database.entities.LogbookReportEntity import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.AfterEach @@ -21,10 +19,8 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.cache.CacheManager import org.springframework.context.annotation.Import import org.springframework.transaction.annotation.Transactional -import java.time.Instant import java.time.ZoneOffset.UTC import java.time.ZonedDateTime -import java.util.* @Import(MapperConfiguration::class) @SpringBootTest(properties = ["monitorfish.scheduling.enable=false"]) @@ -553,7 +549,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + val result = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(filter) // Then assertThat(result).hasSizeGreaterThan(0) @@ -579,7 +575,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + val firstResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(firstFilter) // Then assertThat(firstResult).hasSizeGreaterThan(0) @@ -597,7 +593,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + val secondResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(secondFilter) // Then assertThat(secondResult).hasSizeGreaterThan(0) @@ -619,7 +615,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + val firstResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(firstFilter) // Then assertThat(firstResult).hasSizeGreaterThan(0) @@ -639,7 +635,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + val secondResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(secondFilter) // Then assertThat(secondResult).hasSizeGreaterThan(0) @@ -663,7 +659,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + val firstResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(firstFilter) // Then assertThat(firstResult).hasSizeGreaterThan(0) @@ -687,7 +683,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + val secondResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(secondFilter) // Then assertThat(secondResult).hasSizeGreaterThan(0) @@ -715,7 +711,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + val result = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(filter) // Then assertThat(result).hasSizeGreaterThan(0) @@ -737,7 +733,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + val firstResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(firstFilter) // Then assertThat(firstResult).hasSizeGreaterThan(0) @@ -757,7 +753,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + val secondResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(secondFilter) // Then assertThat(secondResult).hasSizeGreaterThan(0) @@ -781,7 +777,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + val firstResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(firstFilter) // Then assertThat(firstResult).hasSizeGreaterThan(0) @@ -801,7 +797,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + val secondResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(secondFilter) // Then assertThat(secondResult).hasSizeGreaterThan(0) @@ -825,7 +821,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + val result = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(filter) // Then assertThat(result).hasSizeGreaterThan(0) @@ -848,7 +844,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + val result = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(filter) // Then assertThat(result).hasSizeGreaterThan(0) @@ -871,7 +867,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + val result = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(filter) // Then assertThat(result).hasSizeGreaterThan(0) @@ -898,7 +894,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + val result = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(filter) // Then assertThat(result).hasSizeGreaterThan(0) @@ -920,7 +916,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + val firstResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(firstFilter) // Then assertThat(firstResult).hasSizeGreaterThan(0) @@ -938,7 +934,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + val secondResult = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(secondFilter) // Then assertThat(secondResult).hasSizeGreaterThan(0) @@ -962,7 +958,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + val result = jpaLogbookReportRepository.findAllAcknowledgedPriorNotifications(filter) // Then assertThat(result).hasSizeGreaterThan(0) @@ -1013,97 +1009,6 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { assertThat(result.messageType).isEqualTo("PNO") } - @Test - @Transactional - fun `mapToReferenceWithRelatedModels should correctly map models`() { - // Given - - val firstLogbookReportGroupDatOperation = getFakeLogbookReportModel(LogbookOperationType.DAT) - val firstLogbookReportGroup = listOf( - firstLogbookReportGroupDatOperation, - ) - - val secondLogbookReportGroupDatOperation = getFakeLogbookReportModel(LogbookOperationType.DAT) - val secondLogbookReportGroup = listOf( - secondLogbookReportGroupDatOperation, - getFakeLogbookReportModel(LogbookOperationType.RET, secondLogbookReportGroupDatOperation.reportId), - ) - - val thirdLogbookReportGroupDatOperation = getFakeLogbookReportModel(LogbookOperationType.DAT) - val thirdLogbookReportGroupCorOperation = getFakeLogbookReportModel( - LogbookOperationType.COR, - thirdLogbookReportGroupDatOperation.reportId, - ) - val thirdLogbookReportGroup = listOf( - thirdLogbookReportGroupDatOperation, - getFakeLogbookReportModel(LogbookOperationType.RET, thirdLogbookReportGroupDatOperation.reportId), - thirdLogbookReportGroupCorOperation, - getFakeLogbookReportModel(LogbookOperationType.RET, thirdLogbookReportGroupCorOperation.reportId), - getFakeLogbookReportModel(LogbookOperationType.DEL, thirdLogbookReportGroupDatOperation.reportId), - ) - - val fourthLogbookReportGroupDatOperation = getFakeLogbookReportModel(LogbookOperationType.COR) - val fourthLogbookReportGroup = listOf( - fourthLogbookReportGroupDatOperation, - getFakeLogbookReportModel(LogbookOperationType.RET, fourthLogbookReportGroupDatOperation.reportId), - ) - - val fifthLogbookReportGroupDatOperation = getFakeLogbookReportModel( - LogbookOperationType.COR, - "NONEXISTENT_REPORT_ID", - ) - val fifthLogbookReportGroup = listOf( - fifthLogbookReportGroupDatOperation, - getFakeLogbookReportModel(LogbookOperationType.RET, fifthLogbookReportGroupDatOperation.reportId), - ) - - val logbookReportModels = listOf( - firstLogbookReportGroup, - secondLogbookReportGroup, - thirdLogbookReportGroup, - fourthLogbookReportGroup, - fifthLogbookReportGroup, - ).flatten() - - // When - val result = JpaLogbookReportRepository.mapToReferenceWithRelatedModels(logbookReportModels) - - // Then - - assertThat(result).hasSize(5) - - val (firstReferenceLogbookReportModel, firstRelatedLogbookReportModels) = result[0] - assertThat(firstReferenceLogbookReportModel.reportId).isEqualTo(firstLogbookReportGroupDatOperation.reportId) - assertThat(firstReferenceLogbookReportModel.operationType).isEqualTo(LogbookOperationType.DAT) - assertThat(firstRelatedLogbookReportModels).isEmpty() - - val (secondReferenceLogbookReportModel, secondRelatedLogbookReportModels) = result[1] - assertThat(secondReferenceLogbookReportModel.reportId).isEqualTo(secondLogbookReportGroupDatOperation.reportId) - assertThat(secondReferenceLogbookReportModel.operationType).isEqualTo(LogbookOperationType.DAT) - assertThat(secondRelatedLogbookReportModels).hasSize(1) - assertThat(secondRelatedLogbookReportModels.count { it.operationType == LogbookOperationType.RET }).isEqualTo(1) - - val (thirdReferenceLogbookReportModel, thirdRelatedLogbookReportModels) = result[2] - assertThat(thirdReferenceLogbookReportModel.reportId).isEqualTo(thirdLogbookReportGroupDatOperation.reportId) - assertThat(thirdReferenceLogbookReportModel.operationType).isEqualTo(LogbookOperationType.DAT) - assertThat(thirdRelatedLogbookReportModels).hasSize(4) - assertThat(thirdRelatedLogbookReportModels.count { it.operationType == LogbookOperationType.COR }).isEqualTo(1) - assertThat(thirdRelatedLogbookReportModels.count { it.operationType == LogbookOperationType.DEL }).isEqualTo(1) - assertThat(thirdRelatedLogbookReportModels.count { it.operationType == LogbookOperationType.RET }).isEqualTo(2) - - val (fourthReferenceLogbookReportModel, fourthRelatedLogbookReportModels) = result[3] - assertThat(fourthReferenceLogbookReportModel.reportId).isEqualTo(fourthLogbookReportGroupDatOperation.reportId) - assertThat(fourthReferenceLogbookReportModel.operationType).isEqualTo(LogbookOperationType.COR) - assertThat(fourthRelatedLogbookReportModels).hasSize(1) - assertThat(fourthRelatedLogbookReportModels.count { it.operationType == LogbookOperationType.RET }).isEqualTo(1) - - val (fifthReferenceLogbookReportModel, fifthRelatedLogbookReportModels) = result[4] - assertThat(fifthReferenceLogbookReportModel.reportId).isEqualTo(fifthLogbookReportGroupDatOperation.reportId) - assertThat(fifthReferenceLogbookReportModel.operationType).isEqualTo(LogbookOperationType.COR) - assertThat(fifthRelatedLogbookReportModels).hasSize(1) - assertThat(fifthRelatedLogbookReportModels.count { it.operationType == LogbookOperationType.RET }).isEqualTo(1) - } - @Test @Transactional fun `findLastReportSoftware Should return the software of the last message`() { @@ -1128,16 +1033,13 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `updatePriorNotificationState Should update writable state values for an existing PNO logbook report`() { // Given - val currentDatReport = jpaLogbookReportRepository.findById(109) - assertThat((currentDatReport.message as PNO).isBeingSent).isEqualTo(false) - assertThat((currentDatReport.message as PNO).isVerified).isEqualTo(false) - val currentCorReport = jpaLogbookReportRepository.findById(1109) + val currentCorReport = jpaLogbookReportRepository.findById(2109) assertThat((currentCorReport.message as PNO).isBeingSent).isEqualTo(false) assertThat((currentCorReport.message as PNO).isVerified).isEqualTo(false) // When jpaLogbookReportRepository.updatePriorNotificationState( - "FAKE_OPERATION_109", + "FAKE_OPERATION_109_COR", ZonedDateTime.now().minusMinutes(15), isBeingSent = true, isSent = false, @@ -1145,10 +1047,7 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // Then - val updatedDatReport = jpaLogbookReportRepository.findById(109) - assertThat((updatedDatReport.message as PNO).isBeingSent).isEqualTo(true) - assertThat((updatedDatReport.message as PNO).isVerified).isEqualTo(true) - val updatedCorReport = jpaLogbookReportRepository.findById(1109) + val updatedCorReport = jpaLogbookReportRepository.findById(2109) assertThat((updatedCorReport.message as PNO).isBeingSent).isEqualTo(true) assertThat((updatedCorReport.message as PNO).isVerified).isEqualTo(true) } @@ -1157,26 +1056,19 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `updatePriorNotificationNote Should update a note for an existing PNO logbook report`() { // Given - val currentDatReport = jpaLogbookReportRepository.findById(109) - assertThat((currentDatReport.message as PNO).note).isNull() - val currentCorReport = jpaLogbookReportRepository.findById(1109) + val currentCorReport = jpaLogbookReportRepository.findById(2109) assertThat((currentCorReport.message as PNO).note).isNull() // When jpaLogbookReportRepository.updatePriorNotificationAuthorTrigramAndNote( - "FAKE_OPERATION_109", + "FAKE_OPERATION_109_COR", ZonedDateTime.now().minusMinutes(15), "ABC", "A wonderful note", ) // Then - val updatedDatReport = jpaLogbookReportRepository.findById(109) - assertThat((updatedDatReport.message as PNO).note).isEqualTo("A wonderful note") - assertThat((updatedDatReport.message as PNO).isBeingSent).isEqualTo(false) - assertThat((updatedDatReport.message as PNO).isVerified).isEqualTo(false) - assertThat((updatedDatReport.message as PNO).isSent).isEqualTo(false) - val updatedCorReport = jpaLogbookReportRepository.findById(1109) + val updatedCorReport = jpaLogbookReportRepository.findById(2109) assertThat((updatedCorReport.message as PNO).note).isEqualTo("A wonderful note") assertThat((updatedCorReport.message as PNO).isBeingSent).isEqualTo(false) assertThat((updatedCorReport.message as PNO).isVerified).isEqualTo(false) @@ -1187,54 +1079,17 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `invalidate Should invalidate for an existing PNO logbook report`() { // Given - val currentDatReport = jpaLogbookReportRepository.findById(109) - assertThat((currentDatReport.message as PNO).isInvalidated).isNull() - val currentCorReport = jpaLogbookReportRepository.findById(1109) + val currentCorReport = jpaLogbookReportRepository.findById(2109) assertThat((currentCorReport.message as PNO).isInvalidated).isNull() // When jpaLogbookReportRepository.invalidate( - "FAKE_OPERATION_109", + "FAKE_OPERATION_109_COR", ZonedDateTime.now().minusMinutes(15), ) // Then - val updatedDatReport = jpaLogbookReportRepository.findById(109) - assertThat((updatedDatReport.message as PNO).isInvalidated).isEqualTo(true) - val updatedCorReport = jpaLogbookReportRepository.findById(1109) + val updatedCorReport = jpaLogbookReportRepository.findById(2109) assertThat((updatedCorReport.message as PNO).isInvalidated).isEqualTo(true) } - - companion object { - private fun getFakeLogbookReportModel( - operationType: LogbookOperationType, - referenceReportId: String? = null, - ): LogbookReportEntity { - val reportId = UUID.randomUUID().toString() - - return LogbookReportEntity( - reportId = reportId, - referencedReportId = referenceReportId, - externalReferenceNumber = null, - flagState = null, - integrationDateTime = Instant.now(), - internalReferenceNumber = null, - imo = null, - ircs = null, - message = null, - messageType = null, - operationCountry = null, - operationDateTime = Instant.now(), - operationNumber = "FAKE_OPERATION_NUMBER_$reportId", - operationType = operationType, - reportDateTime = null, - software = null, - transmissionFormat = LogbookTransmissionFormat.ERS, - tripGears = null, - tripNumber = null, - tripSegments = null, - vesselName = null, - ) - } - } } diff --git a/frontend/cypress/e2e/side_window/logbook_prior_notification_form/error_handling.spec.ts b/frontend/cypress/e2e/side_window/logbook_prior_notification_form/error_handling.spec.ts index 16c00cedf5..26100c5f9b 100644 --- a/frontend/cypress/e2e/side_window/logbook_prior_notification_form/error_handling.spec.ts +++ b/frontend/cypress/e2e/side_window/logbook_prior_notification_form/error_handling.spec.ts @@ -4,7 +4,7 @@ import { editSideWindowPriorNotification } from '../manual_prior_notification_fo context('Side Window > Logbook Prior Notification Form > Error Handling', () => { const failedQueryCount = RTK_MAX_RETRIES + 1 - const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109?isManuallyCreated=false&operationDate=*' + const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109_COR?isManuallyCreated=false&operationDate=*' it('Should handle fetching error as expected', () => { cy.intercept( @@ -18,7 +18,7 @@ context('Side Window > Logbook Prior Notification Form > Error Handling', () => } ).as('getPriorNotificationsWithError') - editSideWindowPriorNotification(`L'ANCRE`, 'FAKE_OPERATION_109') + editSideWindowPriorNotification(`L'ANCRE`, 'FAKE_OPERATION_109_COR') for (let i = 1; i <= failedQueryCount; i += 1) { cy.wait('@getPriorNotificationsWithError') diff --git a/frontend/cypress/e2e/side_window/logbook_prior_notification_form/form.spec.ts b/frontend/cypress/e2e/side_window/logbook_prior_notification_form/form.spec.ts index be04b34384..d2e25145f0 100644 --- a/frontend/cypress/e2e/side_window/logbook_prior_notification_form/form.spec.ts +++ b/frontend/cypress/e2e/side_window/logbook_prior_notification_form/form.spec.ts @@ -4,11 +4,11 @@ import { editSideWindowPriorNotification } from '../manual_prior_notification_fo context('Side Window > Logbook Prior Notification Form > Form', () => { it('Should not update the form with a PUT request on first render', () => { - cy.intercept('PUT', '/bff/v1/prior_notifications/logbook/FAKE_OPERATION_114*', cy.spy().as('updateForm')) + cy.intercept('PUT', '/bff/v1/prior_notifications/logbook/FAKE_OPERATION_115*', cy.spy().as('updateForm')) - editSideWindowPriorNotification(`LA MER À BOIRE`, 'FAKE_OPERATION_114') + editSideWindowPriorNotification(`LE MARIN`, 'FAKE_OPERATION_115') - cy.contains(`LA MER À BOIRE (CFR110)`).should('be.visible') + cy.contains(`LE MARIN D'EAU DOUCE (CFR111)`).should('be.visible') cy.get('@updateForm').should('not.have.been.called') @@ -17,7 +17,8 @@ context('Side Window > Logbook Prior Notification Form > Form', () => { cy.get('@updateForm').should('have.been.calledOnce') // Reset - cy.request('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_114?operationDate=${dayjs().toISOString()}`, { + const operationDate = dayjs().subtract(6, 'hours').toISOString() + cy.request('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_115?operationDate=${operationDate}`, { body: { authorTrigram: null, note: null diff --git a/frontend/cypress/e2e/side_window/prior_notification_card/card.spec.ts b/frontend/cypress/e2e/side_window/prior_notification_card/card.spec.ts index 12e30851b9..ba4ae5e59f 100644 --- a/frontend/cypress/e2e/side_window/prior_notification_card/card.spec.ts +++ b/frontend/cypress/e2e/side_window/prior_notification_card/card.spec.ts @@ -59,27 +59,8 @@ context('Side Window > Prior Notification Card > Card', () => { cy.contains(`25 kg`).should('be.visible') }) - it('Should display a failed acknowledged message as expected', () => { - openSideWindowPriorNotification(`CALAMARO`) - - // Title - cy.contains(`Préavis navire ≥ 12 M`).should('be.visible') - cy.contains(`CALAMARO (CFR105)`).should('be.visible') - - // Message Header - cy.contains(`PNO`).should('be.visible') - cy.contains(`Préavis (notification de retour au port)`).should('be.visible') - - // Message Body - cy.getDataCy('LogbookMessage-failed-acknowledgement-icon').should('be.visible') - cy.contains(`Saint-Malo (FRSML)`).should('be.visible') - cy.contains(`Débarquement (LAN)`).should('be.visible') - cy.contains(`BAUDROIE (ANF)`).should('be.visible') - cy.contains(`150 kg`).should('be.visible') - }) - it('Should refresh the list when the opened prior notification data differs from its entry in the current list', () => { - const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109?isManuallyCreated=false&operationDate=*' + const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109_COR?isManuallyCreated=false&operationDate=*' cy.intercept({ method: 'GET', @@ -112,7 +93,7 @@ context('Side Window > Prior Notification Card > Card', () => { }) it('Should display a warning banner and refresh the list when the opened prior notification has been deleted', () => { - const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109?isManuallyCreated=false&operationDate=*' + const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109_COR?isManuallyCreated=false&operationDate=*' cy.intercept({ method: 'GET', @@ -152,7 +133,9 @@ context('Side Window > Prior Notification Card > Card', () => { }) it('Should update a logbook prior notification', () => { - cy.request('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_108?operationDate=${dayjs().toISOString()}`, { + // Reset + const operationDate = dayjs().subtract(6, 'hours').toISOString() + cy.request('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_114?operationDate=${operationDate}`, { body: { authorTrigram: null, note: null @@ -160,9 +143,9 @@ context('Side Window > Prior Notification Card > Card', () => { }) // Given - openSideWindowPriorNotification(`CALAMARO`) + openSideWindowPriorNotification(`MER À BOIRE`) - cy.intercept('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_108?operationDate=*`).as( + cy.intercept('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_114?operationDate=*`).as( 'updateLogbookPriorNotification' ) @@ -179,13 +162,13 @@ context('Side Window > Prior Notification Card > Card', () => { cy.get('.Element-Button').contains('Télécharger').parent().should('be.disabled') // The note is saved - openSideWindowPriorNotification(`CALAMARO`) + openSideWindowPriorNotification(`MER À BOIRE`) cy.get('[name="note"]').should('have.value', "Un point d'attention.") cy.get('[name="authorTrigram"]').should('have.value', 'ABC') // Reset - cy.request('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_108?operationDate=${dayjs().toISOString()}`, { + cy.request('PUT', `/bff/v1/prior_notifications/logbook/FAKE_OPERATION_114?operationDate=${operationDate}`, { body: { authorTrigram: null, note: null @@ -198,7 +181,7 @@ context('Side Window > Prior Notification Card > Card', () => { cy.intercept( 'POST', - `/bff/v1/prior_notifications/FAKE_OPERATION_111/verify_and_send?isManuallyCreated=false&operationDate=*` + `/bff/v1/prior_notifications/FAKE_OPERATION_111_COR_ORPHAN/verify_and_send?isManuallyCreated=false&operationDate=*` ).as('verifyAndSendPriorNotification') cy.clickButton('Diffuser') @@ -222,7 +205,7 @@ context('Side Window > Prior Notification Card > Card', () => { cy.clickButton('Fermer') cy.fill('Rechercher un navire', 'LE POISSON AMBULANT') - cy.getTableRowById('FAKE_OPERATION_111' as unknown as number) + cy.getTableRowById('FAKE_OPERATION_111_COR_ORPHAN' as unknown as number) .find('span[title="Diffusion en cours"]') .should('be.visible') }) @@ -250,11 +233,11 @@ context('Side Window > Prior Notification Card > Card', () => { cy.get('[data-cy="side-window-sub-menu-ALL"]').click() cy.fill('Rechercher un navire', 'ANCRE') - cy.getTableRowById('FAKE_OPERATION_109' as any) + cy.getTableRowById('FAKE_OPERATION_109_COR' as any) .find('[title="Préavis invalidé"]') .should('not.exist') - cy.getTableRowById('FAKE_OPERATION_109' as any).clickButton('Éditer le préavis') + cy.getTableRowById('FAKE_OPERATION_109_COR' as any).clickButton('Éditer le préavis') if (document.querySelector('[data-cy="first-loader"]')) { cy.getDataCy('first-loader').should('not.be.visible') } @@ -269,7 +252,7 @@ context('Side Window > Prior Notification Card > Card', () => { cy.clickButton('Fermer') - cy.getTableRowById('FAKE_OPERATION_109' as any) + cy.getTableRowById('FAKE_OPERATION_109_COR' as any) .find('[title="Préavis invalidé"]') .should('exist') }) diff --git a/frontend/cypress/e2e/side_window/prior_notification_card/error_handling.spec.ts b/frontend/cypress/e2e/side_window/prior_notification_card/error_handling.spec.ts index 1c9e81c2a9..0250ec3fa4 100644 --- a/frontend/cypress/e2e/side_window/prior_notification_card/error_handling.spec.ts +++ b/frontend/cypress/e2e/side_window/prior_notification_card/error_handling.spec.ts @@ -4,7 +4,7 @@ import { openSideWindowPriorNotification } from './utils' context('Side Window > Logbook Prior Notification Card > Error Handling', () => { const failedQueryCount = RTK_MAX_RETRIES + 1 - const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109?isManuallyCreated=false&operationDate=*' + const url = '/bff/v1/prior_notifications/FAKE_OPERATION_109_COR?isManuallyCreated=false&operationDate=*' beforeEach(() => { cy.intercept('/bff/v1/authorization/current', { statusCode: 401 }).as('getIsSuperUser') diff --git a/frontend/package.json b/frontend/package.json index 2700242b8a..82928d88d2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,6 +13,7 @@ "clean": "rm -Rf ./node-modules/.vite ./node-modules/build", "cypress:open": "cypress open --browser firefox --config-file ./config/cypress.config.js --e2e", "dev": "import-meta-env-prepare -x ./.env.local.defaults && vite --port 3000", + "dev-cypress": "FRONTEND_OIDC_ENABLED=false import-meta-env-prepare -u -x ./.env.local.defaults && vite --port 3000", "dev-monitorenv": "FRONTEND_MONITORENV_URL=//localhost:9880 import-meta-env-prepare -u -x ./.env.local.defaults && vite --port 3000", "dev-puppeteer": "FRONTEND_MONITORENV_URL=//localhost:9880 import-meta-env-prepare -u -x ./.env.local.defaults && vite --port 3000", "bundle-sw": "esbuild src/workers/serviceWorker.ts --bundle --outfile=public/service-worker.js", diff --git a/frontend/src/api/BackendApi.types.ts b/frontend/src/api/BackendApi.types.ts index d8672f150c..6c7f28e9c9 100644 --- a/frontend/src/api/BackendApi.types.ts +++ b/frontend/src/api/BackendApi.types.ts @@ -1,4 +1,4 @@ -import type { AnyEnum, CollectionItem } from '@mtes-mct/monitor-ui' +import type { AnyEnum } from '@mtes-mct/monitor-ui' import type { AnyObject } from 'yup' export namespace BackendApi { @@ -28,7 +28,7 @@ export namespace BackendApi { } export type ResponseBodyPaginatedList< - ItemData extends CollectionItem = CollectionItem, + ItemData extends AnyObject = AnyObject, ExtraData extends AnyObject | undefined = undefined > = { data: ItemData[] diff --git a/frontend/src/features/PriorNotification/PriorNotification.types.ts b/frontend/src/features/PriorNotification/PriorNotification.types.ts index 993b8b0130..c47184ca36 100644 --- a/frontend/src/features/PriorNotification/PriorNotification.types.ts +++ b/frontend/src/features/PriorNotification/PriorNotification.types.ts @@ -12,8 +12,6 @@ export namespace PriorNotification { /** Unique identifier concatenating all the DAT, COR, RET & DEL operations `id` used for data consolidation. */ fingerprint: string hasVesselRiskFactorSegments: boolean | undefined - /** Logbook message `reportId`. */ - id: string isBeingSent: boolean isCorrection: boolean isInVerificationScope: boolean @@ -27,6 +25,7 @@ export namespace PriorNotification { portLocode: string | undefined portName: string | undefined purposeCode: PurposeCode | undefined + reportId: string reportingCount: number riskFactor: number | undefined seafront: Seafront | undefined diff --git a/frontend/src/features/PriorNotification/components/PriorNotificationList/Row.tsx b/frontend/src/features/PriorNotification/components/PriorNotificationList/Row.tsx index df06a84c09..42bbd3cbbf 100644 --- a/frontend/src/features/PriorNotification/components/PriorNotificationList/Row.tsx +++ b/frontend/src/features/PriorNotification/components/PriorNotificationList/Row.tsx @@ -1,3 +1,4 @@ +import { getPriorNotificationIdentifier } from '@features/PriorNotification/utils' import { useMainAppDispatch } from '@hooks/useMainAppDispatch' import { customDayjs, Icon, TableWithSelectableRows, Tag, THEME } from '@mtes-mct/monitor-ui' import { flexRender, type Row as RowType } from '@tanstack/react-table' @@ -25,7 +26,7 @@ export function Row({ row }: RowProps) { if (priorNotification.isManuallyCreated) { dispatch( openManualPriorNotificationForm( - { operationDate: priorNotification.operationDate, reportId: priorNotification.id }, + getPriorNotificationIdentifier(priorNotification), priorNotification.fingerprint ) ) @@ -35,10 +36,7 @@ export function Row({ row }: RowProps) { dispatch( openPriorNotificationCard( - { - operationDate: priorNotification.operationDate, - reportId: priorNotification.id - }, + getPriorNotificationIdentifier(priorNotification), priorNotification.fingerprint, priorNotification.isManuallyCreated ) diff --git a/frontend/src/features/PriorNotification/components/PriorNotificationList/cells/ActionButtonsCell.tsx b/frontend/src/features/PriorNotification/components/PriorNotificationList/cells/ActionButtonsCell.tsx index 37353eed66..518f90a303 100644 --- a/frontend/src/features/PriorNotification/components/PriorNotificationList/cells/ActionButtonsCell.tsx +++ b/frontend/src/features/PriorNotification/components/PriorNotificationList/cells/ActionButtonsCell.tsx @@ -1,5 +1,6 @@ import { openLogbookPriorNotificationForm } from '@features/PriorNotification/useCases/openLogbookPriorNotificationForm' import { openManualPriorNotificationForm } from '@features/PriorNotification/useCases/openManualPriorNotificationForm' +import { getPriorNotificationIdentifier } from '@features/PriorNotification/utils' import { useMainAppDispatch } from '@hooks/useMainAppDispatch' import { Accent, Icon, IconButton } from '@mtes-mct/monitor-ui' import { VesselIdentifier, type VesselIdentity } from 'domain/entities/vessel/types' @@ -22,7 +23,7 @@ export function ActionButtonsCell({ priorNotification }: ActionButtonsCellProps) if (priorNotification.isManuallyCreated) { dispatch( openManualPriorNotificationForm( - { operationDate: priorNotification.operationDate, reportId: priorNotification.id }, + getPriorNotificationIdentifier(priorNotification), priorNotification.fingerprint ) ) @@ -31,20 +32,14 @@ export function ActionButtonsCell({ priorNotification }: ActionButtonsCellProps) } dispatch( - openLogbookPriorNotificationForm( - { operationDate: priorNotification.operationDate, reportId: priorNotification.id }, - priorNotification.fingerprint - ) + openLogbookPriorNotificationForm(getPriorNotificationIdentifier(priorNotification), priorNotification.fingerprint) ) } const open = () => { dispatch( openPriorNotificationCard( - { - operationDate: priorNotification.operationDate, - reportId: priorNotification.id - }, + getPriorNotificationIdentifier(priorNotification), priorNotification.fingerprint, priorNotification.isManuallyCreated ) diff --git a/frontend/src/features/PriorNotification/components/PriorNotificationList/columns.tsx b/frontend/src/features/PriorNotification/components/PriorNotificationList/columns.tsx index ef2d3f249b..086def4a04 100644 --- a/frontend/src/features/PriorNotification/components/PriorNotificationList/columns.tsx +++ b/frontend/src/features/PriorNotification/components/PriorNotificationList/columns.tsx @@ -18,7 +18,7 @@ export function getTableColumns(isFromUrl: boolean): Array row.id, + accessorFn: row => row.reportId, cell: ({ row }) => ( row.id, + accessorFn: row => row.reportId, cell: (info: CellContext) => ( ), diff --git a/frontend/src/features/PriorNotification/components/PriorNotificationList/index.tsx b/frontend/src/features/PriorNotification/components/PriorNotificationList/index.tsx index a7ea953b90..60032d2c73 100644 --- a/frontend/src/features/PriorNotification/components/PriorNotificationList/index.tsx +++ b/frontend/src/features/PriorNotification/components/PriorNotificationList/index.tsx @@ -122,7 +122,7 @@ export function PriorNotificationList({ isFromUrl }: PriorNotificationListProps) getCoreRowModel: getCoreRowModel(), getExpandedRowModel: getExpandedRowModel(), getRowCanExpand: () => true, - getRowId: row => row.id, + getRowId: row => row.reportId, manualPagination: true, manualSorting: true, onPaginationChange: setReactTablePaginationState, diff --git a/frontend/src/features/PriorNotification/utils.ts b/frontend/src/features/PriorNotification/utils.ts index bf70c8efa2..5cc2e24689 100644 --- a/frontend/src/features/PriorNotification/utils.ts +++ b/frontend/src/features/PriorNotification/utils.ts @@ -1,8 +1,18 @@ import type { PriorNotification } from './PriorNotification.types' import type { LogbookMessage } from '@features/Logbook/LogbookMessage.types' +type PriorNotificationData = { + operationDate: string + reportId: string +} + +export function getPriorNotificationIdentifier(data: PriorNotificationData): PriorNotification.Identifier +export function getPriorNotificationIdentifier(data: undefined): undefined +export function getPriorNotificationIdentifier( + data: PriorNotificationData | undefined +): PriorNotification.Identifier | undefined export function getPriorNotificationIdentifier( - data: { [key: string]: any; operationDate: string; reportId: string } | undefined + data: PriorNotificationData | undefined ): PriorNotification.Identifier | undefined { if (!data) { return undefined