diff --git a/frontend/src/pages/TimeClockPage.jsx b/frontend/src/pages/TimeClockPage.jsx index 61518df..ecd0f1c 100644 --- a/frontend/src/pages/TimeClockPage.jsx +++ b/frontend/src/pages/TimeClockPage.jsx @@ -195,6 +195,9 @@ const TimeClockPage = () => { .slice(0, 5), ); + const [conflictDate, setConflictDate] = useState(getTodayValue()); + const [resolvingConflict, setResolvingConflict] = useState(false); + const [ error, setError, @@ -1212,6 +1215,10 @@ const TimeClockPage = () => { nowTime, ); + setConflictDate( + scanError.scanDate || getTodayValue(), + ); + setScanConflict({ code, type: @@ -1254,7 +1261,7 @@ const TimeClockPage = () => { 'Une entrée est déjà ouverte', confirmationMessage: - 'Vous avez déjà pointer une entrée, voulez vous saisir son heure de sortie ?', + 'Une entrée est déjà ouverte. Voulez-vous indiquer sa date et son heure de sortie, puis enregistrer la nouvelle entrée ?', timeLabel: 'Heure de sortie', @@ -1273,7 +1280,7 @@ const TimeClockPage = () => { 'Aucune entrée ouverte', confirmationMessage: - 'Vous n\avez pas pointer d\'entrée, voulez vous poursuivre et indiquer l\'heure d\'entrée ?', + 'Aucune entrée ouverte. Voulez-vous indiquer la date et l’heure de l’entrée manquante, puis enregistrer cette sortie ?', timeLabel: "Heure d'entrée", @@ -1292,7 +1299,7 @@ const TimeClockPage = () => { 'Une sortie sans entrée existe', confirmationMessage: - "Voulez-vous renseigner l’heure d’entrée ?", + "Voulez-vous indiquer la date et l’heure de l’entrée manquante, puis enregistrer le nouveau pointage ?", timeLabel: "Heure d'entrée", @@ -1328,7 +1335,7 @@ const TimeClockPage = () => { const resolveScanConflict = async () => { - if (!scanConflict) { + if (!scanConflict || resolvingConflict) { return; } @@ -1339,14 +1346,28 @@ const TimeClockPage = () => { return; } + if (!conflictDate || !conflictTime) { + setError('Indiquez la date et l’heure du pointage manquant.'); + return; + } + + if (scanConflict.scanDate && conflictDate > scanConflict.scanDate) { + setError('Le pointage manquant ne peut pas être postérieur au scan.'); + return; + } + setError(''); + setResolvingConflict(true); + + let resolved = false; + try { const options = { resolution: config.resolution, time: conflictTime, - scan_date: scanConflict.scanDate, + scan_date: conflictDate, entry_id: scanConflict.entryId, }; @@ -1357,25 +1378,39 @@ const TimeClockPage = () => { scanConflict.scanTime; } - const response = - await timeApi.scanTimeEntry( - scanConflict.code, - options, - ); + await timeApi.scanTimeEntry(scanConflict.code, options); + resolved = true; - setScanMessage( - response.message, + // La résolution ne rejoue pas le scan qui a déclenché le conflit. + const scanOptions = {}; + if (scanConflict.scanDate) { + scanOptions.scan_date = scanConflict.scanDate; + } + if (scanConflict.scanTime) { + scanOptions.scan_time = scanConflict.scanTime; + } + const response = await timeApi.scanTimeEntry( + scanConflict.code, + scanOptions, ); + setScanMessage(response.message || 'Pointage enregistré.'); setScanConflict(null); - await loadTimeEntries(); } catch ( resolutionError ) { + if (resolved) { + setScanConflict(null); + await loadTimeEntries(); + } setError( - resolutionError.message, + resolved + ? `Le conflit a été résolu, mais le nouveau pointage n’a pas été enregistré : ${resolutionError.message}` + : resolutionError.message, ); + } finally { + setResolvingConflict(false); } }; @@ -1950,6 +1985,17 @@ const TimeClockPage = () => {

+ + + +
@@ -2780,4 +2828,4 @@ const TimeClockPage = () => { ); }; -export default TimeClockPage; \ No newline at end of file +export default TimeClockPage;