diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegments.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegments.kt index 01978f6de4..cc758e600c 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegments.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegments.kt @@ -8,8 +8,6 @@ import fr.gouv.cnsp.monitorfish.domain.repositories.FleetSegmentRepository import fr.gouv.cnsp.monitorfish.domain.repositories.VesselRepository import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.dtos.SpeciesCatchForSegmentCalculation import org.slf4j.LoggerFactory -import java.time.Clock -import java.time.ZonedDateTime /** * Return the computed fleet segments from the species catches. @@ -18,19 +16,18 @@ import java.time.ZonedDateTime class ComputeFleetSegments( private val fleetSegmentRepository: FleetSegmentRepository, private val vesselRepository: VesselRepository, - private val clock: Clock, ) { private val logger = LoggerFactory.getLogger(ComputeFleetSegments::class.java) fun execute( + year: Int, vesselId: Int, speciesCatches: List, ): List { logger.info("Got ${speciesCatches.size} catches to assign fleet segments") - val currentYear = ZonedDateTime.now(clock).year val vesselType = vesselRepository.findVesselById(vesselId)?.vesselType - val fleetSegments = fleetSegmentRepository.findAllByYear(currentYear) + val fleetSegments = fleetSegmentRepository.findAllByYear(year) val controlledPelagicSpeciesWeight = speciesCatches diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsFromControl.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsFromControl.kt index b38fc85275..86516322e4 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsFromControl.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsFromControl.kt @@ -19,11 +19,12 @@ class ComputeFleetSegmentsFromControl( faoAreas: List, gears: List, species: List, + year: Int, ): List { val allSpecies = speciesRepository.findAll() val speciesCatches = getSpeciesCatchesForSegmentCalculation(faoAreas, gears, species, allSpecies) - return computeFleetSegments.execute(vesselId, speciesCatches) + return computeFleetSegments.execute(year, vesselId, speciesCatches) } } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/ComputeManualPriorNotification.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/ComputeManualPriorNotification.kt index c45f1e9042..8d0617fc9d 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/ComputeManualPriorNotification.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/ComputeManualPriorNotification.kt @@ -26,6 +26,7 @@ class ComputeManualPriorNotification( portLocode: String, tripGearCodes: List, vesselId: Int, + year: Int, ): ManualPriorNotificationComputedValues { val vessel = vesselRepository.findVesselById(vesselId) requireNotNull(vessel) { @@ -41,7 +42,7 @@ class ComputeManualPriorNotification( val vesselFlagCountryCode = vessel.flagState val speciesCatch = getSpeciesCatchesForSegmentCalculation(tripGearCodes, fishingCatchesWithFaoArea, species) - val tripSegments = computeFleetSegments.execute(vessel.id, speciesCatch) + val tripSegments = computeFleetSegments.execute(year, vessel.id, speciesCatch) val types = computePnoTypes.execute(fishingCatchesWithFaoArea, tripGearCodes, vesselFlagCountryCode) val vesselRiskFactor = computeRiskFactor.execute(portLocode, tripSegments, vesselCfr) @@ -56,10 +57,10 @@ class ComputeManualPriorNotification( return ManualPriorNotificationComputedValues( isVesselUnderCharter = vessel.underCharter, - nextState, - tripSegments, - types, - vesselRiskFactor, + nextState = nextState, + tripSegments = tripSegments, + types = types, + vesselRiskFactor = vesselRiskFactor, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotification.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotification.kt index 4a043d98ed..14ac649a9e 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotification.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotification.kt @@ -63,11 +63,12 @@ class CreateOrUpdateManualPriorNotification( // The Backend should NEVER update `risk_factors` DB table, only the pipeline is allowed to update it. val computedValues = computeManualPriorNotification.execute( - fishingCatches, - globalFaoArea, - portLocode, - tripGearCodes, - vesselId, + fishingCatches = fishingCatches, + globalFaoArea = globalFaoArea, + portLocode = portLocode, + tripGearCodes = tripGearCodes, + vesselId = vesselId, + year = expectedLandingDate.year, ) val isPartOfControlUnitSubscriptions = diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt index 58137b9f65..a09197893f 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt @@ -28,7 +28,7 @@ class FleetSegmentController( } @PostMapping("/compute") - @Operation(summary = "compute fleet segments for the current year") + @Operation(summary = "compute fleet segments for the given year") fun computeFleetSegments( @RequestBody computeFleetSegmentsDataInput: ComputeFleetSegmentsDataInput, @@ -39,6 +39,7 @@ class FleetSegmentController( computeFleetSegmentsDataInput.faoAreas, computeFleetSegmentsDataInput.gears.map { it.toGearControl() }, computeFleetSegmentsDataInput.species.map { it.toSpeciesControl() }, + computeFleetSegmentsDataInput.year, ) return fleetSegments.map { FleetSegmentDataOutput.fromFleetSegment(it) diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationController.kt index f44e5250da..b33e3a1df6 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationController.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationController.kt @@ -207,6 +207,7 @@ class PriorNotificationController( portLocode = manualPriorNotificationComputeDataInput.portLocode, tripGearCodes = manualPriorNotificationComputeDataInput.tripGearCodes, vesselId = manualPriorNotificationComputeDataInput.vesselId, + year = manualPriorNotificationComputeDataInput.year, ) return ManualPriorNotificationComputedValuesDataOutput diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ComputeFleetSegmentsDataInput.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ComputeFleetSegmentsDataInput.kt index 0f9cae3263..a7cf07e6c1 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ComputeFleetSegmentsDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ComputeFleetSegmentsDataInput.kt @@ -5,4 +5,5 @@ data class ComputeFleetSegmentsDataInput( val vesselId: Int, val gears: List, val species: List, + val year: Int, ) diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ManualPriorNotificationComputeDataInput.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ManualPriorNotificationComputeDataInput.kt index 34d1cdca9a..8e54c7de6a 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ManualPriorNotificationComputeDataInput.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/input/ManualPriorNotificationComputeDataInput.kt @@ -6,4 +6,5 @@ data class ManualPriorNotificationComputeDataInput( val portLocode: String, val tripGearCodes: List, val vesselId: Int, + val year: Int, ) diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsUTests.kt index 888ba20373..a47a4e4df1 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/fleet_segment/ComputeFleetSegmentsUTests.kt @@ -2,6 +2,7 @@ package fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment import com.neovisionaries.i18n.CountryCode import com.nhaarman.mockitokotlin2.any +import com.nhaarman.mockitokotlin2.eq import com.nhaarman.mockitokotlin2.given import fr.gouv.cnsp.monitorfish.domain.entities.fleet_segment.ScipSpeciesType import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel @@ -14,8 +15,6 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.context.junit.jupiter.SpringExtension -import java.time.Clock -import java.time.ZonedDateTime @ExtendWith(SpringExtension::class) class ComputeFleetSegmentsUTests { @@ -25,10 +24,6 @@ class ComputeFleetSegmentsUTests { @MockBean private lateinit var vesselRepository: VesselRepository - companion object { - val fixedClock: Clock = Clock.systemUTC() - } - @Test fun `execute Should compute Lines segment`() { // Given @@ -115,7 +110,7 @@ class ComputeFleetSegmentsUTests { scipSpeciesType = ScipSpeciesType.TUNA, ), ) - given(fleetSegmentRepository.findAllByYear(ZonedDateTime.now().year)).willReturn(fleetSegmentsForComputation) + given(fleetSegmentRepository.findAllByYear(eq(2025))).willReturn(fleetSegmentsForComputation) given(vesselRepository.findVesselById(any())).willReturn( Vessel( id = 1, @@ -134,8 +129,7 @@ class ComputeFleetSegmentsUTests { ComputeFleetSegments( fleetSegmentRepository, vesselRepository, - fixedClock, - ).execute(1, speciesCatches) + ).execute(2025, 1, speciesCatches) // Then assertThat(fleetSegments).hasSize(1) @@ -164,7 +158,7 @@ class ComputeFleetSegmentsUTests { scipSpeciesType = ScipSpeciesType.PELAGIC, ), ) - given(fleetSegmentRepository.findAllByYear(ZonedDateTime.now().year)).willReturn(fleetSegmentsForComputation) + given(fleetSegmentRepository.findAllByYear(eq(2025))).willReturn(fleetSegmentsForComputation) given(vesselRepository.findVesselById(any())).willReturn( Vessel( id = 1, @@ -183,8 +177,7 @@ class ComputeFleetSegmentsUTests { ComputeFleetSegments( fleetSegmentRepository, vesselRepository, - fixedClock, - ).execute(1, speciesCatches) + ).execute(2025, 1, speciesCatches) // Then assertThat(fleetSegments).hasSize(1) @@ -221,7 +214,7 @@ class ComputeFleetSegmentsUTests { scipSpeciesType = null, ), ) - given(fleetSegmentRepository.findAllByYear(ZonedDateTime.now().year)).willReturn(fleetSegmentsForComputation) + given(fleetSegmentRepository.findAllByYear(eq(2025))).willReturn(fleetSegmentsForComputation) given(vesselRepository.findVesselById(any())).willReturn( Vessel( id = 1, @@ -240,8 +233,7 @@ class ComputeFleetSegmentsUTests { ComputeFleetSegments( fleetSegmentRepository, vesselRepository, - fixedClock, - ).execute(1, speciesCatches) + ).execute(2025, 1, speciesCatches) // Then assertThat(fleetSegments).hasSize(1) @@ -278,7 +270,7 @@ class ComputeFleetSegmentsUTests { scipSpeciesType = null, ), ) - given(fleetSegmentRepository.findAllByYear(ZonedDateTime.now().year)).willReturn(fleetSegmentsForComputation) + given(fleetSegmentRepository.findAllByYear(eq(2025))).willReturn(fleetSegmentsForComputation) given(vesselRepository.findVesselById(any())).willReturn( Vessel( id = 1, @@ -297,8 +289,7 @@ class ComputeFleetSegmentsUTests { ComputeFleetSegments( fleetSegmentRepository, vesselRepository, - fixedClock, - ).execute(1, speciesCatches) + ).execute(2025, 1, speciesCatches) // Then assertThat(fleetSegments).hasSize(1) @@ -327,7 +318,7 @@ class ComputeFleetSegmentsUTests { scipSpeciesType = ScipSpeciesType.DEMERSAL, ), ) - given(fleetSegmentRepository.findAllByYear(ZonedDateTime.now().year)).willReturn(fleetSegmentsForComputation) + given(fleetSegmentRepository.findAllByYear(eq(2025))).willReturn(fleetSegmentsForComputation) given(vesselRepository.findVesselById(any())).willReturn( Vessel( id = 1, @@ -346,8 +337,7 @@ class ComputeFleetSegmentsUTests { ComputeFleetSegments( fleetSegmentRepository, vesselRepository, - fixedClock, - ).execute(1, speciesCatches) + ).execute(2025, 1, speciesCatches) // Then assertThat(fleetSegments).hasSize(1) @@ -376,7 +366,7 @@ class ComputeFleetSegmentsUTests { scipSpeciesType = ScipSpeciesType.DEMERSAL, ), ) - given(fleetSegmentRepository.findAllByYear(ZonedDateTime.now().year)).willReturn(fleetSegmentsForComputation) + given(fleetSegmentRepository.findAllByYear(eq(2025))).willReturn(fleetSegmentsForComputation) given(vesselRepository.findVesselById(any())).willReturn( Vessel( id = 1, @@ -395,8 +385,7 @@ class ComputeFleetSegmentsUTests { ComputeFleetSegments( fleetSegmentRepository, vesselRepository, - fixedClock, - ).execute(1, speciesCatches) + ).execute(2025, 1, speciesCatches) // Then assertThat(fleetSegments).hasSize(1) @@ -406,7 +395,7 @@ class ComputeFleetSegmentsUTests { @Test fun `execute Should compute no segment`() { // Given - given(fleetSegmentRepository.findAllByYear(ZonedDateTime.now().year)).willReturn(fleetSegmentsForComputation) + given(fleetSegmentRepository.findAllByYear(eq(2025))).willReturn(fleetSegmentsForComputation) given(vesselRepository.findVesselById(any())).willReturn( Vessel( id = 1, @@ -425,8 +414,7 @@ class ComputeFleetSegmentsUTests { ComputeFleetSegments( fleetSegmentRepository, vesselRepository, - fixedClock, - ).execute(1, listOf()) + ).execute(2025, 1, listOf()) // Then assertThat(fleetSegments).hasSize(0) diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationITests.kt index dd959fa80e..55b44450c6 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationITests.kt @@ -341,7 +341,7 @@ class CreateOrUpdateManualPriorNotificationITests : AbstractDBTests() { // Given val reportId = testCase.reportId - given { computeManualPriorNotification.execute(any(), any(), any(), any(), any()) } + given { computeManualPriorNotification.execute(any(), any(), any(), any(), any(), any()) } .willReturn( ManualPriorNotificationComputedValues( isVesselUnderCharter = false, @@ -390,7 +390,7 @@ class CreateOrUpdateManualPriorNotificationITests : AbstractDBTests() { // Given val reportId = testCase.reportId - given { computeManualPriorNotification.execute(any(), any(), any(), any(), any()) } + given { computeManualPriorNotification.execute(any(), any(), any(), any(), any(), any()) } .willReturn( ManualPriorNotificationComputedValues( isVesselUnderCharter = false, diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationUTests.kt index 1606e4b034..6f8a047d41 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/use_cases/prior_notification/CreateOrUpdateManualPriorNotificationUTests.kt @@ -53,7 +53,7 @@ class CreateOrUpdateManualPriorNotificationUTests { // Given given(vesselRepository.findVesselById(any())).willReturn(VesselFaker.fakeVessel()) - given(computeManualPriorNotification.execute(any(), any(), any(), any(), any())).willReturn( + given(computeManualPriorNotification.execute(any(), any(), any(), any(), any(), any())).willReturn( ManualPriorNotificationComputedValues( isVesselUnderCharter = null, nextState = PriorNotificationState.OUT_OF_VERIFICATION_SCOPE, @@ -116,7 +116,7 @@ class CreateOrUpdateManualPriorNotificationUTests { existingFakePriorNotification, ) given(vesselRepository.findVesselById(any())).willReturn(VesselFaker.fakeVessel()) - given(computeManualPriorNotification.execute(any(), any(), any(), any(), any())).willReturn( + given(computeManualPriorNotification.execute(any(), any(), any(), any(), any(), any())).willReturn( ManualPriorNotificationComputedValues( isVesselUnderCharter = null, nextState = PriorNotificationState.OUT_OF_VERIFICATION_SCOPE, diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt index 8849758061..f2cc476028 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt @@ -77,7 +77,7 @@ class FleetSegmentControllerITests { @Test fun `Should compute fleet segments`() { // Given - given(this.computeFleetSegmentsFromControl.execute(any(), any(), any(), any())).willReturn( + given(this.computeFleetSegmentsFromControl.execute(any(), any(), any(), any(), any())).willReturn( listOf( FleetSegment( segment = "SWW01", @@ -106,6 +106,7 @@ class FleetSegmentControllerITests { ComputeFleetSegmentsDataInput( faoAreas = listOf("27.1.c", "27.1.b"), vesselId = 123, + year = 2021, gears = listOf( GearControlDataInput( diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerUTests.kt index 74981bb10c..3e844eeb1e 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/PriorNotificationControllerUTests.kt @@ -168,7 +168,7 @@ class PriorNotificationControllerUTests { @Test fun `getManualComputation Should get a manual prior notification computed values`() { // Given - given(this.computeManualPriorNotification.execute(any(), any(), any(), any(), any())) + given(this.computeManualPriorNotification.execute(any(), any(), any(), any(), any(), any())) .willReturn( ManualPriorNotificationComputedValues( isVesselUnderCharter = null, @@ -188,6 +188,7 @@ class PriorNotificationControllerUTests { portLocode = "FRABC", tripGearCodes = emptyList(), vesselId = 42, + year = 2025, ), ) api diff --git a/frontend/cypress/e2e/side_window/manual_prior_notification_form/form.spec.ts b/frontend/cypress/e2e/side_window/manual_prior_notification_form/form.spec.ts index b04a4f2d60..cbef9c5cc4 100644 --- a/frontend/cypress/e2e/side_window/manual_prior_notification_form/form.spec.ts +++ b/frontend/cypress/e2e/side_window/manual_prior_notification_form/form.spec.ts @@ -433,6 +433,11 @@ context('Side Window > Manual Prior Notification Form > Form', () => { cy.fill('Engins utilisés', ['OTB'], { index: 1 }) + const { utcDateTupleWithTime: arrivalDateTupleWithTime } = + getUtcDateInMultipleFormats(customDayjs().add(2, 'hours').startOf('minute').toISOString()) + cy.fill("Date et heure estimées d'arrivée au port (UTC)", arrivalDateTupleWithTime) + cy.fill("équivalentes à celles de l'arrivée au port", true) + cy.wait('@computePriorNotification') cy.countRequestsByAlias('@computePriorNotification').should('be.equal', 1) diff --git a/frontend/cypress/e2e/side_window/mission_form/sea_control.spec.ts b/frontend/cypress/e2e/side_window/mission_form/sea_control.spec.ts index db118a3246..68511ef6fb 100644 --- a/frontend/cypress/e2e/side_window/mission_form/sea_control.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/sea_control.spec.ts @@ -141,6 +141,13 @@ context('Side Window > Mission Form > Sea Control', () => { cy.fill('Sous-taille', true) cy.fill('Observations (hors infraction) sur les espèces', 'Une observation hors infraction sur les espèces.') + // This should trigger a computation of the fleet segment + cy.intercept('POST', 'bff/v1/fleet_segments/compute').as( + 'computeFleetSegments' + ) + cy.fill('Date et heure du contrôle', now.utcDateTupleWithTime) + cy.wait('@computeFleetSegments') + // Appréhension et déroutement cy.fill('Appréhension d’engin(s)', true) cy.fill('Appréhension d’espèce(s)', true) diff --git a/frontend/cypress/e2e/side_window/mission_form/sea_control_edition.spec.ts b/frontend/cypress/e2e/side_window/mission_form/sea_control_edition.spec.ts index aa4e8d6113..52215e4e11 100644 --- a/frontend/cypress/e2e/side_window/mission_form/sea_control_edition.spec.ts +++ b/frontend/cypress/e2e/side_window/mission_form/sea_control_edition.spec.ts @@ -82,7 +82,7 @@ context('Side Window > Mission Form > Sea Control Edition', () => { otherComments: 'Commentaires post contrôle', otherInfractions: [], portLocode: null, - segments: [{ segment: 'SWW04', segmentName: 'SWW04' }], + segments: [], seizureAndDiversion: false, seizureAndDiversionComments: null, separateStowageOfPreservedSpecies: 'NO', @@ -179,12 +179,7 @@ context('Side Window > Mission Form > Sea Control Edition', () => { otherComments: 'Commentaires post contrôle', otherInfractions: [], portLocode: null, - segments: [ - { - segment: 'SWW02', - segmentName: 'SWW02' - } - ], + segments: [], seizureAndDiversion: false, seizureAndDiversionComments: null, separateStowageOfPreservedSpecies: 'NO', diff --git a/frontend/src/features/FleetSegment/apis.ts b/frontend/src/features/FleetSegment/apis.ts index 655c2eaa95..2098d1ccc7 100644 --- a/frontend/src/features/FleetSegment/apis.ts +++ b/frontend/src/features/FleetSegment/apis.ts @@ -10,6 +10,7 @@ export type ComputeFleetSegmentsParams = { gears: MissionAction.GearControl[] species: MissionAction.SpeciesControl[] vesselId: number + year: number } export const fleetSegmentApi = monitorfishApi.injectEndpoints({ diff --git a/frontend/src/features/FleetSegment/useCases/computeFleetSegments.ts b/frontend/src/features/FleetSegment/useCases/computeFleetSegments.ts index 5a00a2319c..4a2fb17546 100644 --- a/frontend/src/features/FleetSegment/useCases/computeFleetSegments.ts +++ b/frontend/src/features/FleetSegment/useCases/computeFleetSegments.ts @@ -9,20 +9,26 @@ export const computeFleetSegments = faoAreas: string[] | undefined, gearOnBoard: MissionActionFormValues['gearOnboard'], speciesOnboard: MissionActionFormValues['speciesOnboard'], - vesselId: number + vesselId: number | undefined, + year: number | undefined ) => async (dispatch): Promise => { if (!gearOnBoard?.length && !speciesOnboard?.length) { return [] } + if (vesselId === undefined || year === undefined) { + return [] + } + const { data: fleetSegments } = await dispatch( fleetSegmentApi.endpoints.computeFleetSegments.initiate( { faoAreas: faoAreas ?? [], gears: gearOnBoard ?? [], species: speciesOnboard ?? [], - vesselId + vesselId, + year }, RTK_FORCE_REFETCH_QUERY_OPTIONS ) diff --git a/frontend/src/features/Mission/components/MissionForm/ActionForm/shared/DatePickerField.tsx b/frontend/src/features/Mission/components/MissionForm/ActionForm/shared/DatePickerField.tsx index 328be49da9..56635b1548 100644 --- a/frontend/src/features/Mission/components/MissionForm/ActionForm/shared/DatePickerField.tsx +++ b/frontend/src/features/Mission/components/MissionForm/ActionForm/shared/DatePickerField.tsx @@ -7,7 +7,7 @@ import type { MissionActionFormValues } from '../../types' export function DatePickerField() { const { newWindowContainerRef } = useNewWindow() - const { updateMissionLocation } = useGetMissionActionFormikUsecases() + const { updateMissionLocation, updateSegments } = useGetMissionActionFormikUsecases() const { errors, setFieldValue, values } = useFormikContext() const error = errors.actionDatetimeUtc @@ -16,6 +16,8 @@ export function DatePickerField() { setFieldValue('actionDatetimeUtc', nextActionDatetimeUtc) updateMissionLocation(values) + + updateSegments({ ...values, actionDatetimeUtc: nextActionDatetimeUtc }) } return ( diff --git a/frontend/src/features/Mission/components/MissionForm/hooks/useGetMissionActionFormikUsecases.ts b/frontend/src/features/Mission/components/MissionForm/hooks/useGetMissionActionFormikUsecases.ts index 29feb20607..3683a01fc0 100644 --- a/frontend/src/features/Mission/components/MissionForm/hooks/useGetMissionActionFormikUsecases.ts +++ b/frontend/src/features/Mission/components/MissionForm/hooks/useGetMissionActionFormikUsecases.ts @@ -1,5 +1,4 @@ import { useGetPortsQuery } from '@api/port' -import { useGetFleetSegmentsQuery } from '@features/FleetSegment/apis' import { initMissionGeometry } from '@features/Mission/components/MissionForm/useCases/initMissionGeometry' import { updateActionFAOAreas } from '@features/Mission/components/MissionForm/useCases/updateActionFAOAreas' import { updateActionGearsOnboard } from '@features/Mission/components/MissionForm/useCases/updateActionGearsOnboard' @@ -12,12 +11,8 @@ import { useMainAppDispatch } from '@hooks/useMainAppDispatch' import { useMainAppSelector } from '@hooks/useMainAppSelector' import { skipToken } from '@reduxjs/toolkit/query' import { useFormikContext } from 'formik' -import { useMemo } from 'react' - -import { getFleetSegmentsAsOption } from '../ActionForm/shared/utils' import type { MissionActionFormValues } from '../types' -import type { Option } from '@mtes-mct/monitor-ui' import MissionActionType = MissionAction.MissionActionType @@ -27,17 +22,11 @@ export function useGetMissionActionFormikUsecases() { const draft = useMainAppSelector(state => state.missionForm.draft) const { setFieldValue: setMissionActionFieldValue } = useFormikContext() - const getFleetSegmentsApiQuery = useGetFleetSegmentsQuery() const getPortsApiQuery = useGetPortsQuery() const getMissionApiQuery = useGetMissionQuery(draft?.mainFormValues?.id ?? skipToken) - const fleetSegmentsAsOptions: Option[] = useMemo( - () => getFleetSegmentsAsOption(getFleetSegmentsApiQuery.data), - [getFleetSegmentsApiQuery.data] - ) - const updateSegments = (missionActionValues: MissionActionFormValues) => - updateActionSegments(dispatch, setMissionActionFieldValue, fleetSegmentsAsOptions)(missionActionValues) + updateActionSegments(dispatch, setMissionActionFieldValue)(missionActionValues) /** * Update FAO Areas and segments from the control coordinates or port input @@ -47,8 +36,7 @@ export function useGetMissionActionFormikUsecases() { await updateActionSegments( dispatch, - setMissionActionFieldValue, - fleetSegmentsAsOptions + setMissionActionFieldValue )({ ...missionActionValues, faoAreas @@ -79,8 +67,7 @@ export function useGetMissionActionFormikUsecases() { await updateActionSegments( dispatch, - setMissionActionFieldValue, - fleetSegmentsAsOptions + setMissionActionFieldValue )({ ...missionActionValues, faoAreas, diff --git a/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts b/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts index 5cc2c4ae69..08a25f26ee 100644 --- a/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts +++ b/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts @@ -1,36 +1,32 @@ import { computeFleetSegments } from '@features/FleetSegment/useCases/computeFleetSegments' import { MissionAction } from '@features/Mission/missionAction.types' +import { customDayjs } from '@mtes-mct/monitor-ui' +import type { FleetSegment } from '@features/FleetSegment/types' import type { MissionActionFormValues } from '@features/Mission/components/MissionForm/types' -import type { Option } from '@mtes-mct/monitor-ui' export const updateActionSegments = - ( - dispatch, - setFieldValue: (field: string, value: any) => void, - fleetSegmentsAsOptions: Option[] - ) => - async (missionAction: MissionActionFormValues) => { + (dispatch, setFieldValue: (field: string, value: any) => void) => async (missionAction: MissionActionFormValues) => { if (missionAction.actionType === MissionAction.MissionActionType.AIR_CONTROL) { return } - if (missionAction.vesselId === undefined) { - return - } + const year = missionAction.actionDatetimeUtc ? customDayjs(missionAction.actionDatetimeUtc).get('year') : undefined - const computedFleetSegments = await dispatch( + const computedFleetSegments: FleetSegment[] = await dispatch( computeFleetSegments( missionAction.faoAreas, missionAction.gearOnboard, missionAction.speciesOnboard, - missionAction.vesselId + missionAction.vesselId, + year ) ) - const nextFleetSegments = fleetSegmentsAsOptions - .filter(({ value }) => computedFleetSegments?.find(fleetSegment => fleetSegment.segment === value.segment)) - .map(({ value }) => value) + const nextFleetSegments = computedFleetSegments.map(segment => ({ + segment: segment.segment, + segmentName: segment.segmentName + })) setFieldValue('segments', nextFleetSegments) } diff --git a/frontend/src/features/PriorNotification/PriorNotification.types.ts b/frontend/src/features/PriorNotification/PriorNotification.types.ts index 49f6b0ae22..7aa41e53df 100644 --- a/frontend/src/features/PriorNotification/PriorNotification.types.ts +++ b/frontend/src/features/PriorNotification/PriorNotification.types.ts @@ -237,6 +237,7 @@ export namespace PriorNotification { 'fishingCatches' | 'globalFaoArea' | 'portLocode' | 'tripGearCodes' > & { vesselId: number + year: number } export type ApiManualCreateOrUpdateRequestData = Omit & { diff --git a/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/Content.tsx b/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/Content.tsx index a0df953196..ad3e7b4db7 100644 --- a/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/Content.tsx +++ b/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/Content.tsx @@ -1,5 +1,6 @@ import { ConfirmationModal } from '@components/ConfirmationModal' import { FrontendErrorBoundary } from '@components/FrontendErrorBoundary' +import { SideWindowCard } from '@components/SideWindowCard' import { priorNotificationActions } from '@features/PriorNotification/slice' import { invalidatePriorNotification } from '@features/PriorNotification/useCases/invalidatePriorNotification' import { updateManualPriorNotificationComputedValues } from '@features/PriorNotification/useCases/updateManualPriorNotificationComputedValues' @@ -17,7 +18,6 @@ import { useDebouncedCallback } from 'use-debounce' import { Form } from './Form' import { getPartialComputationRequestData } from './utils' -import { SideWindowCard } from '../../../../components/SideWindowCard' import { PriorNotification } from '../../PriorNotification.types' import { CardBanner } from '../shared/CardBanner' import { CardBodyHead } from '../shared/CardBodyHead' @@ -118,7 +118,8 @@ export function Content({ detail, isValidatingOnChange, onClose, onSubmit, onVer 'fishingCatches', 'portLocode', 'tripGearCodes', - 'vesselId' + 'vesselId', + 'year' ]) if ( !nextComputationRequestData || diff --git a/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/utils.tsx b/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/utils.tsx index 8f51874b92..eb4cfbc61a 100644 --- a/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/utils.tsx +++ b/frontend/src/features/PriorNotification/components/ManualPriorNotificationForm/utils.tsx @@ -5,24 +5,34 @@ import { BLUEFIN_TUNA_SPECY_CODE, SWORDFISH_SPECY_CODE } from '@features/PriorNotification/constants' +import { customDayjs } from '@mtes-mct/monitor-ui' import { INITIAL_FORM_VALUES } from './constants' import type { ManualPriorNotificationFormValues, ManualPriorNotificationFormValuesFishingCatch } from './types' export function getPartialComputationRequestData({ + expectedArrivalDate, + expectedLandingDate, fishingCatches, globalFaoArea, + isExpectedLandingDateSameAsExpectedArrivalDate, portLocode, tripGearCodes, vesselIdentity }: ManualPriorNotificationFormValues) { + const computedExpectedLandingDate = isExpectedLandingDateSameAsExpectedArrivalDate + ? expectedArrivalDate + : expectedLandingDate + const year = computedExpectedLandingDate ? customDayjs(computedExpectedLandingDate).get('year') : undefined + return { fishingCatches, globalFaoArea, portLocode, tripGearCodes, - vesselId: vesselIdentity?.vesselId + vesselId: vesselIdentity?.vesselId, + year } }