Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tech – Re-style la liste, la carte et les formulaires des préavis en border-box #3575

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import java.time.ZonedDateTime
import java.util.*

data class PatchableMissionAction(
val actionDatetimeUtc : Optional<ZonedDateTime>?,
val actionDatetimeUtc: Optional<ZonedDateTime>?,
val actionEndDatetimeUtc: Optional<ZonedDateTime>?,
val observationsByUnit: Optional<String>?,
)
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,18 @@ class ComputeManualPriorNotification(
private val computeRiskFactor: ComputeRiskFactor,
) {
fun execute(
faoArea: String,
fishingCatches: List<LogbookFishingCatch>,
/** When there is a single FAO area shared by all fishing catches. */
globalFaoArea: String?,
portLocode: String,
tripGearCodes: List<String>,
vesselId: Int,
): ManualPriorNotificationComputedValues {
val vessel = vesselRepository.findVesselById(vesselId)

val faoAreas = listOf(faoArea)
val fishingCatchesWithFaoArea = fishingCatches.map { it.copy(faoZone = faoArea) }
val faoAreas = globalFaoArea?.let { listOf(globalFaoArea) } ?: fishingCatches.mapNotNull { it.faoZone }
val fishingCatchesWithFaoArea = globalFaoArea?.let { fishingCatches.map { it.copy(faoZone = globalFaoArea) } }
?: fishingCatches
val specyCodes = fishingCatches.mapNotNull { it.species }
val vesselCfr = vessel?.internalReferenceNumber
val vesselFlagCountryCode = vessel?.flagState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@ class CreateOrUpdateManualPriorNotification(
didNotFishAfterZeroNotice: Boolean,
expectedArrivalDate: ZonedDateTime,
expectedLandingDate: ZonedDateTime,
faoArea: String,
fishingCatches: List<LogbookFishingCatch>,
/**
* Single FAO area shared by all fishing catches.
*
* Take precedence over the FAO area of each fishing catch if set.
*/
globalFaoArea: String?,
hasPortEntranceAuthorization: Boolean,
hasPortLandingAuthorization: Boolean,
note: String?,
Expand All @@ -49,8 +54,8 @@ class CreateOrUpdateManualPriorNotification(
// /!\ Backend computed vessel risk factor is only used as a real time Frontend indicator.
// The Backend should NEVER update `risk_factors` DB table, only the pipeline is allowed to update it.
val computedValues = computeManualPriorNotification.execute(
faoArea,
fishingCatches,
globalFaoArea,
portLocode,
tripGearCodes,
vesselId,
Expand All @@ -60,7 +65,8 @@ class CreateOrUpdateManualPriorNotification(
pnoVesselSubscriptionRepository.has(vesselId) ||
pnoSegmentSubscriptionRepository.has(portLocode, computedValues.tripSegments.map { it.segment })

val fishingCatchesWithFaoArea = fishingCatches.map { it.copy(faoZone = faoArea) }
val fishingCatchesWithFaoArea = globalFaoArea?.let { fishingCatches.map { it.copy(faoZone = globalFaoArea) } }
?: fishingCatches
val tripGears = getTripGears(tripGearCodes)
val tripSegments = computedValues.tripSegments.map { it.toLogbookTripSegment() }
val vessel = vesselRepository.findVesselById(vesselId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ class PriorNotificationController(
val fishingCatches = manualPriorNotificationComputeDataInput.fishingCatches.map { it.toLogbookFishingCatch() }

val manualPriorNotificationComputedValues = computeManualPriorNotification.execute(
faoArea = manualPriorNotificationComputeDataInput.faoArea,
fishingCatches = fishingCatches,
globalFaoArea = manualPriorNotificationComputeDataInput.globalFaoArea,
portLocode = manualPriorNotificationComputeDataInput.portLocode,
tripGearCodes = manualPriorNotificationComputeDataInput.tripGearCodes,
vesselId = manualPriorNotificationComputeDataInput.vesselId,
Expand Down Expand Up @@ -230,7 +230,7 @@ class PriorNotificationController(
didNotFishAfterZeroNotice = manualPriorNotificationFormDataInput.didNotFishAfterZeroNotice,
expectedArrivalDate = manualPriorNotificationFormDataInput.expectedArrivalDate,
expectedLandingDate = manualPriorNotificationFormDataInput.expectedLandingDate,
faoArea = manualPriorNotificationFormDataInput.faoArea,
globalFaoArea = manualPriorNotificationFormDataInput.globalFaoArea,
fishingCatches = manualPriorNotificationFormDataInput.fishingCatches.map { it.toLogbookFishingCatch() },
note = manualPriorNotificationFormDataInput.note,
portLocode = manualPriorNotificationFormDataInput.portLocode,
Expand Down Expand Up @@ -260,7 +260,7 @@ class PriorNotificationController(
didNotFishAfterZeroNotice = manualPriorNotificationFormDataInput.didNotFishAfterZeroNotice,
expectedArrivalDate = manualPriorNotificationFormDataInput.expectedArrivalDate,
expectedLandingDate = manualPriorNotificationFormDataInput.expectedLandingDate,
faoArea = manualPriorNotificationFormDataInput.faoArea,
globalFaoArea = manualPriorNotificationFormDataInput.globalFaoArea,
fishingCatches = manualPriorNotificationFormDataInput.fishingCatches.map { it.toLogbookFishingCatch() },
note = manualPriorNotificationFormDataInput.note,
portLocode = manualPriorNotificationFormDataInput.portLocode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.input

data class ManualPriorNotificationComputeDataInput(
val faoArea: String,
val fishingCatches: List<ManualPriorNotificationFishingCatchDataInput>,
val globalFaoArea: String?,
val portLocode: String,
val tripGearCodes: List<String>,
val vesselId: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.input
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookFishingCatch

data class ManualPriorNotificationFishingCatchDataInput(
val faoArea: String?,
val quantity: Double?,
val specyCode: String,
val specyName: String,
Expand All @@ -13,7 +14,7 @@ data class ManualPriorNotificationFishingCatchDataInput(
conversionFactor = null,
economicZone = null,
effortZone = null,
faoZone = null,
faoZone = faoArea,
freshness = null,
nbFish = quantity,
packaging = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ data class ManualPriorNotificationFormDataInput(
val didNotFishAfterZeroNotice: Boolean,
val expectedArrivalDate: ZonedDateTime,
val expectedLandingDate: ZonedDateTime,
val faoArea: String,
val fishingCatches: List<ManualPriorNotificationFishingCatchDataInput>,
val globalFaoArea: String?,
val note: String?,
val portLocode: String,
val purpose: LogbookMessagePurpose,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.outputs

import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookFishingCatch

class ManualPriorNotificationFishingCatchDataOutput(
data class ManualPriorNotificationFishingCatchDataOutput(
val faoArea: String?,
val quantity: Double?,
val specyCode: String,
val specyName: String,
val weight: Double,
) {
companion object {
fun fromLogbookFishingCatch(logbookFishingCatch: LogbookFishingCatch): ManualPriorNotificationFishingCatchDataOutput {
fun fromLogbookFishingCatch(
logbookFishingCatch: LogbookFishingCatch,
withFaoArea: Boolean,
): ManualPriorNotificationFishingCatchDataOutput {
val faoArea = if (withFaoArea) logbookFishingCatch.faoZone else null
val specyCode = requireNotNull(logbookFishingCatch.species) {
"`logbookFishingCatch.species` is null."
}
Expand All @@ -21,6 +26,7 @@ class ManualPriorNotificationFishingCatchDataOutput(
}

return ManualPriorNotificationFishingCatchDataOutput(
faoArea,
quantity = logbookFishingCatch.nbFish,
specyCode,
specyName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ data class ManualPriorNotificationFormDataOutput(
val didNotFishAfterZeroNotice: Boolean,
val expectedArrivalDate: String,
val expectedLandingDate: String,
val faoArea: String?,
val fishingCatches: List<ManualPriorNotificationFishingCatchDataOutput>,
val globalFaoArea: String?,
val note: String?,
val portLocode: String,
val reportId: String,
Expand Down Expand Up @@ -42,16 +42,6 @@ data class ManualPriorNotificationFormDataOutput(
"`message.predictedLandingDatetimeUtc` is null."
},
).toString()
// At the moment, manual prior notifications only have a single global FAO area field in Frontend,
// so we transform that single FAO area into an FAO area per fishing catch when we save it,
// while setting the global `PNO.faoZone` to `null`.
// We need to reverse this transformation when we output the data.
val globalFaoArea = requireNotNull(pnoMessage.catchOnboard.firstOrNull()?.faoZone) {
"`message.catchOnboard.firstOrNull()?.faoZone` is null."
}
val fishingCatchDataOutputs = pnoMessage.catchOnboard.map {
ManualPriorNotificationFishingCatchDataOutput.fromLogbookFishingCatch(it)
}
val portLocode = requireNotNull(pnoMessage.port) { "`pnoMessage.port` is null." }
val purpose = requireNotNull(pnoMessage.purpose) { "`pnoMessage.purpose` is null." }
val reportId = requireNotNull(priorNotification.reportId) { "`priorNotification.reportId` is null." }
Expand All @@ -69,14 +59,29 @@ data class ManualPriorNotificationFormDataOutput(
val hasPortEntranceAuthorization = pnoMessage.hasPortEntranceAuthorization ?: true
val hasPortLandingAuthorization = pnoMessage.hasPortLandingAuthorization ?: true

// In Frontend form, manual prior notifications can:
// - either have a single global FAO area field
// - or have an FAO area field per fishing catch
// while in Backend, we always have an FAO area field per fishing catch.
// So we need to check if all fishing catches have the same FAO area to know which case we are in.
val hasGlobalFaoArea = pnoMessage.catchOnboard.mapNotNull { it.faoZone }.distinct().size == 1
val globalFaoArea = if (hasGlobalFaoArea) {
pnoMessage.catchOnboard.first().faoZone
} else {
null
}
val fishingCatchDataOutputs = pnoMessage.catchOnboard.map {
ManualPriorNotificationFishingCatchDataOutput.fromLogbookFishingCatch(it, !hasGlobalFaoArea)
}

return ManualPriorNotificationFormDataOutput(
hasPortEntranceAuthorization = hasPortEntranceAuthorization,
hasPortLandingAuthorization = hasPortLandingAuthorization,
authorTrigram = authorTrigram,
didNotFishAfterZeroNotice = priorNotification.didNotFishAfterZeroNotice,
expectedArrivalDate = expectedArrivalDate,
expectedLandingDate = expectedLandingDate,
faoArea = globalFaoArea,
globalFaoArea = globalFaoArea,
fishingCatches = fishingCatchDataOutputs,
note = pnoMessage.note,
portLocode = portLocode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ class CreateOrUpdateManualPriorNotificationITests : AbstractDBTests() {
didNotFishAfterZeroNotice = false,
expectedArrivalDate = ZonedDateTime.now(),
expectedLandingDate = ZonedDateTime.now(),
faoArea = "FAKE_FAO_AREA",
globalFaoArea = "FAKE_FAO_AREA",
fishingCatches = emptyList(),
hasPortEntranceAuthorization = false,
hasPortLandingAuthorization = false,
Expand Down Expand Up @@ -407,7 +407,7 @@ class CreateOrUpdateManualPriorNotificationITests : AbstractDBTests() {
didNotFishAfterZeroNotice = false,
expectedArrivalDate = ZonedDateTime.now(),
expectedLandingDate = ZonedDateTime.now(),
faoArea = "FAKE_FAO_AREA",
globalFaoArea = "FAKE_FAO_AREA",
fishingCatches = emptyList(),
hasPortEntranceAuthorization = false,
hasPortLandingAuthorization = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class CreateOrUpdateManualPriorNotificationUTests {
didNotFishAfterZeroNotice = false,
expectedArrivalDate = ZonedDateTime.parse("2024-01-01T00:00:00Z"),
expectedLandingDate = ZonedDateTime.parse("2024-01-01T00:00:00Z"),
faoArea = "FAKE_FAO_AREA",
globalFaoArea = "FAKE_FAO_AREA",
fishingCatches = emptyList(),
note = null,
portLocode = "FAKE_PORT_LOCODE",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,12 @@ class UpdateLogbookPriorNotificationITests : AbstractDBTests() {
assertThat(afterPriorNotification.reportId).isEqualTo(testCase.reportId)
assertThat(afterPriorNotification.isManuallyCreated)
.isEqualTo(testCase.expectedAfterBooleanState.isManualPriorNotification)
assertThat(afterPnoValue.isInVerificationScope).isEqualTo(testCase.expectedAfterBooleanState.isInVerificationScope)
assertThat(afterPnoValue.isInVerificationScope).isEqualTo(
testCase.expectedAfterBooleanState.isInVerificationScope,
)
assertThat(afterPnoValue.isVerified).isEqualTo(testCase.expectedAfterBooleanState.isVerified)
assertThat(afterPnoValue.isSent).isEqualTo(testCase.expectedAfterBooleanState.isSent)
assertThat(afterPnoValue.isBeingSent).isEqualTo(testCase.expectedAfterBooleanState.isBeingSent)
assertThat(afterPriorNotification.state).isEqualTo(testCase.expectedAfterState)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,9 @@ class VerifyAndSendPriorNotificationITests : AbstractDBTests() {
assertThat(afterPriorNotification.reportId).isEqualTo(testCase.reportId)
assertThat(afterPriorNotification.isManuallyCreated)
.isEqualTo(testCase.expectedAfterBooleanState.isManualPriorNotification)
assertThat(afterPnoValue.isInVerificationScope).isEqualTo(testCase.expectedAfterBooleanState.isInVerificationScope)
assertThat(afterPnoValue.isInVerificationScope).isEqualTo(
testCase.expectedAfterBooleanState.isInVerificationScope,
)
assertThat(afterPnoValue.isVerified).isEqualTo(testCase.expectedAfterBooleanState.isVerified)
assertThat(afterPnoValue.isSent).isEqualTo(testCase.expectedAfterBooleanState.isSent)
assertThat(afterPnoValue.isBeingSent).isEqualTo(testCase.expectedAfterBooleanState.isBeingSent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class PriorNotificationControllerUTests {
// When
val requestBody = objectMapper.writeValueAsString(
ManualPriorNotificationComputeDataInput(
faoArea = "FAO AREA 51",
globalFaoArea = "FAO AREA 51",
fishingCatches = emptyList(),
portLocode = "FRABC",
tripGearCodes = emptyList(),
Expand Down Expand Up @@ -261,7 +261,7 @@ class PriorNotificationControllerUTests {
didNotFishAfterZeroNotice = false,
expectedArrivalDate = ZonedDateTime.now(),
expectedLandingDate = ZonedDateTime.now(),
faoArea = "FAO AREA 51",
globalFaoArea = "FAO AREA 51",
fishingCatches = emptyList(),
note = null,
portLocode = "FRABVC",
Expand Down Expand Up @@ -294,7 +294,7 @@ class PriorNotificationControllerUTests {
didNotFishAfterZeroNotice = anyOrNull(),
expectedArrivalDate = anyOrNull(),
expectedLandingDate = anyOrNull(),
faoArea = anyOrNull(),
globalFaoArea = anyOrNull(),
fishingCatches = anyOrNull(),
hasPortEntranceAuthorization = anyOrNull(),
hasPortLandingAuthorization = anyOrNull(),
Expand All @@ -317,7 +317,7 @@ class PriorNotificationControllerUTests {
didNotFishAfterZeroNotice = false,
expectedArrivalDate = ZonedDateTime.now(),
expectedLandingDate = ZonedDateTime.now(),
faoArea = "FAO AREA 51",
globalFaoArea = "FAO AREA 51",
fishingCatches = emptyList(),
note = null,
portLocode = "FRABVC",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ context('Side Window > Manual Prior Notification Form > Behavior', () => {
cy.fill('Espèces à bord et à débarquer', 'AAX')
cy.fill('Poids (AAX)', 25)
cy.fill('Engins utilisés', ['OTP'], { index: 1 })
cy.fill('Zone de pêche', '21.4.T')
cy.fill('Zone globale de capture', '21.4.T')
cy.fill('Saisi par', 'ABC')

cy.clickButton('Créer le préavis')
Expand Down
Loading
Loading