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 980f354277..00a643d425 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 @@ -18,6 +18,7 @@ data class LogbookMessage( val externalReferenceNumber: String? = null, val ircs: String? = null, val vesselName: String? = null, + // ISO Alpha-3 country code val flagState: String? = null, val imo: String? = null, val messageType: String? = null, 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 e7cb4d8255..637eeb14c3 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 @@ -22,6 +22,7 @@ data class PriorNotification( val types: List, val vesselId: Int, val vesselExternalReferenceNumber: String?, + // ISO Alpha-2 country code val vesselFlagCountryCode: String?, val vesselInternalReferenceNumber: String?, val vesselIrcs: String?, diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/vessel/Vessel.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/vessel/Vessel.kt index f6b0c7ad00..ec754a5571 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/vessel/Vessel.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/vessel/Vessel.kt @@ -11,6 +11,7 @@ data class Vessel( val ircs: String? = null, val externalReferenceNumber: String? = null, val vesselName: String? = null, + // ISO Alpha-2 country code val flagState: CountryCode, val width: Double? = null, val length: Double? = null, @@ -37,11 +38,12 @@ data class Vessel( val underCharter: Boolean? = null, ) { fun getNationalIdentifier(): String { - val internalReferenceNumberCountryCode = LIKELY_CONTROLLED_COUNTRY_CODES.find { countryAlpha3 -> - internalReferenceNumber?.contains( - countryAlpha3, - ) ?: false - } + val internalReferenceNumberCountryCode = + LIKELY_CONTROLLED_COUNTRY_CODES.find { countryAlpha3 -> + internalReferenceNumber?.contains( + countryAlpha3, + ) ?: false + } val identifier = internalReferenceNumber?.replace("${internalReferenceNumberCountryCode}000", "") ?: "" if (districtCode.isNullOrEmpty()) { @@ -52,47 +54,48 @@ data class Vessel( } } -val LIKELY_CONTROLLED_COUNTRY_CODES = listOf( - CountryCode.FR.alpha3, - CountryCode.RU.alpha3, - CountryCode.KR.alpha3, - CountryCode.JP.alpha3, - CountryCode.LY.alpha3, - CountryCode.VE.alpha3, - CountryCode.SC.alpha3, - CountryCode.AU.alpha3, - CountryCode.CN.alpha3, - CountryCode.MG.alpha3, - CountryCode.BR.alpha3, - CountryCode.PL.alpha3, - CountryCode.VU.alpha3, - CountryCode.KM.alpha3, - CountryCode.MC.alpha3, - CountryCode.BW.alpha3, - CountryCode.AI.alpha3, - CountryCode.LK.alpha3, - CountryCode.TW.alpha3, - CountryCode.TT.alpha3, - CountryCode.FO.alpha3, - CountryCode.GY.alpha3, - CountryCode.PA.alpha3, - CountryCode.SX.alpha3, - CountryCode.TN.alpha3, - CountryCode.TR.alpha3, - CountryCode.AL.alpha3, - CountryCode.GD.alpha3, - CountryCode.DZ.alpha3, - CountryCode.SX.alpha3, - CountryCode.BE.alpha3, - CountryCode.DK.alpha3, - CountryCode.DE.alpha3, - CountryCode.EE.alpha3, - CountryCode.IE.alpha3, - CountryCode.ES.alpha3, - CountryCode.IT.alpha3, - CountryCode.NL.alpha3, - CountryCode.NO.alpha3, - CountryCode.PT.alpha3, - CountryCode.SE.alpha3, - CountryCode.GB.alpha3, -) +val LIKELY_CONTROLLED_COUNTRY_CODES = + listOf( + CountryCode.FR.alpha3, + CountryCode.RU.alpha3, + CountryCode.KR.alpha3, + CountryCode.JP.alpha3, + CountryCode.LY.alpha3, + CountryCode.VE.alpha3, + CountryCode.SC.alpha3, + CountryCode.AU.alpha3, + CountryCode.CN.alpha3, + CountryCode.MG.alpha3, + CountryCode.BR.alpha3, + CountryCode.PL.alpha3, + CountryCode.VU.alpha3, + CountryCode.KM.alpha3, + CountryCode.MC.alpha3, + CountryCode.BW.alpha3, + CountryCode.AI.alpha3, + CountryCode.LK.alpha3, + CountryCode.TW.alpha3, + CountryCode.TT.alpha3, + CountryCode.FO.alpha3, + CountryCode.GY.alpha3, + CountryCode.PA.alpha3, + CountryCode.SX.alpha3, + CountryCode.TN.alpha3, + CountryCode.TR.alpha3, + CountryCode.AL.alpha3, + CountryCode.GD.alpha3, + CountryCode.DZ.alpha3, + CountryCode.SX.alpha3, + CountryCode.BE.alpha3, + CountryCode.DK.alpha3, + CountryCode.DE.alpha3, + CountryCode.EE.alpha3, + CountryCode.IE.alpha3, + CountryCode.ES.alpha3, + CountryCode.IT.alpha3, + CountryCode.NL.alpha3, + CountryCode.NO.alpha3, + CountryCode.PT.alpha3, + CountryCode.SE.alpha3, + CountryCode.GB.alpha3, + ) 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 aabb56d544..c6dd02981a 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 @@ -46,6 +46,7 @@ data class LogbookReportEntity( val externalReferenceNumber: String? = null, @Column(name = "vessel_name") val vesselName: String? = null, + // ISO Alpha-3 country code @Column(name = "flag_state") val flagState: String? = null, @Column(name = "imo") diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/RiskFactorsEntity.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/RiskFactorsEntity.kt index d5e9c44a21..968edf5629 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/RiskFactorsEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/RiskFactorsEntity.kt @@ -43,6 +43,7 @@ data class RiskFactorsEntity( val segmentHighestPriority: String? = null, @Column(name = "control_priority_level") val controlPriorityLevel: Double, + // TODO Can't this field be null? @Column(name = "last_control_datetime_utc") val lastControlDatetime: ZonedDateTime, @Column(name = "control_rate_risk_factor") @@ -62,34 +63,36 @@ data class RiskFactorsEntity( @Column(name = "number_vessel_seizures_last_5_years") val numberVesselSeizuresLastFiveYears: Short, ) : Serializable { - - fun toVesselRiskFactor(mapper: ObjectMapper) = VesselRiskFactor( - impactRiskFactor = impactRiskFactor, - probabilityRiskFactor = probabilityRiskFactor, - detectabilityRiskFactor = detectabilityRiskFactor, - riskFactor = riskFactor, - internalReferenceNumber = cfr, - gearOnboard = mapper.readValue( - gearOnboard, - mapper.typeFactory - .constructCollectionType(MutableList::class.java, Gear::class.java), - ), - speciesOnboard = mapper.readValue( - speciesOnboard, - mapper.typeFactory - .constructCollectionType(MutableList::class.java, Species::class.java), - ), - segments = segments, - controlPriorityLevel = controlPriorityLevel, - segmentHighestImpact = segmentHighestImpact, - segmentHighestPriority = segmentHighestPriority, - lastControlDatetime = lastControlDatetime, - controlRateRiskFactor = controlRateRiskFactor, - numberControlsLastFiveYears = numberControlsLastFiveYears, - numberControlsLastThreeYears = numberControlsLastThreeYears, - numberInfractionsLastFiveYears = numberInfractionsLastFiveYears, - numberGearSeizuresLastFiveYears = numberGearSeizuresLastFiveYears, - numberSpeciesSeizuresLastFiveYears = numberSpeciesSeizuresLastFiveYears, - numberVesselSeizuresLastFiveYears = numberVesselSeizuresLastFiveYears, - ) + fun toVesselRiskFactor(mapper: ObjectMapper) = + VesselRiskFactor( + impactRiskFactor = impactRiskFactor, + probabilityRiskFactor = probabilityRiskFactor, + detectabilityRiskFactor = detectabilityRiskFactor, + riskFactor = riskFactor, + internalReferenceNumber = cfr, + gearOnboard = + mapper.readValue( + gearOnboard, + mapper.typeFactory + .constructCollectionType(MutableList::class.java, Gear::class.java), + ), + speciesOnboard = + mapper.readValue( + speciesOnboard, + mapper.typeFactory + .constructCollectionType(MutableList::class.java, Species::class.java), + ), + segments = segments, + controlPriorityLevel = controlPriorityLevel, + segmentHighestImpact = segmentHighestImpact, + segmentHighestPriority = segmentHighestPriority, + lastControlDatetime = lastControlDatetime, + controlRateRiskFactor = controlRateRiskFactor, + numberControlsLastFiveYears = numberControlsLastFiveYears, + numberControlsLastThreeYears = numberControlsLastThreeYears, + numberInfractionsLastFiveYears = numberInfractionsLastFiveYears, + numberGearSeizuresLastFiveYears = numberGearSeizuresLastFiveYears, + numberSpeciesSeizuresLastFiveYears = numberSpeciesSeizuresLastFiveYears, + numberVesselSeizuresLastFiveYears = numberVesselSeizuresLastFiveYears, + ) } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/VesselEntity.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/VesselEntity.kt index 9dedb88e71..6ec4820e31 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/VesselEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/VesselEntity.kt @@ -35,6 +35,7 @@ data class VesselEntity( val externalReferenceNumber: String? = null, @Column(name = "vessel_name") val vesselName: String? = null, + // ISO Alpha-2 country code @Column(name = "flag_state") val flagState: String? = null, @Column(name = "width") @@ -62,7 +63,6 @@ data class VesselEntity( val declaredFishingGears: List? = null, @Column(name = "nav_licence_expiration_date", columnDefinition = "date") val navigationLicenceExpirationDate: Date? = null, - @Column(name = "operator_name") val operatorName: String? = null, @Column(name = "operator_phones", columnDefinition = "varchar(100)[]") @@ -87,44 +87,45 @@ data class VesselEntity( @Column(name = "under_charter") val underCharter: Boolean? = null, ) { - - fun toVessel() = Vessel( - id = id, - internalReferenceNumber = internalReferenceNumber, - ircs = ircs, - mmsi = mmsi, - externalReferenceNumber = externalReferenceNumber, - vesselName = vesselName, - flagState = flagState?.let { - try { - CountryCode.valueOf(flagState) - } catch (e: IllegalArgumentException) { - logger.warn(e.message) - CountryCode.UNDEFINED - } - } ?: CountryCode.UNDEFINED, - width = width, - length = length, - district = district, - districtCode = districtCode, - gauge = gauge, - registryPort = registryPort, - power = power, - vesselType = vesselType, - sailingCategory = sailingCategory, - sailingType = sailingType, - declaredFishingGears = declaredFishingGears, - navigationLicenceExpirationDate = navigationLicenceExpirationDate, - operatorName = operatorName, - operatorPhones = operatorPhones, - operatorEmail = operatorEmail, - proprietorName = proprietorName, - proprietorPhones = proprietorPhones, - proprietorEmails = proprietorEmails, - vesselPhones = vesselPhones, - vesselEmails = vesselEmails, - underCharter = underCharter, - ) + fun toVessel() = + Vessel( + id = id, + internalReferenceNumber = internalReferenceNumber, + ircs = ircs, + mmsi = mmsi, + externalReferenceNumber = externalReferenceNumber, + vesselName = vesselName, + flagState = + flagState?.let { + try { + CountryCode.valueOf(flagState) + } catch (e: IllegalArgumentException) { + logger.warn(e.message) + CountryCode.UNDEFINED + } + } ?: CountryCode.UNDEFINED, + width = width, + length = length, + district = district, + districtCode = districtCode, + gauge = gauge, + registryPort = registryPort, + power = power, + vesselType = vesselType, + sailingCategory = sailingCategory, + sailingType = sailingType, + declaredFishingGears = declaredFishingGears, + navigationLicenceExpirationDate = navigationLicenceExpirationDate, + operatorName = operatorName, + operatorPhones = operatorPhones, + operatorEmail = operatorEmail, + proprietorName = proprietorName, + proprietorPhones = proprietorPhones, + proprietorEmails = proprietorEmails, + vesselPhones = vesselPhones, + vesselEmails = vesselEmails, + underCharter = underCharter, + ) companion object { private val logger: Logger = LoggerFactory.getLogger(VesselEntity::class.java) 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 3a4361d897..43033ee18a 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 @@ -42,6 +42,7 @@ class JpaLogbookReportRepository( return Specification { root, _, criteriaBuilder -> val vessel: Join = root.join("vessel") + // TODO Double-check if it's < 12 VS >= 12. if (isLessThanTwelveMetersVessel) { criteriaBuilder.lessThan(vessel.get("length"), 12) } else { diff --git a/backend/src/main/resources/db/testdata/V666.11__Insert_risk_factors.sql b/backend/src/main/resources/db/testdata/V666.11__Insert_risk_factors.sql index 962b8e2d45..2fdf7066df 100644 --- a/backend/src/main/resources/db/testdata/V666.11__Insert_risk_factors.sql +++ b/backend/src/main/resources/db/testdata/V666.11__Insert_risk_factors.sql @@ -1,62 +1,6 @@ -insert into risk_factors (cfr, - impact_risk_factor, - probability_risk_factor, - detectability_risk_factor, - risk_factor, - last_logbook_message_datetime_utc, - departure_datetime_utc, - trip_number, - gear_onboard, - species_onboard, - segments, - total_weight_onboard, - control_priority_level, - segment_highest_impact, - segment_highest_priority, - vessel_id, - ircs, - external_immatriculation, - last_control_datetime_utc, - last_control_infraction, - post_control_comments, - number_recent_controls, - control_rate_risk_factor, - infraction_score, - infraction_rate_risk_factor, - number_controls_last_5_years, - number_controls_last_3_years, - number_infractions_last_5_years, - number_gear_seizures_last_5_years, - number_species_seizures_last_5_years, - number_vessel_seizures_last_5_years) -values ('FAK000999999', - 2.1, - 2, - 3, - 2.473, - CURRENT_DATE, - CURRENT_DATE, - 123456, - '[{"gear": "OTB", "mesh": 70.0, "dimensions": 45.0}]', - '[{ "gear": "OTB","faoZone": "27.8.b","species": "BLI","weight": 13.46 },{ "gear": "OTB","faoZone": "27.8.c","species": "HKE","weight": 235.6 },{ "gear": "OTB","faoZone": "27.8.b","species": "HKE","weight": 235.6 }]', - '{"NWW10", "PEL 03"}', - 1235.36, - 2.56, - 'NWW10', - 'PEL 03', - 1, - 'CALLME', - '', - CURRENT_DATE, - true, - '', - 0, - 3.8, - NULL, - 2.56, - 8, - 1, - 5, - 4, - 3, - 2); +-- /!\ This file is automatically generated by a local script. +-- Do NOT update it directly, update the associated .jsonc file. + +INSERT INTO risk_factors (cfr, control_priority_level, control_rate_risk_factor, departure_datetime_utc, detectability_risk_factor, external_immatriculation, impact_risk_factor, infraction_rate_risk_factor, infraction_score, ircs, last_control_datetime_utc, last_control_infraction, last_logbook_message_datetime_utc, number_controls_last_3_years, number_controls_last_5_years, number_gear_seizures_last_5_years, number_infractions_last_5_years, number_recent_controls, number_species_seizures_last_5_years, number_vessel_seizures_last_5_years, post_control_comments, probability_risk_factor, risk_factor, segment_highest_impact, segment_highest_priority, segments, total_weight_onboard, trip_number, vessel_id, gear_onboard, species_onboard) VALUES ('FAK000999999', 2.56, 3.8, CURRENT_DATE, 3, '', 2.1, 2.56, NULL, 'CALLME', CURRENT_DATE, true, CURRENT_DATE, 1, 8, 4, 5, 0, 3, 2, '', 2, 2.473, 'NWW10', 'PEL 03', '{"NWW10", "PEL 03"}', 1235.36, 123456, 1, '[{"gear":"OTB","mesh":70,"dimensions":45}]', '[{"gear":"OTB","faoZone":"27.8.b","species":"BLI","weight":13.46},{"gear":"OTB","faoZone":"27.8.c","species":"HKE","weight":235.6},{"gear":"OTB","faoZone":"27.8.b","species":"HKE","weight":235.6}]'); + +INSERT INTO risk_factors (cfr, control_priority_level, control_rate_risk_factor, departure_datetime_utc, detectability_risk_factor, external_immatriculation, impact_risk_factor, infraction_rate_risk_factor, infraction_score, ircs, last_control_datetime_utc, last_control_infraction, last_logbook_message_datetime_utc, number_controls_last_3_years, number_controls_last_5_years, number_gear_seizures_last_5_years, number_infractions_last_5_years, number_recent_controls, number_species_seizures_last_5_years, number_vessel_seizures_last_5_years, post_control_comments, probability_risk_factor, risk_factor, segment_highest_impact, segment_highest_priority, segments, total_weight_onboard, trip_number, vessel_id, gear_onboard, species_onboard) VALUES ('CFR101', 4, 5, NOW() - INTERVAL '1 day', 5, '', 4, 3, NULL, 'IRCS101', '2023-01-01T00:00:00', true, NOW(), 0, 0, 4, 5, 0, 3, 2, '', 4, 4, 'NWW10', 'PEL 03', '{"NWW10", "PEL 03"}', 12345.67, 123102, 101, '[{"gear":"OTB","mesh":70,"dimensions":45}]', '[{"gear":"OTB","faoZone":"27.8.b","species":"BLI","weight":13.46},{"gear":"OTB","faoZone":"27.8.c","species":"HKE","weight":235.6},{"gear":"OTB","faoZone":"27.8.b","species":"HKE","weight":235.6}]'); diff --git a/backend/src/main/resources/db/testdata/V666.2__Insert_dummy_vessels.sql b/backend/src/main/resources/db/testdata/V666.2.0__Insert_dummy_vessels.sql similarity index 100% rename from backend/src/main/resources/db/testdata/V666.2__Insert_dummy_vessels.sql rename to backend/src/main/resources/db/testdata/V666.2.0__Insert_dummy_vessels.sql 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 new file mode 100644 index 0000000000..e0340d68dc --- /dev/null +++ b/backend/src/main/resources/db/testdata/V666.2.1__Insert_more_dummy_vessels.sql @@ -0,0 +1,4 @@ +-- /!\ This file is automatically generated by a local script. +-- Do NOT update it directly, update the associated .jsonc file. + +INSERT INTO vessels (id, cfr, mmsi, ircs, external_immatriculation, vessel_name, flag_state, length, under_charter) VALUES (101, 'CFR101', 'MMSI101', 'IRCS101', 'EXTIMM101', 'VIVA ESPANA', 'ES', 15, 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 399499b8cf..3999ad5fcc 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 @@ -25,16 +25,21 @@ INSERT INTO logbook_raw_messages (operation_number) VALUES ('FAKE_OPERATION_111' INSERT INTO logbook_raw_messages (operation_number) VALUES ('FAKE_OPERATION_112'); -INSERT INTO logbook_reports (id, cfr, enriched, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_id, vessel_name, trip_gears, trip_segments, value) VALUES (101, 'FAK000999999', true, 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', 'ERS', 1, 'PHENOMENE', '[{"gear":"GTR","mesh":100,"dimensions":"250;180"},{"gear":"GTR","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"NWW01","segment_name":"Chalutiers de fond"},{"segment":"PEL01","segment_name":"Chalutiers pélagiques"}]', '{"catchOnboard":[{"weight":25,"nbFish":null,"species":"SOL","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"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}'); +INSERT INTO logbook_reports (id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_id, vessel_name, trip_gears, trip_segments, value) VALUES (101, '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', 'ERS', 1, 'PHENOMENE', '[{"gear":"GTR","mesh":100,"dimensions":"250;180"},{"gear":"GTR","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"NWW01","segment_name":"Chalutiers de fond"},{"segment":"PEL01","segment_name":"Chalutiers pélagiques"}]', '{"catchOnboard":[{"weight":25,"nbFish":null,"species":"SOL","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"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 '4 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 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, cfr, enriched, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_id, vessel_name, trip_gears, trip_segments, value) VALUES (102, 'ABC000042310', true, 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', 10, 'COURANT MAIN PROFESSEUR', '[{"gear":"GTR","mesh":100,"dimensions":"250;180"},{"gear":"GTR","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"NWW01","segment_name":"Chalutiers de fond"},{"segment":"PEL01","segment_name":"Chalutiers pélagiques"}]', '{"catchOnboard":[{"weight":25,"nbFish":null,"species":"SOL","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"pnoTypes":[{"pnoTypeName":"Préavis type C","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"AEFRP","predictedArrivalDatetimeUtc":null,"predictedLandingDatetimeUtc":null,"purpose":"LAN","tripStartDate":null}'); +INSERT INTO logbook_reports (id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_id, vessel_name, trip_gears, trip_segments, value) VALUES (102, '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', 10, 'COURANT MAIN PROFESSEUR', '[{"gear":"GTR","mesh":100,"dimensions":"250;180"},{"gear":"GTR","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"NWW01","segment_name":"Chalutiers de fond"},{"segment":"PEL01","segment_name":"Chalutiers pélagiques"}]', '{"catchOnboard":[{"weight":25,"nbFish":null,"species":"SOL","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"pnoTypes":[{"pnoTypeName":"Préavis type C","minimumNotificationPeriod":4,"hasDesignatedPorts":false}],"port":"AEFRP","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, enriched, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_id, trip_gears, trip_segments, value) VALUES (103, true, NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_103', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', -1, '[]', '[]', '{"catchOnboard":[],"pnoTypes":[],"port":"AEHZP","predictedArrivalDatetimeUtc":null,"purpose":"GRD","tripStartDate":null}'); +INSERT INTO logbook_reports (id, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_id, trip_gears, trip_segments, value) VALUES (103, true, NULL, NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'PNO', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'FAKE_OPERATION_103', 'DAT', NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes', 'ERS', -1, '[]', '[]', '{"catchOnboard":[],"pnoTypes":[],"port":"AEHZP","predictedArrivalDatetimeUtc":null,"purpose":"GRD","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 = 103; 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 = 103; + +INSERT INTO logbook_reports (id, cfr, enriched, flag_state, integration_datetime_utc, log_type, operation_datetime_utc, operation_number, operation_type, report_datetime_utc, transmission_format, vessel_id, vessel_name, trip_gears, trip_segments, value) VALUES (104, 'FAK000999999', 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', 101, 'VIVA ESPANA', '[{"gear":"GTR","mesh":100,"dimensions":"250;180"},{"gear":"GTR","mesh":120.5,"dimensions":"250;280"}]', '[{"segment":"NWW01","segment_name":"Chalutiers de fond"},{"segment":"PEL01","segment_name":"Chalutiers pélagiques"}]', '{"catchOnboard":[{"weight":25,"nbFish":null,"species":"SOL","faoZone":"27.8.a","effortZone":"C","economicZone":"FRA","statisticalRectangle":"23E6"}],"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 '4 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 '3 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; diff --git a/backend/src/main/resources/db/testdata/json/V666.11__Insert_risk_factors.jsonc b/backend/src/main/resources/db/testdata/json/V666.11__Insert_risk_factors.jsonc new file mode 100644 index 0000000000..9387668f14 --- /dev/null +++ b/backend/src/main/resources/db/testdata/json/V666.11__Insert_risk_factors.jsonc @@ -0,0 +1,127 @@ +[ + { + "table": "risk_factors", + "data": [ + // - Vessel: PHENOMENE + { + "cfr": "FAK000999999", + "control_priority_level": 2.56, + "control_rate_risk_factor": 3.8, + "departure_datetime_utc:sql": "CURRENT_DATE", + "detectability_risk_factor": 3, + "external_immatriculation": "", + "impact_risk_factor": 2.1, + "infraction_rate_risk_factor": 2.56, + "infraction_score": null, + "ircs": "CALLME", + "last_control_datetime_utc:sql": "CURRENT_DATE", + "last_control_infraction": true, + "last_logbook_message_datetime_utc:sql": "CURRENT_DATE", + "number_controls_last_3_years": 1, + "number_controls_last_5_years": 8, + "number_gear_seizures_last_5_years": 4, + "number_infractions_last_5_years": 5, + "number_recent_controls": 0, + "number_species_seizures_last_5_years": 3, + "number_vessel_seizures_last_5_years": 2, + "post_control_comments": "", + "probability_risk_factor": 2, + "risk_factor": 2.473, + "segment_highest_impact": "NWW10", + "segment_highest_priority": "PEL 03", + "segments": ["NWW10", "PEL 03"], + "total_weight_onboard": 1235.36, + "trip_number": 123456, + "vessel_id": 1, + "gear_onboard:jsonb": [ + { + "gear": "OTB", + "mesh": 70.0, + "dimensions": 45.0 + } + ], + "species_onboard:jsonb": [ + { + "gear": "OTB", + "faoZone": "27.8.b", + "species": "BLI", + "weight": 13.46 + }, + { + "gear": "OTB", + "faoZone": "27.8.c", + "species": "HKE", + "weight": 235.6 + }, + { + "gear": "OTB", + "faoZone": "27.8.b", + "species": "HKE", + "weight": 235.6 + } + ] + }, + + // - Vessel: VIVA ESPANA + // - Last control date: 2023-01-01 + { + "cfr": "CFR101", + "control_priority_level": 4, + "control_rate_risk_factor": 5, + "departure_datetime_utc:sql": "NOW() - INTERVAL '1 day'", + "detectability_risk_factor": 5, + "external_immatriculation": "", + "impact_risk_factor": 4, + "infraction_rate_risk_factor": 3, + "infraction_score": null, + "ircs": "IRCS101", + "last_control_datetime_utc": "2023-01-01T00:00:00", + "last_control_infraction": true, + "last_logbook_message_datetime_utc:sql": "NOW()", + "number_controls_last_3_years": 0, + "number_controls_last_5_years": 0, + "number_gear_seizures_last_5_years": 4, + "number_infractions_last_5_years": 5, + "number_recent_controls": 0, + "number_species_seizures_last_5_years": 3, + "number_vessel_seizures_last_5_years": 2, + "post_control_comments": "", + "probability_risk_factor": 4, + "risk_factor": 4, + "segment_highest_impact": "NWW10", + "segment_highest_priority": "PEL 03", + "segments": ["NWW10", "PEL 03"], + "total_weight_onboard": 12345.67, + "trip_number": 123102, + "vessel_id": 101, + "gear_onboard:jsonb": [ + { + "gear": "OTB", + "mesh": 70.0, + "dimensions": 45.0 + } + ], + "species_onboard:jsonb": [ + { + "gear": "OTB", + "faoZone": "27.8.b", + "species": "BLI", + "weight": 13.46 + }, + { + "gear": "OTB", + "faoZone": "27.8.c", + "species": "HKE", + "weight": 235.6 + }, + { + "gear": "OTB", + "faoZone": "27.8.b", + "species": "HKE", + "weight": 235.6 + } + ] + } + ] + } +] 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 new file mode 100644 index 0000000000..91fea14841 --- /dev/null +++ b/backend/src/main/resources/db/testdata/json/V666.2.1__Insert_more_dummy_vessels.jsonc @@ -0,0 +1,20 @@ +[ + { + "table": "vessels", + "data": [ + // - Vessel: VIVA ESPANA + // - Flag state: ES + { + "id": 101, + "cfr": "CFR101", + "mmsi": "MMSI101", + "ircs": "IRCS101", + "external_immatriculation": "EXTIMM101", + "vessel_name": "VIVA ESPANA", + "flag_state": "ES", + "length": 15, + "under_charter": false + } + ] + } +] 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 1682822ff3..1dc2b47d0f 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 @@ -26,6 +26,7 @@ "id": 101, "cfr": "FAK000999999", "enriched": true, + "flag_state": "FRA", "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", "log_type": "PNO", "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", @@ -82,6 +83,7 @@ "id": 102, "cfr": "ABC000042310", "enriched": true, + "flag_state": "FRA", "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", "log_type": "PNO", "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", @@ -132,6 +134,7 @@ { "id": 103, "enriched": true, + "flag_state": null, "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", "log_type": "PNO", "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", @@ -150,6 +153,63 @@ "purpose": "GRD", "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" } + }, + + // - Vessel: VIVA ESPANA + // - Purpose: LAN + // - Without reporting + { + "id": 104, + "cfr": "FAK000999999", + "enriched": true, + "flag_state": "ESP", + "integration_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", + "log_type": "PNO", + "operation_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", + "operation_number": "FAKE_OPERATION_104", + "operation_type": "DAT", + "report_datetime_utc:sql": "NOW() AT TIME ZONE 'UTC' - INTERVAL '15 minutes'", + "transmission_format": "ERS", + "vessel_id": 101, + "vessel_name": "VIVA ESPANA", + "trip_gears:jsonb": [ + { "gear": "GTR", "mesh": 100, "dimensions": "250;180" }, + { "gear": "GTR", "mesh": 120.5, "dimensions": "250;280" } + ], + "trip_segments:jsonb": [ + { "segment": "NWW01", "segment_name": "Chalutiers de fond" }, + { "segment": "PEL01", "segment_name": "Chalutiers pélagiques" } + ], + "value:jsonb": { + "catchOnboard": [ + { + "weight": 25.0, + "nbFish": null, + "species": "SOL", + "faoZone": "27.8.a", + "effortZone": "C", + "economicZone": "FRA", + "statisticalRectangle": "23E6" + } + ], + "pnoTypes": [ + { + "pnoTypeName": "Préavis type A", + "minimumNotificationPeriod": 4.0, + "hasDesignatedPorts": false + }, + { + "pnoTypeName": "Préavis type B", + "minimumNotificationPeriod": 8.0, + "hasDesignatedPorts": true + } + ], + "port": "FRSML", + "predictedArrivalDatetimeUtc:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '4 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')", + "predictedLandingDatetimeUtc:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' + INTERVAL '3 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')", + "purpose": "LAN", + "tripStartDate:sql": "TO_CHAR(NOW() AT TIME ZONE 'UTC' - INTERVAL '10 hours', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"')" + } } ] } diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookRawMessageRepositoryITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookRawMessageRepositoryITests.kt index 2c84465f4e..e2e66b5043 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookRawMessageRepositoryITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/JpaLogbookRawMessageRepositoryITests.kt @@ -2,8 +2,8 @@ package fr.gouv.cnsp.monitorfish.infrastructure.database.repositories import fr.gouv.cnsp.monitorfish.config.MapperConfiguration import fr.gouv.cnsp.monitorfish.domain.exceptions.NoERSMessagesFound +import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired @@ -13,7 +13,6 @@ import org.springframework.transaction.annotation.Transactional @Import(MapperConfiguration::class) class JpaLogbookRawMessageRepositoryITests : AbstractDBTests() { - @Autowired private lateinit var jpaLogbookRawMessageRepository: JpaLogbookRawMessageRepository @@ -114,7 +113,7 @@ class JpaLogbookRawMessageRepositoryITests : AbstractDBTests() { @Transactional fun `findRawMessage Should throw an exception When the message is not found`() { // When - val throwable = catchThrowable { jpaLogbookRawMessageRepository.findRawMessage("BAD_OP") } + val throwable = Assertions.catchThrowable { jpaLogbookRawMessageRepository.findRawMessage("BAD_OP") } // Then assertThat(throwable).isInstanceOf(NoERSMessagesFound::class.java) 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 a439cf6289..daeb081401 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 @@ -6,10 +6,10 @@ 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.messages.* import fr.gouv.cnsp.monitorfish.domain.exceptions.NoLogbookFishingTripFound +import fr.gouv.cnsp.monitorfish.domain.filters.LogbookReportFilter import fr.gouv.cnsp.monitorfish.domain.use_cases.TestUtils import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable -import org.hibernate.query.sqm.TemporalUnit import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -24,7 +24,6 @@ import java.time.ZonedDateTime @Import(MapperConfiguration::class) @SpringBootTest(properties = ["monitorfish.scheduling.enable=false"]) class JpaLogbookReportRepositoryITests : AbstractDBTests() { - @Autowired private lateinit var jpaLogbookReportRepository: JpaLogbookReportRepository @@ -81,9 +80,10 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findLastTripBefore Should throw an exception When no parameter is given`() { // When - val throwable = catchThrowable { - jpaLogbookReportRepository.findLastTripBeforeDateTime("", ZonedDateTime.now()) - } + val throwable = + catchThrowable { + jpaLogbookReportRepository.findLastTripBeforeDateTime("", ZonedDateTime.now()) + } // Then assertThat(throwable).isInstanceOf(NoLogbookFishingTripFound::class.java) @@ -94,12 +94,13 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findLastTripBefore Should throw an exception When the vessel could not be found`() { // When - val throwable = catchThrowable { - jpaLogbookReportRepository.findLastTripBeforeDateTime( - "ARGH", - ZonedDateTime.now(), - ) - } + val throwable = + catchThrowable { + jpaLogbookReportRepository.findLastTripBeforeDateTime( + "ARGH", + ZonedDateTime.now(), + ) + } // Then assertThat(throwable).isInstanceOf(NoLogbookFishingTripFound::class.java) @@ -110,10 +111,11 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findTripBeforeTripNumber Should return the previous trip number When there is an overlap between the current and previous trip`() { // When - val secondTrip = jpaLogbookReportRepository.findTripBeforeTripNumber( - "FAK000999999", - "9463714", - ) + val secondTrip = + jpaLogbookReportRepository.findTripBeforeTripNumber( + "FAK000999999", + "9463714", + ) // Then assertThat(secondTrip.tripNumber).isEqualTo("9463713") @@ -125,12 +127,13 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findTripBeforeTripNumber Should return an exception When the current trip number is invalid`() { // When - val throwable = catchThrowable { - jpaLogbookReportRepository.findTripBeforeTripNumber( - "FAK000999999", - "9463712", - ) - } + val throwable = + catchThrowable { + jpaLogbookReportRepository.findTripBeforeTripNumber( + "FAK000999999", + "9463712", + ) + } // Then assertThat(throwable).isInstanceOf(NoLogbookFishingTripFound::class.java) @@ -141,10 +144,11 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findTripBeforeTripNumber Should return the previous trip number When there is no overlap between the current and previous trip`() { // When - val secondTrip = jpaLogbookReportRepository.findTripBeforeTripNumber( - "FAK000999999", - "9463715", - ) + val secondTrip = + jpaLogbookReportRepository.findTripBeforeTripNumber( + "FAK000999999", + "9463715", + ) // Then assertThat(secondTrip.tripNumber).isEqualTo("9463714") @@ -156,10 +160,11 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findTripAfterTripNumber Should return the next trip number When there is an overlap between the current and previous trip`() { // When - val secondTrip = jpaLogbookReportRepository.findTripAfterTripNumber( - "FAK000999999", - "9463713", - ) + val secondTrip = + jpaLogbookReportRepository.findTripAfterTripNumber( + "FAK000999999", + "9463713", + ) // Then assertThat(secondTrip.tripNumber).isEqualTo("9463714") @@ -171,10 +176,11 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findTripAfterTripNumber Should return the next trip number When there is no overlap between the current and previous trip`() { // When - val secondTrip = jpaLogbookReportRepository.findTripAfterTripNumber( - "FAK000999999", - "9463714", - ) + val secondTrip = + jpaLogbookReportRepository.findTripAfterTripNumber( + "FAK000999999", + "9463714", + ) // Then assertThat(secondTrip.tripNumber).isEqualTo("9463715") @@ -186,12 +192,13 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findTripAfterTripNumber Should throw an exception When there is no next trip found`() { // When - val throwable = catchThrowable { - jpaLogbookReportRepository.findTripAfterTripNumber( - "FAK000999999", - "9463715", - ) - } + val throwable = + catchThrowable { + jpaLogbookReportRepository.findTripAfterTripNumber( + "FAK000999999", + "9463715", + ) + } // Then assertThat(throwable).isInstanceOf(NoLogbookFishingTripFound::class.java) @@ -206,8 +213,9 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { val now = ZonedDateTime.now() // When - val messages = jpaLogbookReportRepository - .findAllMessagesByTripNumberBetweenDates("FAK000999999", lastDepartureDate, now, "9463715") + val messages = + jpaLogbookReportRepository + .findAllMessagesByTripNumberBetweenDates("FAK000999999", lastDepartureDate, now, "9463715") // Then assertThat(messages).hasSize(20) @@ -391,8 +399,9 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { val beforeDate = ZonedDateTime.of(2019, 10, 11, 9, 4, 0, 0, UTC) // When - val messages = jpaLogbookReportRepository - .findAllMessagesByTripNumberBetweenDates("FAK000999999", afterDate, beforeDate, "9463715") + val messages = + jpaLogbookReportRepository + .findAllMessagesByTripNumberBetweenDates("FAK000999999", afterDate, beforeDate, "9463715") // Then assertThat(messages).hasSize(2) @@ -489,10 +498,11 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findFirstAcknowledgedDateOfTripBeforeDateTime Should return the last acknowledged message date When transmission format is ERS`() { // When - val lastTrip = jpaLogbookReportRepository.findFirstAcknowledgedDateOfTripBeforeDateTime( - "FAK000999999", - ZonedDateTime.now(), - ) + val lastTrip = + jpaLogbookReportRepository.findFirstAcknowledgedDateOfTripBeforeDateTime( + "FAK000999999", + ZonedDateTime.now(), + ) // Then assertThat(lastTrip.toString()).isEqualTo("2019-10-17T11:32Z") @@ -502,10 +512,11 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findFirstAcknowledgedDateOfTripBeforeDateTime Should return the last acknowledged message date When transmission format is FLUX`() { // When - val lastTrip = jpaLogbookReportRepository.findFirstAcknowledgedDateOfTripBeforeDateTime( - "SOCR4T3", - ZonedDateTime.now(), - ) + val lastTrip = + jpaLogbookReportRepository.findFirstAcknowledgedDateOfTripBeforeDateTime( + "SOCR4T3", + ZonedDateTime.now(), + ) // Then assertThat(lastTrip.toString()).isEqualTo("2020-05-06T18:39:33Z") @@ -515,12 +526,13 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findFirstAcknowledgedDateOfTripBeforeDateTime Should throw a custom exception When the findFirstAcknowledgedDateOfTrip request is empty`() { // When - val throwable = catchThrowable { - jpaLogbookReportRepository.findFirstAcknowledgedDateOfTripBeforeDateTime( - "UNKNOWN_VESS", - ZonedDateTime.parse("2018-02-17T01:06:00Z"), - ) - } + val throwable = + catchThrowable { + jpaLogbookReportRepository.findFirstAcknowledgedDateOfTripBeforeDateTime( + "UNKNOWN_VESS", + ZonedDateTime.parse("2018-02-17T01:06:00Z"), + ) + } // Then assertThat(throwable).isInstanceOf(NoLogbookFishingTripFound::class.java) @@ -531,9 +543,10 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findLastTwoYearsTripNumbers Should return an empty list When no trip is found`() { // When - val trips = jpaLogbookReportRepository.findLastTwoYearsTripNumbers( - "UNKNOWN_VESS", - ) + val trips = + jpaLogbookReportRepository.findLastTwoYearsTripNumbers( + "UNKNOWN_VESS", + ) // Then assertThat(trips).isEmpty() @@ -543,10 +556,11 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { @Transactional fun `findLastTwoYearsTripNumbers Should return the last trips`() { // Given - val rawMessages = listOf( - LogbookRawMessage("FPXE1546546114565"), - LogbookRawMessage("FPXE1546545654481"), - ) + val rawMessages = + listOf( + LogbookRawMessage("FPXE1546546114565"), + LogbookRawMessage("FPXE1546545654481"), + ) jpaLogbookRawMessageRepository.save(rawMessages.first()) jpaLogbookRawMessageRepository.save(rawMessages.last()) @@ -573,11 +587,67 @@ class JpaLogbookReportRepositoryITests : AbstractDBTests() { ) // When - val trips = jpaLogbookReportRepository.findLastTwoYearsTripNumbers( - "FAK000999999", - ) + val trips = + jpaLogbookReportRepository.findLastTwoYearsTripNumbers( + "FAK000999999", + ) // Then assertThat(trips).isEqualTo(listOf("456", "123")) } + + @Test + @Transactional + fun `findAllPriorNotifications Should return PNO logbook reports from ESP & FRA vessels`() { + val filter = LogbookReportFilter(flagStates = listOf("ESP", "FRA")) + + val result = jpaLogbookReportRepository.findAllPriorNotifications(filter) + + assertThat(result).hasSizeGreaterThan(0) + assertThat(result.all { listOf("ES", "FR").contains(it.vesselFlagCountryCode) }).isEqualTo(true) + } + + @Test + @Transactional + fun `findAllPriorNotifications Should return PNO logbook reports for less than 12 meters long vessels`() { + val firstFilter = LogbookReportFilter(isLessThanTwelveMetersVessel = true) + + val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + + assertThat(firstResult).hasSizeGreaterThan(0) + assertThat(firstResult.all { it.vesselLength!! < 12 }).isEqualTo(true) + + val secondFilter = LogbookReportFilter(isLessThanTwelveMetersVessel = false) + + val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + + assertThat(secondResult).hasSizeGreaterThan(0) + assertThat(secondResult.all { it.vesselLength!! >= 12 }).isEqualTo(true) + } + + @Test + @Transactional + fun `findAllPriorNotifications Should return PNO logbook reports controlled after or before January 1st, 2024`() { + val firstFilter = LogbookReportFilter(lastControlledAfter = "2024-01-01T00:00:00Z") + + val firstResult = jpaLogbookReportRepository.findAllPriorNotifications(firstFilter) + + assertThat(firstResult).hasSizeGreaterThan(0) + assertThat( + firstResult.all { + ZonedDateTime.parse(it.vesselLastControlDate!!).isAfter(ZonedDateTime.parse("2024-01-01T00:00:00Z")) + }, + ).isEqualTo(true) + + val secondFilter = LogbookReportFilter(lastControlledBefore = "2024-01-01T00:00:00Z") + + val secondResult = jpaLogbookReportRepository.findAllPriorNotifications(secondFilter) + + assertThat(secondResult).hasSizeGreaterThan(0) + assertThat( + secondResult.all { + ZonedDateTime.parse(it.vesselLastControlDate!!).isBefore(ZonedDateTime.parse("2024-01-01T00:00:00Z")) + }, + ).isEqualTo(true) + } } diff --git a/frontend/cypress/mappings/delete-control_unit_contacts-*.v1.json b/frontend/cypress/mappings/delete-control_unit_contacts-*.v1.json deleted file mode 100644 index e020f7c36f..0000000000 --- a/frontend/cypress/mappings/delete-control_unit_contacts-*.v1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "request": { - "method": "DELETE", - "urlPattern": "/api/v1/control_unit_contacts/[0-9]+" - }, - "response": { - "status": 200, - "headers": { - "Access-Control-Allow-Headers": "*", - "Access-Control-Allow-Methods": "*", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers": "*", - "Content-Type": "application/json" - }, - "jsonBody": {} - } -} diff --git a/frontend/cypress/mappings/delete-control_unit_resources-*.v1.json b/frontend/cypress/mappings/delete-control_unit_resources-*.v1.json deleted file mode 100644 index 925d9e4ee5..0000000000 --- a/frontend/cypress/mappings/delete-control_unit_resources-*.v1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "request": { - "method": "DELETE", - "urlPattern": "/api/v1/control_unit_resources/[0-9]+" - }, - "response": { - "status": 200, - "headers": { - "Access-Control-Allow-Headers": "*", - "Access-Control-Allow-Methods": "*", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers": "*", - "Content-Type": "application/json" - }, - "jsonBody": {} - } -} diff --git a/frontend/cypress/mappings/get-control_unit_resources-*-can_delete.v1.json b/frontend/cypress/mappings/get-control_unit_resources-*-can_delete.v1.json deleted file mode 100644 index ec1c418b0c..0000000000 --- a/frontend/cypress/mappings/get-control_unit_resources-*-can_delete.v1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "request": { - "method": "GET", - "urlPattern": "/api/v1/control_unit_resources/[0-9]+/can_delete" - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Methods": "*" - }, - "jsonBody": { - "value": true - } - } -} diff --git a/frontend/cypress/mappings/put-control_unit_contacts-*.v1.json b/frontend/cypress/mappings/put-control_unit_contacts-*.v1.json deleted file mode 100644 index 10e9465a37..0000000000 --- a/frontend/cypress/mappings/put-control_unit_contacts-*.v1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "request": { - "method": "PUT", - "urlPattern": "/api/v1/control_unit_contacts/[0-9]+" - }, - "response": { - "status": 200, - "headers": { - "Access-Control-Allow-Headers": "*", - "Access-Control-Allow-Methods": "*", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers": "*", - "Content-Type": "application/json" - }, - "jsonBody": {} - } -} diff --git a/frontend/cypress/mappings/put-control_unit_resources-*.v1.json b/frontend/cypress/mappings/put-control_unit_resources-*.v1.json deleted file mode 100644 index 47caef9cba..0000000000 --- a/frontend/cypress/mappings/put-control_unit_resources-*.v1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "request": { - "method": "PUT", - "urlPattern": "/api/v1/control_unit_resources/[0-9]+" - }, - "response": { - "status": 200, - "headers": { - "Access-Control-Allow-Headers": "*", - "Access-Control-Allow-Methods": "*", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers": "*", - "Content-Type": "application/json" - }, - "jsonBody": {} - } -} diff --git a/frontend/cypress/mappings/put-control_units-*.v1.json b/frontend/cypress/mappings/put-control_units-*.v1.json deleted file mode 100644 index 802fbfa9b1..0000000000 --- a/frontend/cypress/mappings/put-control_units-*.v1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "request": { - "method": "PUT", - "urlPattern": "/api/v2/control_units/[0-9]+" - }, - "response": { - "status": 200, - "headers": { - "Access-Control-Allow-Headers": "*", - "Access-Control-Allow-Methods": "*", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers": "*", - "Content-Type": "application/json" - }, - "jsonBody": {} - } -} diff --git a/frontend/scripts/generate_test_data_seeds.mjs b/frontend/scripts/generate_test_data_seeds.mjs index 87e2f22e51..c0cb8428de 100644 --- a/frontend/scripts/generate_test_data_seeds.mjs +++ b/frontend/scripts/generate_test_data_seeds.mjs @@ -47,17 +47,22 @@ function generateInsertStatement(row, table) { sqlColumns.push(sqlColumn) sqlValues.push(sqlValue) + } else if (Array.isArray(value)) { + const valueAsSqlArray = `'{"${value.map(valueItem => valueItem.replace(/'/g, "''")).join('", "')}"}'` + + sqlColumns.push(sqlColumn) + sqlValues.push(valueAsSqlArray) + } else if (value === null) { + sqlColumns.push(sqlColumn) + sqlValues.push('NULL') + } else if (typeof value !== 'string' || key.endsWith(':sql')) { + sqlColumns.push(sqlColumn) + sqlValues.push(value) } else { - const processedValue = - // eslint-disable-next-line no-nested-ternary - value === null - ? 'null' - : typeof value !== 'string' || key.endsWith(':sql') - ? value - : `'${value.replace(/'/g, "''")}'` + const valueAsSqlString = `'${value.replace(/'/g, "''")}'` sqlColumns.push(sqlColumn) - sqlValues.push(processedValue) + sqlValues.push(valueAsSqlString) } }