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

[Act-Rep] Groupe les espèces non-ciblées dans un colonne OTH #2977

Merged
merged 3 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ dependencies {
runtimeOnly("org.postgresql:postgresql:42.6.0")
testImplementation("io.ktor:ktor-client-mock-jvm:2.3.3")
testImplementation("org.assertj:assertj-core:3.25.0")
testImplementation("org.testcontainers:postgresql:1.19.6")
testImplementation("org.testcontainers:postgresql:1.19.4")
testImplementation("org.testcontainers:testcontainers:1.19.4")
testImplementation("org.testcontainers:junit-jupiter:1.19.4")
testImplementation("jakarta.servlet:jakarta.servlet-api:6.0.0")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { describe, expect, it } from '@jest/globals'

import { JDP_CSV_MAP_BASE } from '../components/ExportActivityReportsDialog/csvMap'
import { JDP } from '../constants'
import { JDP_CSV_MAP_BASE } from '../csvMap'
import { formatDMDCoordinateForActivityReport, getJDPCsvMap } from '../utils'
import {
formatDMDCoordinateForActivityReport,
getJDPCsvMap,
getSpeciesOnboardWithUntargetedSpeciesGrouped
} from '../utils'

describe('utils', () => {
it('formatCoordinateForActivityReport Should format a latitude', async () => {
Expand All @@ -29,9 +33,32 @@ describe('utils', () => {
expect(latitude).toEqual('')
})

it('getSpeciesOnboardWithUntargetedSpeciesGrouped Should return untargeted species grouped as OTH', async () => {
// Given
const speciesOnboard = [
{ controlledWeight: 500, declaredWeight: 471.2, nbFish: undefined, speciesCode: 'HKE', underSized: true },
{ controlledWeight: undefined, declaredWeight: 13.46, nbFish: undefined, speciesCode: 'BLI', underSized: false },
{ controlledWeight: 123.6, declaredWeight: undefined, nbFish: undefined, speciesCode: 'COD', underSized: false },
{ controlledWeight: undefined, declaredWeight: 12.6, nbFish: undefined, speciesCode: 'ANZ', underSized: false },
{ controlledWeight: undefined, declaredWeight: 45.5, nbFish: undefined, speciesCode: 'FMI', underSized: false }
]

// When
const groupedSpeciesOnboard = getSpeciesOnboardWithUntargetedSpeciesGrouped(speciesOnboard, ['ANZ', 'HKE', 'ATJ'])

// Then
expect(groupedSpeciesOnboard).toHaveLength(3)
expect(groupedSpeciesOnboard[0]?.speciesCode).toEqual('HKE')
expect(groupedSpeciesOnboard[0]?.controlledWeight).toEqual(500)
expect(groupedSpeciesOnboard[1]?.speciesCode).toEqual('OTH')
expect(groupedSpeciesOnboard[1]?.declaredWeight).toEqual(182.56)
expect(groupedSpeciesOnboard[2]?.speciesCode).toEqual('ANZ')
expect(groupedSpeciesOnboard[2]?.declaredWeight).toEqual(12.6)
})

it('getJDPCsvMap Should be dynamically generated with species, infractions and control comment for WESTERN_WATERS', async () => {
// When
const csvMap = getJDPCsvMap(JDP_CSV_MAP_BASE, JDP.WESTERN_WATERS, ['ANZ', 'HKE'])
const csvMap = getJDPCsvMap(JDP_CSV_MAP_BASE, JDP.WESTERN_WATERS)

// Then
expect(Object.keys(csvMap)).toHaveLength(91)
Expand Down Expand Up @@ -67,7 +94,7 @@ describe('utils', () => {

it('getJDPCsvMap Should be dynamically generated with species, infractions and control comment for MEDITERRANEAN_AND_EASTERN_ATLANTIC', async () => {
// When
const csvMap = getJDPCsvMap(JDP_CSV_MAP_BASE, JDP.MEDITERRANEAN_AND_EASTERN_ATLANTIC, [])
const csvMap = getJDPCsvMap(JDP_CSV_MAP_BASE, JDP.MEDITERRANEAN_AND_EASTERN_ATLANTIC)

// Then
expect(Object.keys(csvMap)).toHaveLength(91)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { monitorfishApi } from '../../../../api/api'
import { monitorfishApi } from '@api/api'

import type { ActivityReport } from './types'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { customDayjs } from '@mtes-mct/monitor-ui'
import { toAlpha3 } from 'i18n-iso-countries'

import { formatDMDCoordinateForActivityReport, getPatrolType } from './utils'
import { getCoordinates } from '../../../../coordinates'
import { CoordinatesFormat, WSG84_PROJECTION } from '../../../../domain/entities/map/constants'
import { formatDMDCoordinateForActivityReport, getPatrolType } from '../../utils'

import type { ActivityReportWithId } from './types'
import type { DownloadAsCsvMap } from '../../../../utils/downloadAsCsv'
import type { ActivityReportWithId } from '../../types'
import type { DownloadAsCsvMap } from '@utils/downloadAsCsv'

/* eslint-disable sort-keys-fix/sort-keys-fix */
export const JDP_CSV_MAP_BASE: DownloadAsCsvMap<ActivityReportWithId> = {
patrolCode: {
label: 'PATROL_CODE',
transform: activity => getPatrolType(activity) + (activity.controlUnits[0]?.name || '')
transform: activity => getPatrolType(activity) + (activity.controlUnits[0]?.name ?? '')
},
patrolType: {
label: 'PATROL_TYPE',
transform: activity => getPatrolType(activity)
},
controlUnit: {
label: 'MEAN_ID',
transform: activity => activity.controlUnits[0]?.name || ''
transform: activity => activity.controlUnits[0]?.name ?? ''
},
jdpCode: 'JDP_CODE',
eventType: {
Expand Down Expand Up @@ -85,15 +85,15 @@ export const JDP_CSV_MAP_BASE: DownloadAsCsvMap<ActivityReportWithId> = {
meshSize: {
label: 'MESH_SIZE',
transform: activity =>
activity.action.gearOnboard[0]?.controlledMesh || activity.action.gearOnboard[0]?.declaredMesh || ''
activity.action.gearOnboard[0]?.controlledMesh ?? (activity.action.gearOnboard[0]?.declaredMesh || '')
},
faoArea: {
label: 'FAO_AREA_CODE',
transform: activity => activity.action.faoAreas[0] || ''
transform: activity => activity.action.faoAreas[0] ?? ''
},
fleetSegment: {
label: 'FLEET_SEGMENT',
transform: activity => activity.action.segments[0]?.segment || ''
transform: activity => activity.action.segments[0]?.segment ?? ''
},
latitude: {
label: 'LA',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import {
Accent,
Button,
Expand All @@ -11,9 +12,8 @@ import {
import { useState } from 'react'
import styled from 'styled-components'

import { JDP } from './constants'
import { downloadActivityReports, NO_ACTIVITY_REPORT } from './useCases/downloadActivityReports'
import { useMainAppDispatch } from '../../../../hooks/useMainAppDispatch'
import { JDP } from '../../constants'
import { downloadActivityReports, NO_ACTIVITY_REPORT } from '../../useCases/downloadActivityReports'

import type { Promisable } from 'type-fest'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export enum JDP {
WESTERN_WATERS = 'JDP WW-01'
}

export const NOT_TARGETED_SPECIES_CODE = 'OTH'
export const UNTARGETED_SPECIES_CODE = 'OTH'
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Vessel } from '../../../../domain/entities/vessel/types'
import type { LegacyControlUnit } from '../../../../domain/types/legacyControlUnit'
import type { MissionAction } from '../../../../domain/types/missionAction'
import type { Vessel } from '../../domain/entities/vessel/types'
import type { LegacyControlUnit } from '../../domain/types/legacyControlUnit'
import type { MissionAction } from '../../domain/types/missionAction'

export type ActivityReports = {
activityReports: ActivityReport[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { customDayjs, logSoftError } from '@mtes-mct/monitor-ui'
import { sortBy } from 'lodash'
import { downloadAsCsv } from '@utils/downloadAsCsv'

import { downloadAsCsv } from '../../../../../utils/downloadAsCsv'
import { activityReportApi } from '../apis'
import { JDP_CSV_MAP_BASE } from '../components/ExportActivityReportsDialog/csvMap'
import { JDP } from '../constants'
import { JDP_CSV_MAP_BASE } from '../csvMap'
import { getJDPCsvMap } from '../utils'
import { getJDPCsvMap, getSpeciesOnboardWithUntargetedSpeciesGrouped } from '../utils'

import type { ActivityReports } from '../types'

Expand All @@ -30,14 +29,13 @@ export const downloadActivityReports = (afterDateTime: string, beforeDateTime: s
...activity,
action: {
...activity.action,
// We sort species by weight as only 10 species columns are contained in the CSV
speciesOnboard: sortBy(activity.action.speciesOnboard, ({ declaredWeight }) => declaredWeight).reverse()
speciesOnboard: getSpeciesOnboardWithUntargetedSpeciesGrouped(activity.action.speciesOnboard, jdpSpecies)
},
id: index
}))
const fileName = getCsvFileName(jdp)

const csvMap = getJDPCsvMap(JDP_CSV_MAP_BASE, jdp, jdpSpecies)
const csvMap = getJDPCsvMap(JDP_CSV_MAP_BASE, jdp)
downloadAsCsv(fileName, activityReportsWithId, csvMap)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { range } from 'lodash'
import { range, sortBy } from 'lodash'

import { JDP, NOT_TARGETED_SPECIES_CODE } from './constants'
import { MissionAction } from '../../../../domain/types/missionAction'
import { JDP, UNTARGETED_SPECIES_CODE } from './constants'
import { MissionAction } from '../../domain/types/missionAction'

import type { ActivityReportWithId } from './types'
import type { DownloadAsCsvMap } from '../../../../utils/downloadAsCsv'
import type { DownloadAsCsvMap } from '@utils/downloadAsCsv'

export function formatDMDCoordinateForActivityReport(coordinate: string | undefined): string {
const hemisphere = coordinate?.at(-1)
Expand All @@ -17,7 +17,10 @@ export function formatDMDCoordinateForActivityReport(coordinate: string | undefi
return `${hemisphere}${nextCoordinate}`
}

export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>, jdp: JDP, jdpSpecies: string[]) {
/**
* Adds 'SPECIES' related columns, 'INFR' related columns and 'COMMENT' column to JDP_CSV_MAP_BASE
*/
export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>, jdp: JDP) {
const numberOfSpeciesColumns = 10
const numberOfInfractionColumns = 10

Expand All @@ -33,10 +36,6 @@ export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>,
return ''
}

if (!jdpSpecies.includes(speciesOnboard.speciesCode)) {
return NOT_TARGETED_SPECIES_CODE
}

return speciesOnboard.speciesCode
}
}
Expand All @@ -47,7 +46,7 @@ export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>,
transform: activity => {
const speciesOnboard = activity.action.speciesOnboard[count - 1]

return speciesOnboard?.controlledWeight || speciesOnboard?.declaredWeight || ''
return speciesOnboard?.controlledWeight ?? speciesOnboard?.declaredWeight ?? ''
}
}

Expand All @@ -57,7 +56,7 @@ export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>,
transform: activity => {
const speciesOnboard = activity.action.speciesOnboard[count - 1]

return speciesOnboard?.nbFish || ''
return speciesOnboard?.nbFish ?? ''
}
}
})
Expand All @@ -74,7 +73,7 @@ export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>,
transform: activity => {
const allNatinfs = getInfractionsKeys(activity.action, 'natinf')

return allNatinfs[count - 1] || ''
return allNatinfs[count - 1] ?? ''
}
}

Expand All @@ -84,7 +83,7 @@ export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>,
transform: activity => {
const allComments = getInfractionsKeys(activity.action, 'comments')

return allComments[count - 1] || ''
return allComments[count - 1] ?? ''
}
}
})
Expand All @@ -95,6 +94,31 @@ export function getJDPCsvMap(baseCsvMap: DownloadAsCsvMap<ActivityReportWithId>,
return baseCsvMap
}

export function getSpeciesOnboardWithUntargetedSpeciesGrouped(
speciesOnboard: MissionAction.SpeciesControl[],
jdpSpecies: string[]
): MissionAction.SpeciesControl[] {
const otherSpeciesSummedWeight = speciesOnboard
.filter(species => !jdpSpecies.includes(species.speciesCode))
.map(species => species.controlledWeight ?? species.declaredWeight)
.filter((species): species is number => species !== undefined)
.reduce((accumulator, currentValue) => accumulator + currentValue, 0)

const otherSpecy = {
controlledWeight: undefined,
declaredWeight: otherSpeciesSummedWeight,
nbFish: undefined,
speciesCode: UNTARGETED_SPECIES_CODE,
underSized: undefined
}

const speciesOnboardWithoutOtherSpecies = speciesOnboard.filter(species => jdpSpecies.includes(species.speciesCode))

const groupedSpeciesOnboard = speciesOnboardWithoutOtherSpecies.concat(otherSpecy)

return sortBy(groupedSpeciesOnboard, ({ declaredWeight }) => declaredWeight).reverse()
}

function getInfractionsKeys(action: MissionAction.MissionAction, key: string): string[] {
return ([] as string[]).concat.apply(
[],
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/features/SideWindow/MissionList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useCallback, useState } from 'react'
import styled from 'styled-components'

import { MISSION_LIST_SUB_MENU_OPTIONS, MISSION_LIST_TABLE_OPTIONS } from './constants'
import { ExportActivityReportsDialog } from './ExportActivityReportsDialog'
import { FilterBar } from './FilterBar'
import { hasSomeOngoingActions, renderStatus } from './utils'
import { SEA_FRONT_GROUP_SEA_FRONTS, SeaFrontGroup } from '../../../domain/entities/seaFront/constants'
Expand All @@ -14,6 +13,7 @@ import { useMainAppSelector } from '../../../hooks/useMainAppSelector'
import { useTable } from '../../../hooks/useTable'
import { EmptyCardTable } from '../../../ui/card-table/EmptyCardTable'
import { NoRsuiteOverrideWrapper } from '../../../ui/NoRsuiteOverrideWrapper'
import { ExportActivityReportsDialog } from '../../ActivityReport/components/ExportActivityReportsDialog'
import { useGetFilteredMissionsQuery } from '../../Mission/components/MissionList/hooks/useGetFilteredMissionsQuery'
import { missionListActions } from '../../Mission/components/MissionList/slice'
import { addMission } from '../../Mission/useCases/addMission'
Expand Down
Loading