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

[WIP] Act Rep - Filtrage des espèces du JDP dans les colonnes du csv #2881

Merged
merged 7 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
package fr.gouv.cnsp.monitorfish.domain.entities.mission_actions.actrep

enum class JointDeploymentPlan(private val species: List<FaoCodesAndSpecy>) {
enum class JointDeploymentPlan(private val species: List<FaoZonesAndSpecy>) {
MEDITERRANEAN_AND_EASTERN_ATLANTIC(MEDITERRANEAN_AND_EASTERN_ATLANTIC_SPECIES),
NORTH_SEA(NORTH_SEA_SPECIES),
WESTERN_WATERS(WESTERN_WATERS_SPECIES),
;

fun getSpeciesCodes(): List<FaoCodesAndSpecy> {
fun getFaoZonesAndSpeciesCodes(): List<FaoZonesAndSpecy> {
return this.species
}

fun getSpeciesCodes(): List<String> {
return this.species.map { it.second }.distinct()
}

fun isLandControlApplicable(speciesOnboardCodes: List<String>, tripFaoCodes: List<String>): Boolean {
return this.species.any { (jdpFaoCodes, jdpSpecy) ->
return this.species.any { (jdpFaoZones, jdpSpecy) ->
val isSpecyFound = speciesOnboardCodes.contains(jdpSpecy)
val isFaoCodeFound = jdpFaoCodes

val isFaoZoneFound = jdpFaoZones
.any { jdpFaoCode ->
// The JDP FAO code is included in at least one trip FAO code
// The JDP FAO zone is included in at least one trip FAO code
tripFaoCodes.any { tripFaoCode -> tripFaoCode.contains(jdpFaoCode) }
}

return@any isSpecyFound && isFaoCodeFound
return@any isSpecyFound && isFaoZoneFound
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package fr.gouv.cnsp.monitorfish.domain.entities.mission_actions.actrep

typealias FaoCodes = List<String>
typealias FaoCodesAndSpecy = Pair<FaoCodes, String>
typealias FaoZones = List<String>
typealias FaoZonesAndSpecy = Pair<FaoZones, String>

/**
* The following fao areas and species are defined in the species table document of each JDP.
*
* These tables could be found in these file names :
* - "Liste Espèces_JDP MED.pdf"
* - "liste espèces JDP NS-01.odt"
* - "LISTE_ESPECES_JDP WW.odt"
* * See issue: https://github.com/MTES-MCT/monitorfish/issues/1750
*/

val MED_FAO_CODES = listOf("37.1", "37.2", "37.3")
val MEDITERRANEAN_AND_EASTERN_ATLANTIC_SPECIES: List<FaoCodesAndSpecy> = generateSpeciesWithFaoCode(
val MEDITERRANEAN_AND_EASTERN_ATLANTIC_SPECIES: List<FaoZonesAndSpecy> = generateSpeciesWithFaoCode(
MED_FAO_CODES,
listOf(
"ANE",
Expand Down Expand Up @@ -59,8 +65,9 @@ val MEDITERRANEAN_AND_EASTERN_ATLANTIC_SPECIES: List<FaoCodesAndSpecy> = generat
) +
// Eastern Atlantic part
listOf(Pair(listOf("27.7", "27.8", "27.9", "27.10"), "BFT"))

val NS_01_FAO_CODES = listOf("27.4", "27.3.a")
val NORTH_SEA_SPECIES = generateSpeciesWithFaoCode(
val NORTH_SEA_SPECIES: List<FaoZonesAndSpecy> = generateSpeciesWithFaoCode(
NS_01_FAO_CODES,
listOf(
"HOM",
Expand Down Expand Up @@ -103,8 +110,9 @@ val NORTH_SEA_SPECIES = generateSpeciesWithFaoCode(
"NOP",
),
)

val WW_01_FAO_CODES = listOf("27.6", "27.7", "27.8", "27.9", "27.10")
val WESTERN_WATERS_SPECIES = listOf(
val WESTERN_WATERS_SPECIES: List<FaoZonesAndSpecy> = listOf(
Pair(listOf("27.6", "27.7", "27.8", "27.9"), "PIL"),
Pair(listOf("27.6", "27.7", "27.8", "27.9"), "ELE"),
) + generateSpeciesWithFaoCode(
Expand Down Expand Up @@ -146,6 +154,6 @@ val WESTERN_WATERS_SPECIES = listOf(
),
)

fun generateSpeciesWithFaoCode(faoCodes: FaoCodes, species: List<String>): List<FaoCodesAndSpecy> {
return species.map { Pair(faoCodes, it) }
fun generateSpeciesWithFaoCode(faoZones: FaoZones, species: List<String>): List<FaoZonesAndSpecy> {
return species.map { Pair(faoZones, it) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import fr.gouv.cnsp.monitorfish.domain.repositories.MissionRepository
import fr.gouv.cnsp.monitorfish.domain.repositories.PortRepository
import fr.gouv.cnsp.monitorfish.domain.repositories.VesselRepository
import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.dtos.ActivityReport
import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.dtos.ActivityReports
import org.slf4j.LoggerFactory
import java.time.ZonedDateTime

Expand All @@ -22,12 +23,15 @@ class GetActivityReports(
) {
private val logger = LoggerFactory.getLogger(GetActivityReports::class.java)

fun execute(beforeDateTime: ZonedDateTime, afterDateTime: ZonedDateTime, jdp: JointDeploymentPlan): List<ActivityReport> {
fun execute(beforeDateTime: ZonedDateTime, afterDateTime: ZonedDateTime, jdp: JointDeploymentPlan): ActivityReports {
val controls = missionActionsRepository.findControlsInDates(beforeDateTime, afterDateTime)
logger.info("Found ${controls.size} controls between dates [$afterDateTime, $beforeDateTime].")

if (controls.isEmpty()) {
return listOf()
return ActivityReports(
activityReports = listOf(),
jdpSpecies = jdp.getSpeciesCodes(),
)
}

val controlledVesselsIds = controls.mapNotNull { it.vesselId }.distinct()
Expand Down Expand Up @@ -62,7 +66,7 @@ class GetActivityReports(
}
logger.info("Found ${filteredControls.size} controls to report.")

return filteredControls.map { control ->
val activityReports = filteredControls.map { control ->
val activityCode = when (control.actionType) {
MissionActionType.LAND_CONTROL -> ActivityCode.LAN
MissionActionType.SEA_CONTROL -> ActivityCode.FIS
Expand Down Expand Up @@ -103,5 +107,10 @@ class GetActivityReports(
vessel = controlledVessel,
)
}.filterNotNull()

return ActivityReports(
activityReports = activityReports,
jdpSpecies = jdp.getSpeciesCodes(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel
data class ActivityReport(
val action: MissionAction,
val activityCode: ActivityCode,
val vesselNationalIdentifier: String, // The `districtCode` and `internalReferenceNumber` concatenation
// The `districtCode` and `internalReferenceNumber` concatenation
val vesselNationalIdentifier: String,
val controlUnits: List<ControlUnit>,
val vessel: Vessel,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.dtos

data class ActivityReports(
val activityReports: List<ActivityReport>,
// Species targeted for this JDP
val jdpSpecies: List<String>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.bff
import fr.gouv.cnsp.monitorfish.domain.entities.mission_actions.actrep.JointDeploymentPlan
import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.*
import fr.gouv.cnsp.monitorfish.infrastructure.api.input.AddMissionActionDataInput
import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.ActivityReportDataOutput
import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.ActivityReportsDataOutput
import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.ControlsSummaryDataOutput
import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.MissionActionDataOutput
import io.swagger.v3.oas.annotations.Operation
Expand Down Expand Up @@ -61,10 +61,10 @@ class MissionActionsController(
@Parameter(description = "JDP")
@RequestParam(name = "jdp")
jdp: JointDeploymentPlan,
): List<ActivityReportDataOutput> {
return getActivityReports.execute(beforeDateTime, afterDateTime, jdp).map {
ActivityReportDataOutput.fromActivityReport(it)
}
): ActivityReportsDataOutput {
val activityReports = getActivityReports.execute(beforeDateTime, afterDateTime, jdp)

return ActivityReportsDataOutput.fromActivityReports(activityReports)
}

@GetMapping("")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.dtos.ActivityRe
data class ActivityReportDataOutput(
val action: MissionActionDataOutput,
val activityCode: ActivityCode,
val vesselNationalIdentifier: String, // The `districtCode` and `internalReferenceNumber` concatenation
val vesselNationalIdentifier: String,
val controlUnits: List<ControlUnit>,
val vessel: VesselDataOutput,
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.outputs

import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.dtos.ActivityReports

data class ActivityReportsDataOutput(
val activityReports: List<ActivityReportDataOutput>,
val jdpSpecies: List<String>,
) {
companion object {
fun fromActivityReports(activityReports: ActivityReports) = ActivityReportsDataOutput(
activityReports = activityReports.activityReports.map { ActivityReportDataOutput.fromActivityReport(it) },
jdpSpecies = activityReports.jdpSpecies,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,12 @@ class GetActivityReportsUTests {
)

// Then
assertThat(activityReports).hasSize(2)
val landReport = activityReports.first()
assertThat(activityReports.jdpSpecies).hasSize(38)
assertThat(activityReports.activityReports).hasSize(2)
val landReport = activityReports.activityReports.first()
assertThat(landReport.activityCode).isEqualTo(ActivityCode.LAN)
assertThat(landReport.action.portName).isEqualTo("Al Jazeera Port")
val seaReport = activityReports.last()
val seaReport = activityReports.activityReports.last()
assertThat(seaReport.activityCode).isEqualTo(ActivityCode.FIS)
assertThat(landReport.vesselNationalIdentifier).isEqualTo("AYFR00022680")
}
Expand Down Expand Up @@ -275,8 +276,9 @@ class GetActivityReportsUTests {
)

// Then
assertThat(activityReports).hasSize(1)
val landReport = activityReports.first()
assertThat(activityReports.jdpSpecies).hasSize(38)
assertThat(activityReports.activityReports).hasSize(1)
val landReport = activityReports.activityReports.first()
assertThat(landReport.activityCode).isEqualTo(ActivityCode.LAN)
assertThat(landReport.action.portName).isEqualTo("Al Jazeera Port")
}
Expand Down Expand Up @@ -369,6 +371,6 @@ class GetActivityReportsUTests {
)

// Then
assertThat(activityReports).hasSize(0)
assertThat(activityReports.activityReports).hasSize(0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import fr.gouv.cnsp.monitorfish.domain.entities.mission_actions.actrep.JointDepl
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.Vessel
import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.*
import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.dtos.ActivityReport
import fr.gouv.cnsp.monitorfish.domain.use_cases.mission_actions.dtos.ActivityReports
import fr.gouv.cnsp.monitorfish.infrastructure.api.input.AddMissionActionDataInput
import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.TestUtils
import kotlinx.coroutines.runBlocking
Expand Down Expand Up @@ -290,32 +291,35 @@ class PublicMissionActionsControllerITests {
fun `Should get all activity reports for a given date range and JDP`() {
// Given
given(getActivityReports.execute(any(), any(), any())).willReturn(
listOf(
ActivityReport(
action = MissionAction(
1,
1,
1,
actionType = MissionActionType.SEA_CONTROL,
actionDatetimeUtc = ZonedDateTime.now(),
isDeleted = false,
hasSomeGearsSeized = false,
hasSomeSpeciesSeized = false,
isFromPoseidon = true,
),
activityCode = ActivityCode.FIS,
vesselNationalIdentifier = "AYFR000654",
controlUnits = listOf(ControlUnit(1234, "DIRM", false, "Cross Etel", listOf())),
vessel = Vessel(
id = 1,
internalReferenceNumber = "FR00022680",
vesselName = "MY AWESOME VESSEL",
flagState = CountryCode.FR,
declaredFishingGears = listOf("Trémails"),
vesselType = "Fishing",
districtCode = "AY",
ActivityReports(
activityReports = listOf(
ActivityReport(
action = MissionAction(
1,
1,
1,
actionType = MissionActionType.SEA_CONTROL,
actionDatetimeUtc = ZonedDateTime.now(),
isDeleted = false,
hasSomeGearsSeized = false,
hasSomeSpeciesSeized = false,
isFromPoseidon = true,
),
activityCode = ActivityCode.FIS,
vesselNationalIdentifier = "AYFR000654",
controlUnits = listOf(ControlUnit(1234, "DIRM", false, "Cross Etel", listOf())),
vessel = Vessel(
id = 1,
internalReferenceNumber = "FR00022680",
vesselName = "MY AWESOME VESSEL",
flagState = CountryCode.FR,
declaredFishingGears = listOf("Trémails"),
vesselType = "Fishing",
districtCode = "AY",
),
),
),
jdpSpecies = listOf("BSS", "MAK", "LTH"),
),
)

Expand All @@ -327,12 +331,14 @@ class PublicMissionActionsControllerITests {
)
// Then
.andExpect(status().isOk)
.andExpect(jsonPath("$.length()", equalTo(1)))
.andExpect(jsonPath("$[0].action.id", equalTo(1)))
.andExpect(jsonPath("$[0].activityCode", equalTo("FIS")))
.andExpect(jsonPath("$[0].vesselNationalIdentifier", equalTo("AYFR000654")))
.andExpect(jsonPath("$[0].controlUnits[0].id", equalTo(1234)))
.andExpect(jsonPath("$[0].vessel.vesselId", equalTo(1)))
.andExpect(jsonPath("$.activityReports.length()", equalTo(1)))
.andExpect(jsonPath("$.activityReports[0].action.id", equalTo(1)))
.andExpect(jsonPath("$.activityReports[0].activityCode", equalTo("FIS")))
.andExpect(jsonPath("$.activityReports[0].vesselNationalIdentifier", equalTo("AYFR000654")))
.andExpect(jsonPath("$.activityReports[0].controlUnits[0].id", equalTo(1234)))
.andExpect(jsonPath("$.activityReports[0].vessel.vesselId", equalTo(1)))
.andExpect(jsonPath("$.jdpSpecies.length()", equalTo(3)))
.andExpect(jsonPath("$.jdpSpecies[0]", equalTo("BSS")))

Mockito.verify(getActivityReports).execute(
ZonedDateTime.parse("2020-05-04T03:04:05Z"),
Expand Down
Loading
Loading