Skip to content

Commit

Permalink
Préavis – Ajouter des pastilles indiquant le nombre de préavis à véri…
Browse files Browse the repository at this point in the history
…fier (#3447)

## Linked issues

- Resolve #3427

----

- [ ] Tests E2E (Cypress)
  • Loading branch information
louptheron authored Aug 1, 2024
2 parents a2c7b24 + 61fb80b commit 0554202
Show file tree
Hide file tree
Showing 46 changed files with 574 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ interface LogbookReportRepository {
isVerified: Boolean,
)

fun findAllPriorNotificationsToVerify(): List<PriorNotification>

fun updatePriorNotificationNote(reportId: String, operationDate: ZonedDateTime, note: String?)

// For test purpose
fun deleteAll()
fun updatePriorNotificationNote(reportId: String, operationDate: ZonedDateTime, note: String?)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ interface ManualPriorNotificationRepository {
fun save(newOrNextPriorNotification: PriorNotification): PriorNotification

fun updateState(reportId: String, isBeingSent: Boolean, isVerified: Boolean)

fun findAllToVerify(): List<PriorNotification>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.facade.SeafrontGroup
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationStats
import fr.gouv.cnsp.monitorfish.domain.repositories.*

@UseCase
class GetNumberToVerify(
private val logbookReportRepository: LogbookReportRepository,
private val manualPriorNotificationRepository: ManualPriorNotificationRepository,
private val portRepository: PortRepository,
private val riskFactorRepository: RiskFactorRepository,
private val vesselRepository: VesselRepository,
) {
fun execute(): PriorNotificationStats {
val allPorts = portRepository.findAll()
val allRiskFactors = riskFactorRepository.findAll()
val allVessels = vesselRepository.findAll()

val automaticPriorNotifications = logbookReportRepository.findAllPriorNotificationsToVerify()
val manualPriorNotifications = manualPriorNotificationRepository.findAllToVerify()
val incompletePriorNotifications = automaticPriorNotifications + manualPriorNotifications

val undeletedPriorNotifications = incompletePriorNotifications
.filter { !it.logbookMessageTyped.logbookMessage.isDeleted }

val priorNotifications = undeletedPriorNotifications
.map { priorNotification ->
priorNotification.enrich(allPorts, allRiskFactors, allVessels, priorNotification.isManuallyCreated)

priorNotification
}

return PriorNotificationStats(
perSeafrontGroupCount = SeafrontGroup.entries.associateWith { seafrontGroupEntry ->
priorNotifications.count { priorNotification ->
seafrontGroupEntry.hasSeafront(priorNotification.seafront)
}
},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PriorNotificationController(
private val createOrUpdateManualPriorNotification: CreateOrUpdateManualPriorNotification,
private val getPriorNotification: GetPriorNotification,
private val getPriorNotifications: GetPriorNotifications,
private val getNumberToVerify: GetNumberToVerify,
private val getPriorNotificationTypes: GetPriorNotificationTypes,
private val updatePriorNotificationNote: UpdatePriorNotificationNote,
private val verifyAndSendPriorNotification: VerifyAndSendPriorNotification,
Expand Down Expand Up @@ -125,6 +126,14 @@ class PriorNotificationController(
)
}

@GetMapping("/to_verify")
@Operation(summary = "Get number of prior notifications to verify")
fun getNumberToVerify(): PriorNotificationsExtraDataOutput {
val priorNotificationStats = getNumberToVerify.execute()

return PriorNotificationsExtraDataOutput.fromPriorNotificationStats(priorNotificationStats)
}

@PostMapping("/manual/compute")
@Operation(summary = "Calculate manual prior notification fleet segments, prior notification types and risk factor")
fun getManualComputation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class CaffeineConfiguration {
val nextLogbook = "next_logbook"
val previousLogbook = "previous_logbook"
val pnoTypes = "pno_types"
val pnoToVerify = "pno_to_verify"
val manualPnoToVerify = "manual_pno_to_verify"

// Missions
val missionControlUnits = "mission_control_units"
Expand Down Expand Up @@ -108,6 +110,8 @@ class CaffeineConfiguration {
val nextLogbookCache = buildMinutesCache(nextLogbook, ticker, 10)
val previousLogbookCache = buildMinutesCache(previousLogbook, ticker, 10)

val pnoToVerifyCache = buildMinutesCache(pnoToVerify, ticker, 5)
val manualPnoToVerifyCache = buildMinutesCache(manualPnoToVerify, ticker, 5)
val pnoTypesCache = buildMinutesCache(pnoTypes, ticker, 123)

// Missions
Expand Down Expand Up @@ -176,6 +180,8 @@ class CaffeineConfiguration {
missionControlUnitsCache,
nextLogbookCache,
pnoTypesCache,
pnoToVerifyCache,
manualPnoToVerifyCache,
portCache,
portsCache,
previousLogbookCache,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import fr.gouv.cnsp.monitorfish.domain.repositories.LogbookReportRepository
import fr.gouv.cnsp.monitorfish.infrastructure.database.entities.LogbookReportEntity
import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.interfaces.DBLogbookReportRepository
import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.utils.toSqlArrayString
import fr.gouv.cnsp.monitorfish.utils.CustomZonedDateTime
import jakarta.transaction.Transactional
import org.slf4j.LoggerFactory
import org.springframework.cache.annotation.CacheEvict
import org.springframework.cache.annotation.Cacheable
import org.springframework.dao.EmptyResultDataAccessException
import org.springframework.data.domain.PageRequest
Expand Down Expand Up @@ -63,6 +65,42 @@ class JpaLogbookReportRepository(
}
}

@Cacheable(value = ["pno_to_verify"])
override fun findAllPriorNotificationsToVerify(): List<PriorNotification> {
val allLogbookReportModels = dbLogbookReportRepository.findAllEnrichedPnoReferencesAndRelatedOperations(
flagStates = emptyList(),
hasOneOrMoreReportings = null,
isLessThanTwelveMetersVessel = null,
lastControlledAfter = null,
lastControlledBefore = null,
portLocodes = emptyList(),
priorNotificationTypesAsSqlArrayString = null,
searchQuery = null,
specyCodesAsSqlArrayString = null,
tripGearCodesAsSqlArrayString = null,
tripSegmentCodesAsSqlArrayString = null,
willArriveAfter = CustomZonedDateTime(ZonedDateTime.now()).toString(),
willArriveBefore = CustomZonedDateTime(ZonedDateTime.now().plusHours(24)).toString(),
)

return mapToReferenceWithRelatedModels(allLogbookReportModels)
.mapNotNull { (referenceLogbookReportModel, relatedLogbookReportModels) ->
try {
referenceLogbookReportModel.toPriorNotification(objectMapper, relatedLogbookReportModels)
} catch (e: Exception) {
logger.warn(
"Error while converting logbook report models to prior notifications (reportId = ${referenceLogbookReportModel.reportId}).",
e,
)

null
}
}.filter {
it.logbookMessageTyped.typedMessage.isInVerificationScope == true &&
it.logbookMessageTyped.typedMessage.isVerified == false
}
}

override fun findPriorNotificationByReportId(reportId: String, operationDate: ZonedDateTime): PriorNotification? {
val allLogbookReportModels = dbLogbookReportRepository.findEnrichedPnoReferenceAndRelatedOperationsByReportId(
reportId,
Expand Down Expand Up @@ -318,6 +356,7 @@ class JpaLogbookReportRepository(
}

@Transactional
@CacheEvict(value = ["pno_to_verify"], allEntries = true)
override fun updatePriorNotificationState(
reportId: String,
operationDate: ZonedDateTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ import fr.gouv.cnsp.monitorfish.domain.repositories.ManualPriorNotificationRepos
import fr.gouv.cnsp.monitorfish.infrastructure.database.entities.ManualPriorNotificationEntity
import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.interfaces.DBManualPriorNotificationRepository
import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.utils.toSqlArrayString
import fr.gouv.cnsp.monitorfish.utils.CustomZonedDateTime
import org.springframework.cache.annotation.CacheEvict
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional
import java.time.ZonedDateTime
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
Expand Down Expand Up @@ -43,6 +47,30 @@ class JpaManualPriorNotificationRepository(
).map { it.toPriorNotification() }
}

@Cacheable(value = ["manual_pno_to_verify"])
override fun findAllToVerify(): List<PriorNotification> {
return dbManualPriorNotificationRepository
.findAll(
flagStates = emptyList(),
hasOneOrMoreReportings = null,
lastControlledAfter = null,
lastControlledBefore = null,
portLocodes = emptyList(),
priorNotificationTypesAsSqlArrayString = null,
searchQuery = null,
specyCodesAsSqlArrayString = null,
tripGearCodesAsSqlArrayString = null,
tripSegmentCodesAsSqlArrayString = null,
willArriveAfter = CustomZonedDateTime(ZonedDateTime.now()).toString(),
willArriveBefore = CustomZonedDateTime(ZonedDateTime.now().plusHours(24)).toString(),
).filter {
it.value.isInVerificationScope == true && it.value.isVerified == false
}
.map {
it.toPriorNotification()
}
}

override fun findByReportId(reportId: String): PriorNotification? {
return dbManualPriorNotificationRepository.findByReportId(reportId)?.toPriorNotification()
}
Expand All @@ -63,6 +91,7 @@ class JpaManualPriorNotificationRepository(
}

@Transactional
@CacheEvict(value = ["manual_pno_to_verify"], allEntries = true)
override fun updateState(reportId: String, isBeingSent: Boolean, isVerified: Boolean) {
val manualPriorNotificationEntity =
dbManualPriorNotificationRepository.findByReportId(reportId) ?: throw BackendUsageException(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import com.nhaarman.mockitokotlin2.given
import fr.gouv.cnsp.monitorfish.domain.entities.facade.SeafrontGroup
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessage
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookMessageTyped
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookOperationType
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.LogbookTransmissionFormat
import fr.gouv.cnsp.monitorfish.domain.entities.logbook.messages.PNO
import fr.gouv.cnsp.monitorfish.domain.entities.port.Port
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotification
import fr.gouv.cnsp.monitorfish.domain.repositories.*
import org.assertj.core.api.Assertions.assertThat
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.ZonedDateTime

@ExtendWith(SpringExtension::class)
class GetNumberToVerifyUTests {
@MockBean
private lateinit var logbookReportRepository: LogbookReportRepository

@MockBean
private lateinit var manualPriorNotificationRepository: ManualPriorNotificationRepository

@MockBean
private lateinit var portRepository: PortRepository

@MockBean
private lateinit var riskFactorRepository: RiskFactorRepository

@MockBean
private lateinit var vesselRepository: VesselRepository

@Test
fun `execute Should return a map of PNO for each facade to verify`() {
// Given
given(portRepository.findAll()).willReturn(
listOf(
Port("AEFJR", "Al Jazeera Port", facade = "NAMO"),
Port("AEFAT", "Al Jazeera Port", facade = "Guyane"),
Port("AEJAZ", "Arzanah Island", facade = "SA"),
),
)
given(logbookReportRepository.findAllPriorNotificationsToVerify()).willReturn(
listOf(
PriorNotification(
reportId = "FAKE_REPORT_ID_1",
authorTrigram = null,
createdAt = null,
didNotFishAfterZeroNotice = false,
isManuallyCreated = false,
logbookMessageTyped = LogbookMessageTyped(
clazz = PNO::class.java,
logbookMessage = LogbookMessage(
id = 1,
reportId = "FAKE_REPORT_ID_1",
referencedReportId = null,
integrationDateTime = ZonedDateTime.now(),
isCorrectedByNewerMessage = false,
isDeleted = false,
isEnriched = false,
message = PNO().apply { port = "AEFJR" },
operationDateTime = ZonedDateTime.now(),
operationNumber = "1",
operationType = LogbookOperationType.DAT,
reportDateTime = ZonedDateTime.now(),
transmissionFormat = LogbookTransmissionFormat.ERS,
),
),
port = null,
reportingCount = null,
seafront = null,
sentAt = null,
state = null,
updatedAt = null,
vessel = null,
lastControlDateTime = null,
),

PriorNotification(
reportId = "FAKE_REPORT_ID_2",
authorTrigram = null,
createdAt = null,
didNotFishAfterZeroNotice = false,
isManuallyCreated = false,
logbookMessageTyped = LogbookMessageTyped(
clazz = PNO::class.java,
logbookMessage = LogbookMessage(
id = 1,
reportId = "FAKE_REPORT_ID_2_COR",
referencedReportId = "FAKE_NONEXISTENT_REPORT_ID_2",
integrationDateTime = ZonedDateTime.now(),
isCorrectedByNewerMessage = false,
isDeleted = false,
isEnriched = false,
message = PNO().apply { port = "AEFAT" },
operationDateTime = ZonedDateTime.now(),
operationNumber = "1",
operationType = LogbookOperationType.COR,
reportDateTime = ZonedDateTime.now(),
transmissionFormat = LogbookTransmissionFormat.ERS,
),
),
port = null,
reportingCount = null,
seafront = null,
sentAt = null,
state = null,
updatedAt = null,
vessel = null,
lastControlDateTime = null,
),
),
)

// When
val result = GetNumberToVerify(
logbookReportRepository,
manualPriorNotificationRepository,
portRepository,
riskFactorRepository,
vesselRepository,
).execute()

// Then
assertThat(result.perSeafrontGroupCount.values).hasSize(8)
assertThat(result.perSeafrontGroupCount[SeafrontGroup.ALL]).isEqualTo(2)
assertThat(result.perSeafrontGroupCount[SeafrontGroup.NAMO]).isEqualTo(1)
assertThat(result.perSeafrontGroupCount[SeafrontGroup.OUTREMEROA]).isEqualTo(1)
assertThat(result.perSeafrontGroupCount[SeafrontGroup.NONE]).isEqualTo(0)
}
}
Loading

0 comments on commit 0554202

Please sign in to comment.