Skip to content

Commit

Permalink
Préavis – Afficher la liste de diffusion (unités et leurs contacts) d…
Browse files Browse the repository at this point in the history
…ans les préavis et si la diffusion a réussi ou non (#3669)

## Cas non gérés

- La liste des inscrits est générée à partir de l'historique des
messages envoyés, cela veut donc dire qu'elle est vide tant qu'un
message n'a pas encore été envoyé.

## Linked issues

- Resolve #3598

## Screenshots


![image](https://github.com/user-attachments/assets/369d8c1a-d10d-4f70-882e-29bfe90c2689)

----

- [x] Tests E2E (Cypress)
  • Loading branch information
ivangabriele authored Oct 1, 2024
2 parents 81ec604 + b9ac0c6 commit b2534d8
Show file tree
Hide file tree
Showing 47 changed files with 3,049 additions and 2,758 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fr.gouv.cnsp.monitorfish.domain.entities.prior_notification

import java.time.ZonedDateTime

data class PriorNotificationSentMessage(
val id: Int,
val communicationMeans: String,
val dateTimeUtc: ZonedDateTime,
val errorMessage: String?,
val priorNotificationReportId: String?,
val priorNotificationSource: String,
val recipientAddressOrNumber: String,
val recipientName: String,
val recipientOrganization: String,
val success: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package fr.gouv.cnsp.monitorfish.domain.repositories

import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationSentMessage

interface PriorNotificationSentMessageRepository {
fun findAllByReportId(reportId: String): List<PriorNotificationSentMessage>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import fr.gouv.cnsp.monitorfish.config.UseCase
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationSentMessage
import fr.gouv.cnsp.monitorfish.domain.repositories.*

@UseCase
class GetPriorNotificationSentMessages(
private val priorNotificationSentMessageRepository: PriorNotificationSentMessageRepository,
) {
fun execute(reportId: String): List<PriorNotificationSentMessage> {
return priorNotificationSentMessageRepository.findAllByReportId(reportId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class PriorNotificationController(
private val deletePriorNotificationUpload: DeletePriorNotificationUpload,
private val getPriorNotification: GetPriorNotification,
private val getPriorNotificationPdfDocument: GetPriorNotificationPdfDocument,
private val getPriorNotificationSentMessages: GetPriorNotificationSentMessages,
private val getPriorNotificationUpload: GetPriorNotificationUpload,
private val getPriorNotificationUploads: GetPriorNotificationUploads,
private val getPriorNotifications: GetPriorNotifications,
Expand Down Expand Up @@ -374,6 +375,17 @@ class PriorNotificationController(
return PriorNotificationDataOutput.fromPriorNotification(updatedPriorNotification)
}

@GetMapping("/{reportId}/sent_messages")
@Operation(summary = "Get all sent messages for a given prior notification")
fun getSentMessages(
@PathParam("Logbook message `reportId`")
@PathVariable(name = "reportId")
reportId: String,
): List<PriorNotificationSentMessageDataOutput> {
return getPriorNotificationSentMessages.execute(reportId)
.map { PriorNotificationSentMessageDataOutput.fromPriorNotificationSentMessage(it) }
}

@GetMapping("/{reportId}/uploads/{priorNotificationUploadId}")
@Operation(summary = "Download a prior notification attachment")
fun getUploads(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class PriorNotificationDataOutput(
val operationDate: ZonedDateTime,
val state: PriorNotificationState?,
val riskFactor: Double?,
val vesselId: Int,
) {
companion object {
fun fromPriorNotification(priorNotification: PriorNotification): PriorNotificationDataOutput {
Expand Down Expand Up @@ -46,15 +47,14 @@ class PriorNotificationDataOutput(
null
}

val isLessThanTwelveMetersVessel =
val vessel =
requireNotNull(priorNotification.vessel) {
"`priorNotification.vessel` is null."
}.isLessThanTwelveMetersVessel()
val isVesselUnderCharter =
requireNotNull(priorNotification.vessel) {
"`priorNotification.vessel` is null."
}.underCharter
}
val isLessThanTwelveMetersVessel = vessel.isLessThanTwelveMetersVessel()
val isVesselUnderCharter = vessel.underCharter
val logbookMessage = priorNotification.logbookMessageAndValue.logbookMessage
val vesselId = vessel.id

val logbookMessageDataOutput = LogbookMessageDataOutput.fromLogbookMessage(logbookMessage)

Expand All @@ -71,6 +71,7 @@ class PriorNotificationDataOutput(
operationDate = logbookMessage.operationDateTime,
state = priorNotification.state,
riskFactor = priorNotification.logbookMessageAndValue.value.riskFactor,
vesselId = vesselId,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.outputs

import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationSentMessage
import java.time.ZonedDateTime

data class PriorNotificationSentMessageDataOutput(
val id: Int,
val communicationMeans: String,
val dateTimeUtc: ZonedDateTime,
val errorMessage: String?,
val recipientAddressOrNumber: String,
val recipientName: String,
val recipientOrganization: String,
val success: Boolean,
) {
companion object {
fun fromPriorNotificationSentMessage(
priorNotificationSentMessage: PriorNotificationSentMessage,
): PriorNotificationSentMessageDataOutput {
return PriorNotificationSentMessageDataOutput(
id = priorNotificationSentMessage.id,
communicationMeans = priorNotificationSentMessage.communicationMeans,
dateTimeUtc = priorNotificationSentMessage.dateTimeUtc,
errorMessage = priorNotificationSentMessage.errorMessage,
recipientAddressOrNumber = priorNotificationSentMessage.recipientAddressOrNumber,
recipientName = priorNotificationSentMessage.recipientName,
recipientOrganization = priorNotificationSentMessage.recipientOrganization,
success = priorNotificationSentMessage.success,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package fr.gouv.cnsp.monitorfish.infrastructure.database.entities

import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationSentMessage
import jakarta.persistence.*
import org.hibernate.annotations.Immutable
import java.time.ZonedDateTime

@Entity
@Immutable
@Table(name = "prior_notification_sent_messages")
data class PriorNotificationSentMessageEntity(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
val id: Int,
@Column(name = "communication_means", nullable = false)
val communicationMeans: String,
@Column(name = "date_time_utc", nullable = false)
val dateTimeUtc: ZonedDateTime,
@Column(name = "error_message", nullable = true)
val errorMessage: String?,
@Column(name = "prior_notification_report_id", nullable = false)
val priorNotificationReportId: String?,
@Column(name = "prior_notification_source", nullable = false)
val priorNotificationSource: String,
@Column(name = "recipient_address_or_number", nullable = false)
val recipientAddressOrNumber: String,
@Column(name = "recipient_name", nullable = false)
val recipientName: String,
@Column(name = "recipient_organization", nullable = false)
val recipientOrganization: String,
@Column(name = "success", nullable = false)
val success: Boolean,
) {
fun toPriorNotificationSentMessage(): PriorNotificationSentMessage {
return PriorNotificationSentMessage(
id = id,
communicationMeans = communicationMeans,
dateTimeUtc = dateTimeUtc,
errorMessage = errorMessage,
priorNotificationReportId = priorNotificationReportId,
priorNotificationSource = priorNotificationSource,
recipientAddressOrNumber = recipientAddressOrNumber,
recipientName = recipientName,
recipientOrganization = recipientOrganization,
success = success,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package fr.gouv.cnsp.monitorfish.infrastructure.database.repositories

import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationSentMessage
import fr.gouv.cnsp.monitorfish.domain.repositories.PriorNotificationSentMessageRepository
import fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.interfaces.DBPriorNotificationSentMessageRepository
import org.springframework.stereotype.Repository

@Repository
class JpaPriorNotificationSentMessageRepository(
private val dbPriorNotificationSentMessageRepository: DBPriorNotificationSentMessageRepository,
) : PriorNotificationSentMessageRepository {
override fun findAllByReportId(reportId: String): List<PriorNotificationSentMessage> {
return dbPriorNotificationSentMessageRepository
.findAllByReportId(reportId)
.map { it.toPriorNotificationSentMessage() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package fr.gouv.cnsp.monitorfish.infrastructure.database.repositories.interfaces

import fr.gouv.cnsp.monitorfish.infrastructure.database.entities.PriorNotificationSentMessageEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query

interface DBPriorNotificationSentMessageRepository : JpaRepository<PriorNotificationSentMessageEntity, String> {
@Query(
"""
SELECT *
FROM prior_notification_sent_messages
WHERE prior_notification_report_id = :reportId
""",
nativeQuery = true,
)
fun findAllByReportId(reportId: String): List<PriorNotificationSentMessageEntity>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DELETE FROM public.prior_notification_sent_messages;

ALTER TABLE public.prior_notification_sent_messages
ADD COLUMN recipient_name VARCHAR NOT NULL,
ADD COLUMN recipient_organization VARCHAR NOT NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
INSERT INTO public.prior_notification_sent_messages (
prior_notification_report_id, prior_notification_source, date_time_utc, communication_means, recipient_address_or_number, success, error_message, recipient_name, recipient_organization
) VALUES
( 'FAKE_OPERATION_103', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 1', 'Douane'),

( 'FAKE_OPERATION_106', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 1', 'Douane'),
( 'FAKE_OPERATION_106', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 3', 'Gendarmerie'),

( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.3 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 3', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 4', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.1 minutes', 'SMS', '+33123456789', FALSE, NULL, 'Unité 3', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.2 minutes', 'SMS', '+33987654321', FALSE, NULL, 'Unité 4', 'Gendarmerie'),

( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '4.0 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 3', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '4.1 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 4', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '4.2 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 5', 'DDTM 40'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '4.3 minutes', 'SMS', '+33123456789', TRUE, NULL, 'Unité 3', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '4.4 minutes', 'SMS', '+33987654321', FALSE, NULL, 'Unité 4', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '4.5 minutes', 'SMS', '+33000000000', FALSE, NULL, 'Unité 5', 'DDTM 40'),

( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '9.3 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 3', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '9.2 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 4', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '9.1 minutes', 'SMS', '+33123456789', TRUE, NULL, 'Unité 3', 'Gendarmerie'),
( 'FAKE_OPERATION_108', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '9.0 minutes', 'SMS', '+33987654321', TRUE, NULL, 'Unité 4', 'Gendarmerie'),

( 'FAKE_OPERATION_110', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 6', 'DDTM'),
( 'FAKE_OPERATION_110', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 7', 'Office Français de la Biodiversité'),
( 'FAKE_OPERATION_110', 'LOGBOOK', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'SMS', '+33111111111', FALSE, NULL, 'Unité 7', 'Office Français de la Biodiversité'),

('00000000-0000-4000-0000-000000000003', 'MANUAL', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 9', 'DDTM'),
('00000000-0000-4000-0000-000000000003', 'MANUAL', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 10', 'DIRM / DM'),

('00000000-0000-4000-0000-000000000004', 'MANUAL', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 11', 'DDTM'),

('00000000-0000-4000-0000-000000000006', 'MANUAL', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 11', 'DDTM'),

('00000000-0000-4000-0000-000000000008', 'MANUAL', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', FALSE, NULL, 'Unité 12', 'DIRM / DM'),

('00000000-0000-4000-0000-000000000010', 'MANUAL', NOW() AT TIME ZONE 'UTC' - INTERVAL '2.0 minutes', 'EMAIL', '[email protected]', TRUE, NULL, 'Unité 12', 'DIRM / DM');
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package fr.gouv.cnsp.monitorfish.domain.use_cases.prior_notification

import com.nhaarman.mockitokotlin2.given
import fr.gouv.cnsp.monitorfish.domain.entities.prior_notification.PriorNotificationSentMessage
import fr.gouv.cnsp.monitorfish.domain.repositories.PriorNotificationSentMessageRepository
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 GetPriorNotificationSentMessagesUTests {
@MockBean
private lateinit var priorNotificationSentMessageRepository: PriorNotificationSentMessageRepository

@Test
fun `execute Should return a list of prior notification types`() {
// Given
val fakeReportId = "FAKE_REPORT_ID"
given(priorNotificationSentMessageRepository.findAllByReportId(fakeReportId)).willReturn(
listOf(
PriorNotificationSentMessage(
id = 1,
communicationMeans = "EMAIL",
dateTimeUtc = ZonedDateTime.now(),
errorMessage = null,
priorNotificationReportId = fakeReportId,
priorNotificationSource = "LOGBOOK",
recipientAddressOrNumber = "[email protected]",
recipientName = "DREAL 01",
recipientOrganization = "DREAL",
success = true,
),
PriorNotificationSentMessage(
id = 2,
communicationMeans = "SMS",
dateTimeUtc = ZonedDateTime.now(),
errorMessage = null,
priorNotificationReportId = fakeReportId,
priorNotificationSource = "MANUAL",
recipientAddressOrNumber = "+33123456789",
recipientName = "DREAL 02",
recipientOrganization = "DREAL",
success = true,
),
),
)

// When
val result = GetPriorNotificationSentMessages(priorNotificationSentMessageRepository).execute(fakeReportId)

// Then
assertThat(result).hasSize(2)
assertThat(result[0].communicationMeans).isEqualTo("EMAIL")
assertThat(result[1].communicationMeans).isEqualTo("SMS")
}
}
Loading

0 comments on commit b2534d8

Please sign in to comment.