diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/entities/mission/nav/crew/MissionCrewAbsenceEntity.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/entities/mission/nav/crew/MissionCrewAbsenceEntity.kt new file mode 100644 index 000000000..78c313eeb --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/entities/mission/nav/crew/MissionCrewAbsenceEntity.kt @@ -0,0 +1,40 @@ +package fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew + +import fr.gouv.dgampa.rapportnav.infrastructure.database.model.mission.crew.MissionCrewAbsenceModel +import fr.gouv.dgampa.rapportnav.infrastructure.database.model.mission.crew.MissionCrewModel +import java.time.Instant +import java.time.LocalDate + + +data class MissionCrewAbsenceEntity( + val id: Int? = null, + val startDate: LocalDate? = null, + val endDate: LocalDate? = null, + val isAbsentFullMission: Boolean? = null, + val reason: String? = null, +) { + + fun toMissionCrewAbsenceModel(crew: MissionCrewModel): MissionCrewAbsenceModel { + return MissionCrewAbsenceModel( + id = id, + startDate = startDate, + endDate = endDate, + isAbsentFullMission = isAbsentFullMission, + reason = reason, + missionCrew = crew + ) + } + + companion object { + fun fromMissionCrewAbsenceModel(model: MissionCrewAbsenceModel): MissionCrewAbsenceEntity { + return MissionCrewAbsenceEntity( + id = model.id, + startDate = model.startDate, + endDate = model.endDate, + isAbsentFullMission = model.isAbsentFullMission, + reason = model.reason, + ) + } + } +} + diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/entities/mission/nav/crew/MissionCrewEntity.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/entities/mission/nav/crew/MissionCrewEntity.kt index d414158a2..48c2993a0 100644 --- a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/entities/mission/nav/crew/MissionCrewEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/entities/mission/nav/crew/MissionCrewEntity.kt @@ -1,30 +1,31 @@ package fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew -import fr.gouv.dgampa.rapportnav.infrastructure.database.model.mission.crew.MissionCrewModel -import java.time.Instant import java.util.* - +import fr.gouv.dgampa.rapportnav.infrastructure.database.model.mission.crew.MissionCrewModel data class MissionCrewEntity( val id: Int? = null, - val agent: AgentEntity2, + val agent: AgentEntity2? = null, val comment: String? = null, val role: AgentRoleEntity? = null, val missionId: Int? = null, val missionIdUUID: UUID? = null, - val createdAt: Instant? = null, - val updatedAt: Instant? = null, + val fullName: String? = null, + val absences: List? = null ){ fun toMissionCrewModel(commentDefaultsToString: Boolean? = false): MissionCrewModel { - return MissionCrewModel( + var model = MissionCrewModel( id = id, missionId = missionId, - agent = agent.toAgentModel(), + agent = agent?.toAgentModel(), role = role?.toAgentRoleModel(), comment = if (comment == null && commentDefaultsToString == true) "" else comment, missionIdUUID = missionIdUUID, + fullName = fullName, ) + model.absences = absences?.map { it.toMissionCrewAbsenceModel(model) }?.toMutableList() ?: mutableListOf() + return model } companion object { @@ -34,11 +35,14 @@ data class MissionCrewEntity( missionId = crew.missionId, comment = crew.comment, missionIdUUID = crew.missionIdUUID, - agent = crew.agent.let { AgentEntity2.fromAgentModel(it) }, + agent = crew.agent?.let { AgentEntity2.fromAgentModel(it) }, role = crew.role?.let { AgentRoleEntity.fromAgentRoleModel(it) }, - createdAt = crew.createdAt, - updatedAt = crew.updatedAt + absences = crew.absences.map { MissionCrewAbsenceEntity.fromMissionCrewAbsenceModel(it) }, + fullName = crew.fullName, ) } } } + + + diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/ExportMissionRapportPatrouille.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/ExportMissionRapportPatrouille.kt index 7b9963b6c..57a4dd3bd 100644 --- a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/ExportMissionRapportPatrouille.kt +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/ExportMissionRapportPatrouille.kt @@ -124,14 +124,18 @@ class ExportMissionRapportPatrouille( val crew: List> = listOf( listOf("Fonction", "Nom", "Observation (formation, repos, mission, stage...)") - ) + agentsCrew.map { + ) + agentsCrew.map { row -> + val displayName = row.agent?.let { "${it.firstName} ${it.lastName}" } + ?: row.fullName // fallback when agent == null + listOf( - it.role?.title, - "${it.agent.firstName} ${it.agent.lastName}", - it.comment.takeIf { comment -> !comment.isNullOrEmpty() } ?: "Présent" + row.role?.title, + displayName, + row.comment.takeIf { !it.isNullOrEmpty() } ?: "Présent" ) } + // to combine // Bilan opérationnel val proFishingSeaSummary = getMissionOperationalSummary.getProFishingSeaSummary(mission) diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle.kt index d20655165..273763adc 100644 --- a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle.kt +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle.kt @@ -131,14 +131,18 @@ class ExportMissionPatrolSingle( val crew: List> = listOf( listOf("Fonction", "Nom", "Observation (formation, repos, mission, stage...)") - ) + agentsCrew.map { + ) + agentsCrew.map { row -> + val displayName = row.agent?.let { "${it.firstName} ${it.lastName}" } + ?: row.fullName // fallback when agent == null + listOf( - it.role?.title, - "${it.agent.firstName} ${it.agent.lastName}", - it.comment.takeIf { comment -> !comment.isNullOrEmpty() } ?: "Présent" + row.role?.title, + displayName, + row.comment.takeIf { !it.isNullOrEmpty() } ?: "Présent" ) } + // Bilan opérationnel val proFishingSeaSummary = getMissionOperationalSummary.getProFishingSeaSummary(mission) val proFishingLandSummary = getMissionOperationalSummary.getProFishingLandSummary(mission) diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle2.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle2.kt index f8ffd8820..d951eb80d 100644 --- a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle2.kt +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/domain/use_cases/mission/export/v2/ExportMissionPatrolSingle2.kt @@ -80,15 +80,19 @@ class ExportMissionPatrolSingle2( val crew: List> = listOf( listOf("Fonction", "Nom", "Observation (formation, repos, mission, stage...)") - ) + missionCrew.orEmpty().map { + ) + missionCrew.orEmpty().map { row -> + val displayName = row.agent?.let { "${it.firstName} ${it.lastName}" } + ?: row.fullName // fallback when agent == null + listOf( - it.role?.title, - "${it.agent.firstName} ${it.agent.lastName}", - it.comment.takeIf { comment -> !comment.isNullOrEmpty() } ?: "Présent" + row.role?.title, + displayName, + row.comment.takeIf { !it.isNullOrEmpty() } ?: "Présent" ) } + // Bilan opérationnel val operationalSummary = patrolData?.operationalSummary val proFishingSeaSummary = operationalSummary?.proFishingSeaSummary diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/api/bff/model/crew/MissionCrew.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/api/bff/model/crew/MissionCrew.kt index 65339eb7d..f14995064 100644 --- a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/api/bff/model/crew/MissionCrew.kt +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/api/bff/model/crew/MissionCrew.kt @@ -2,14 +2,18 @@ package fr.gouv.dgampa.rapportnav.infrastructure.api.bff.model.crew import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew.MissionCrewEntity import java.util.UUID +import kotlin.collections.map +import kotlin.collections.orEmpty data class MissionCrew( val id: Int? = null, - val agent: Agent2, + val agent: Agent2? = null, val missionId: Int? = null, val comment: String? = null, val role: AgentRole? = null, - val missionIdUUID: UUID? = null + val missionIdUUID: UUID? = null, + val absences: List? = null, + var fullName: String? = null, ) { companion object { @@ -20,7 +24,9 @@ data class MissionCrew( agent = Agent2.fromAgentEntity(crew.agent)!!, role = crew.role?.let { AgentRole.fromAgentRoleEntity(it) }, comment = crew.comment, - missionIdUUID = crew.missionIdUUID + missionIdUUID = crew.missionIdUUID, + absences = crew.absences.orEmpty().map { MissionCrewAbsence.fromMissionCrewAbsenceEntity(it) }, + fullName = crew.fullName, ) } } @@ -28,11 +34,13 @@ data class MissionCrew( fun toMissionCrewEntity(missionIdUUID: UUID?= null, missionId: Int? = null): MissionCrewEntity { return MissionCrewEntity( id = if (id == 0 || id == null) null else id, - comment = comment, + missionIdUUID = missionIdUUID, + agent = agent?.toAgentEntity(), missionId = missionId, - agent = agent.toAgentEntity(), + comment = comment, role = role?.toAgentRoleEntity(), - missionIdUUID = missionIdUUID + absences = absences.orEmpty().map { it.toMissionCrewAbsenceEntity() }, + fullName = fullName, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/api/bff/model/crew/MissionCrewAbsence.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/api/bff/model/crew/MissionCrewAbsence.kt new file mode 100644 index 000000000..0b6082669 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/api/bff/model/crew/MissionCrewAbsence.kt @@ -0,0 +1,35 @@ +package fr.gouv.dgampa.rapportnav.infrastructure.api.bff.model.crew + +import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew.MissionCrewAbsenceEntity +import java.time.LocalDate + +data class MissionCrewAbsence( + val id: Int? = null, + val startDate: LocalDate? = null, + val endDate: LocalDate? = null, + val isAbsentFullMission: Boolean? = null, + val reason: String? = null, +) { + + companion object { + fun fromMissionCrewAbsenceEntity(crew: MissionCrewAbsenceEntity): MissionCrewAbsence { + return MissionCrewAbsence( + id = crew.id, + startDate = crew.startDate, + endDate = crew.endDate, + isAbsentFullMission = crew.isAbsentFullMission, + reason = crew.reason, + ) + } + } + + fun toMissionCrewAbsenceEntity(): MissionCrewAbsenceEntity { + return MissionCrewAbsenceEntity( + id = if (id == 0 || id == null) null else id, + startDate = startDate, + endDate = endDate, + isAbsentFullMission = isAbsentFullMission, + reason = reason, + ) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/model/mission/crew/MissionCrewAbsenceModel.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/model/mission/crew/MissionCrewAbsenceModel.kt new file mode 100644 index 000000000..f132cf0d1 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/model/mission/crew/MissionCrewAbsenceModel.kt @@ -0,0 +1,55 @@ +package fr.gouv.dgampa.rapportnav.infrastructure.database.model.mission.crew + +import com.fasterxml.jackson.annotation.JsonIgnore +import jakarta.persistence.* +import org.springframework.data.annotation.CreatedBy +import org.springframework.data.annotation.CreatedDate +import org.springframework.data.annotation.LastModifiedBy +import org.springframework.data.annotation.LastModifiedDate +import org.springframework.data.jpa.domain.support.AuditingEntityListener +import java.time.Instant +import java.time.LocalDate + +@Entity +@EntityListeners(AuditingEntityListener::class) +@Table(name = "mission_crew_absence") +class MissionCrewAbsenceModel( + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", unique = true, nullable = false) + var id: Int? = null, + + @Column(name = "start_date", nullable = true) + var startDate: LocalDate? = null, + + @Column(name = "end_date", nullable = true) + var endDate: LocalDate? = null, + + @Column(name = "is_absent_full_mission", nullable = true) + var isAbsentFullMission: Boolean? = null, + + @Column(name = "reason", nullable = true) + var reason: String? = null, + + @CreatedDate + @Column(name = "created_at", updatable = false) + var createdAt: Instant? = null, + + @LastModifiedDate + @Column(name = "updated_at") + var updatedAt: Instant? = null, + + @CreatedBy + @Column(name = "created_by", updatable = false) + var createdBy: Int? = null, + + @LastModifiedBy + @Column(name = "updated_by") + var updatedBy: Int? = null, +// + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "mission_crew_id", referencedColumnName = "id", nullable = true) + @JsonIgnore + var missionCrew: MissionCrewModel? = null, +) diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/model/mission/crew/MissionCrewModel.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/model/mission/crew/MissionCrewModel.kt index 6b0a2353c..606b68ffc 100644 --- a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/model/mission/crew/MissionCrewModel.kt +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/model/mission/crew/MissionCrewModel.kt @@ -19,12 +19,18 @@ class MissionCrewModel( var id: Int?, @ManyToOne - @JoinColumn(name = "agent_id") - var agent: AgentModel2, + @JoinColumn(name = "agent_id", nullable = true) + var agent: AgentModel2? = null, + + @Column(name = "full_name", nullable = true) + var fullName: String? = null, @Column(name = "mission_id", nullable = true) var missionId: Int? = null, + @Column(name = "mission_id_uuid", nullable = true) + var missionIdUUID: UUID? = null, + @Column(name = "comment", nullable = true) var comment: String? = null, @@ -32,9 +38,6 @@ class MissionCrewModel( @JoinColumn(name = "agent_role_id", nullable = true) var role: AgentRoleModel?, - @Column(name = "mission_id_uuid", nullable = true) - var missionIdUUID: UUID? = null, - @CreatedDate @Column(name = "created_at", nullable = true, updatable = false) var createdAt: Instant? = null, @@ -49,5 +52,13 @@ class MissionCrewModel( @LastModifiedBy @Column(name = "updated_by") - var updatedBy: Int? = null + var updatedBy: Int? = null, + + @OneToMany( + mappedBy = "missionCrew", + cascade = [CascadeType.ALL], + orphanRemoval = true + ) + var absences: MutableList = mutableListOf() + ) diff --git a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/repositories/mission/crew/JPAMissionCrewRepository.kt b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/repositories/mission/crew/JPAMissionCrewRepository.kt index e8da41434..60743353d 100644 --- a/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/repositories/mission/crew/JPAMissionCrewRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/dgampa/rapportnav/infrastructure/database/repositories/mission/crew/JPAMissionCrewRepository.kt @@ -32,8 +32,14 @@ class JPAMissionCrewRepository( override fun save(crew: MissionCrewEntity): MissionCrewModel { return try { val crewModel = crew.toMissionCrewModel() - val agent = dbAgentRepository.findById(crew.agent.id!!).orElseThrow() - crewModel.agent = agent + + if (crew.agent != null) { + val agent = dbAgentRepository.findById(crew.agent.id!!).orElseThrow() + crewModel.agent = agent + // TODO ask christian +// crewModel.fullName = listOf(crew.agent.firstName, crew.agent.lastName).joinToString(separator = " ") + } + if (crew.role !== null) { val role = dbAgentRoleRepository.findById(crew.role.id!!).orElseThrow() diff --git a/backend/src/main/resources/db/migration/V1.2026.01.10.08.12__create_table_mission_crew_absence.sql b/backend/src/main/resources/db/migration/V1.2026.01.10.08.12__create_table_mission_crew_absence.sql new file mode 100644 index 000000000..4072d88d2 --- /dev/null +++ b/backend/src/main/resources/db/migration/V1.2026.01.10.08.12__create_table_mission_crew_absence.sql @@ -0,0 +1,29 @@ +DO +$$ +BEGIN + CREATE TABLE IF NOT EXISTS public.mission_crew_absence ( + id SERIAL PRIMARY KEY, + mission_crew_id INTEGER NOT NULL REFERENCES public.mission_crew(id) ON DELETE CASCADE, + + start_date DATE, + end_date DATE, + is_absent_full_mission BOOLEAN, + reason TEXT, + + created_at TIMESTAMPTZ DEFAULT now(), + updated_at TIMESTAMPTZ, + created_by INTEGER, + updated_by INTEGER + ); + + -- Index for fast filtering by mission crew + CREATE INDEX IF NOT EXISTS idx_mission_crew_absence_crew_id + ON public.mission_crew_absence (mission_crew_id); + + + -- prevent overlapping absences for the same mission_crew + -- Requires btree_gist extension (safe to include) + CREATE EXTENSION IF NOT EXISTS btree_gist; + +END +$$; diff --git a/backend/src/main/resources/db/migration/V1.2026.01.10.10.12__update_mission_crew.sql b/backend/src/main/resources/db/migration/V1.2026.01.10.10.12__update_mission_crew.sql new file mode 100644 index 000000000..5850ad296 --- /dev/null +++ b/backend/src/main/resources/db/migration/V1.2026.01.10.10.12__update_mission_crew.sql @@ -0,0 +1,5 @@ + +ALTER TABLE public.mission_crew + ADD COLUMN IF NOT EXISTS full_name TEXT; + + diff --git a/backend/src/main/resources/wiremock/env/mission.json b/backend/src/main/resources/wiremock/env/mission.json index a2cae7e60..690bb6916 100644 --- a/backend/src/main/resources/wiremock/env/mission.json +++ b/backend/src/main/resources/wiremock/env/mission.json @@ -6,19 +6,19 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], diff --git a/backend/src/main/resources/wiremock/env/missions.json b/backend/src/main/resources/wiremock/env/missions.json index 76e3419ee..ea0f9d1a5 100644 --- a/backend/src/main/resources/wiremock/env/missions.json +++ b/backend/src/main/resources/wiremock/env/missions.json @@ -7,19 +7,19 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -51,39 +51,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -116,39 +116,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -180,39 +180,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -245,39 +245,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -308,39 +308,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -371,39 +371,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -435,39 +435,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -499,39 +499,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], @@ -562,39 +562,39 @@ ], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" }, { "id": 385, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Ostrea PM 437" }, { "id": 279, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Malprat – PM 457" }, { "id": 69, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Atys PM 432" }, { "id": 106, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Brizo – PM 480" }, { "id": 240, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Voiture" } ], diff --git a/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/domain/use_cases/mission/v2/GetMissionCrewTest.kt b/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/domain/use_cases/mission/v2/GetMissionCrewTest.kt index 9a323353f..d3b265f35 100644 --- a/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/domain/use_cases/mission/v2/GetMissionCrewTest.kt +++ b/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/domain/use_cases/mission/v2/GetMissionCrewTest.kt @@ -62,7 +62,7 @@ class GetMissionCrewTest { agent = agent1, role = role, missionId = missionId, - missionIdUUID = missionIdUUID + missionIdUUID = missionIdUUID, ), MissionCrewEntityMock.create( agent = agent2, @@ -79,7 +79,7 @@ class GetMissionCrewTest { oldServiceId = serviceId, generalInfo = generalInfos, missionId = missionId, - missionIdUUID = missionIdUUID + missionIdUUID = missionIdUUID, ) // Then diff --git a/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/mocks/mission/crew/MissionCrewEntityMock.kt b/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/mocks/mission/crew/MissionCrewEntityMock.kt index 72c9240cb..48a8f03b2 100644 --- a/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/mocks/mission/crew/MissionCrewEntityMock.kt +++ b/backend/src/test/kotlin/fr/gouv/gmampa/rapportnav/mocks/mission/crew/MissionCrewEntityMock.kt @@ -3,6 +3,7 @@ package fr.gouv.gmampa.rapportnav.mocks.mission.crew import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew.AgentEntity import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew.AgentEntity2 import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew.AgentRoleEntity +import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew.MissionCrewAbsenceEntity import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.crew.MissionCrewEntity import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.service.ServiceEntity import fr.gouv.dgampa.rapportnav.domain.entities.mission.nav.service.ServiceTypeEnum @@ -28,6 +29,7 @@ object MissionCrewEntityMock { ), missionId: Int? = null, missionIdUUID: UUID? = null, + absences: List? = listOf() ): MissionCrewEntity { return MissionCrewEntity( id = id, @@ -35,7 +37,8 @@ object MissionCrewEntityMock { comment = comment, role = role, missionId = missionId, - missionIdUUID = missionIdUUID + missionIdUUID = missionIdUUID, + absences = absences ) } } diff --git a/backend/src/test/resources/missions/mission.json b/backend/src/test/resources/missions/mission.json index 174411f1e..26152d326 100644 --- a/backend/src/test/resources/missions/mission.json +++ b/backend/src/test/resources/missions/mission.json @@ -3,14 +3,14 @@ "missionTypes": ["SEA"], "controlUnits": [ { - "id": 10225, + "id": 10080, "administration": "DDTM", "isArchived": false, "name": "ULAM 33", "resources": [ { "id": 1205, - "controlUnitId": 10225, + "controlUnitId": 10080, "name": "Edulis - PM 424" } ], diff --git a/frontend/src/features/common/types/crew-types.ts b/frontend/src/features/common/types/crew-types.ts deleted file mode 100644 index 177877788..000000000 --- a/frontend/src/features/common/types/crew-types.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Service - * represents - * ex: pam_X_bordée_A, ULAM33, GM - */ -export type Service = { - id: string - name: string -} - -/** - * Agent - * represents an actual human part of a crew - * it is linked to different services (mostly 1) - */ -export type Agent = { - id: string - firstName: string - lastName: string - services: Service[] -} - -/** - * AgentRole - * represents the function of a member of a crew - * such as captain, chief mecanic, ... - */ -export type AgentRole = { - id: string - title: string -} - -/** - * MissionCrew - * represents the actual crew of a mission - * there will be as many rows as there are crew members of a mission - */ -export type MissionCrew = { - id: string - agent?: Agent - comment?: string - role?: AgentRole -} diff --git a/frontend/src/v2/features/common/components/ui/formik-date-range-picker.tsx b/frontend/src/v2/features/common/components/ui/formik-date-range-picker.tsx index 17b2081bf..e4bbb476f 100644 --- a/frontend/src/v2/features/common/components/ui/formik-date-range-picker.tsx +++ b/frontend/src/v2/features/common/components/ui/formik-date-range-picker.tsx @@ -16,10 +16,19 @@ type FormikDateRangePickerProps = FormikDatePickerWithDateDateProps & { name: string validateOnSubmit?: boolean fieldFormik: FieldProps + withTime?: boolean + allowSameDate?: boolean } export const FormikDateRangePicker = styled( - ({ name, fieldFormik, validateOnSubmit, ...props }: FormikDateRangePickerProps) => { + ({ + name, + fieldFormik, + validateOnSubmit, + withTime = true, + allowSameDate = false, + ...props + }: FormikDateRangePickerProps) => { const [errors, setErrors] = useState>() const [initValue, setInitValue] = useState() @@ -45,7 +54,7 @@ export const FormikDateRangePicker = styled( onSubmit={handleSubmit} enableReinitialize validateOnChange={true} - validationSchema={simpleDateRangeValidationSchema} + validationSchema={simpleDateRangeValidationSchema({ allowSameDate })} > {({ validateForm }) => ( <> @@ -58,7 +67,13 @@ export const FormikDateRangePicker = styled( - +