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

Préavis – Afficher la liste de diffusion (unités et leurs contacts) dans les préavis et si la diffusion a réussi ou non #3669

Merged
merged 31 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e42a9e0
Add GetPriorNotificationSentMessages use case
ivangabriele Sep 19, 2024
bee890c
Add unit & inte tests for pno sent messages in Backend
ivangabriele Sep 19, 2024
3e4cb6c
Add get pno sent messages route in Backend
ivangabriele Sep 19, 2024
6ba6582
Add unit test for get pno sent messages route in Backend
ivangabriele Sep 19, 2024
72ce82b
Clean naming in PriorNotificationSentMessageDataOutput
ivangabriele Sep 19, 2024
92f99dd
Add get pno sent messages route in Frontend
ivangabriele Sep 19, 2024
e576d03
Update prior_notification_sent_messages table
VincentAntoine Sep 25, 2024
3eb3e75
Extract administration from control units api response
VincentAntoine Sep 25, 2024
5c82ea6
Update ControlUnit entity
VincentAntoine Sep 25, 2024
755ff71
Change columns names
VincentAntoine Sep 26, 2024
998749e
Record pno recipents' name and organization
VincentAntoine Sep 26, 2024
5f2ea3b
Renumber migrations
VincentAntoine Sep 26, 2024
b06bce5
Fix test
VincentAntoine Sep 26, 2024
bb2ea40
Add recipient name & org to pno sent messages in Backend
ivangabriele Sep 27, 2024
34233a5
Dry pno card body head into shared component
ivangabriele Sep 27, 2024
3753c2c
Fix table height in pno list
ivangabriele Sep 27, 2024
ec815c1
Add vesselId prop to PriorNotificationDataOutput
ivangabriele Sep 27, 2024
f123d57
Add subscribers list & send statuses in pno form
ivangabriele Sep 30, 2024
7742922
Order sent messages batches by date desc in pno form
ivangabriele Sep 30, 2024
9c95ccb
Fix subscriber list style in pno form
ivangabriele Sep 30, 2024
0ee18d1
Limit sent messages data fetching to collapsed state in pno form
ivangabriele Sep 30, 2024
e787242
Add e2e tests for pno form sent message list
ivangabriele Sep 30, 2024
a93babb
Disable scroll in logbook pno form sent message list error e2e test
ivangabriele Sep 30, 2024
9c95ad9
Add unit tests for pno form sent message utils
ivangabriele Sep 30, 2024
0d86c8b
Use last sent messages batch to generate pno form subscriber list
ivangabriele Sep 30, 2024
ccb7718
Clean minor code patterns
ivangabriele Sep 30, 2024
718f221
Fix pno form sent message history sizes
ivangabriele Sep 30, 2024
e97ef98
Emphasize pno form failed sent message contact info in bold
ivangabriele Sep 30, 2024
4d529bc
Replace ternaries with function in CardBodyHead utils
ivangabriele Oct 1, 2024
7a9d597
Fix UTC dates in getSentMessagesBatches() Frontend util
ivangabriele Oct 1, 2024
b9ac0c6
Use early returns in getSentMessagesBatches() Frontend util
ivangabriele Oct 1, 2024
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
@@ -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
Loading