feat : ajout colonne Cumul sur l'écran RTT (#18)
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Affiche le solde RTT à la fin de chaque semaine (report N-1 + somme totalMinutes des semaines − paiements des mois antérieurs). Permet la comparaison ligne à ligne avec un suivi RH externe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: #18 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #18.
This commit is contained in:
@@ -313,6 +313,7 @@ Tous les filtres checkbox sont cochés par défaut à l'ouverture du drawer.
|
|||||||
- les heures payées sont soustraites du disponible RTT (`availableMinutes -= totalPaidMinutes`)
|
- les heures payées sont soustraites du disponible RTT (`availableMinutes -= totalPaidMinutes`)
|
||||||
- affichage: 2 lignes par mois dans le tableau (25% et 50%)
|
- affichage: 2 lignes par mois dans le tableau (25% et 50%)
|
||||||
- colonnes Total 25% et Total 50%: somme base + bonus de chaque tranche
|
- colonnes Total 25% et Total 50%: somme base + bonus de chaque tranche
|
||||||
|
- colonne Cumul (dernière colonne): solde RTT à la fin de chaque semaine = `report N-1 + somme totalMinutes des semaines jusqu'à celle-ci − paiements RTT des mois antérieurs au mois de la semaine`. Le paiement d'un mois M n'est déduit qu'à partir des semaines du mois M+1 (cohérent avec la logique de la ligne "Report mois précédent"). Permet la comparaison ligne à ligne avec un suivi RH externe (Excel)
|
||||||
- ligne Report N-1 (carry rollover): affichée en juin uniquement si carry > 0
|
- ligne Report N-1 (carry rollover): affichée en juin uniquement si carry > 0
|
||||||
- ligne Report mois précédent: solde cumulé (carry N-1 + semaines antérieures − paiements antérieurs), affichée à partir de juillet (masquée si nul)
|
- ligne Report mois précédent: solde cumulé (carry N-1 + semaines antérieures − paiements antérieurs), affichée à partir de juillet (masquée si nul)
|
||||||
- Reste = Report cumulé + Total du mois − Payé du mois (balance courante en fin de mois)
|
- Reste = Report cumulé + Total du mois − Payé du mois (balance courante en fin de mois)
|
||||||
|
|||||||
@@ -40,14 +40,15 @@
|
|||||||
<table class="w-full table-fixed border-collapse text-[18px]">
|
<table class="w-full table-fixed border-collapse text-[18px]">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col />
|
<col />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[10%]" />
|
||||||
|
<col class="w-[10%]" />
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -59,7 +60,8 @@
|
|||||||
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">Base</th>
|
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">Base</th>
|
||||||
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">50%</th>
|
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">50%</th>
|
||||||
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">Total 50%</th>
|
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">Total 50%</th>
|
||||||
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">Total</th>
|
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">Total</th>
|
||||||
|
<th class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">Cumul</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -73,6 +75,7 @@
|
|||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(summary!.carryBase50Minutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryBase50Minutes) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(summary!.carryBase50Minutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryBase50Minutes) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(summary!.carryBonus50Minutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryBonus50Minutes) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(summary!.carryBonus50Minutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryBonus50Minutes) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(summary!.carryBase50Minutes + summary!.carryBonus50Minutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryBase50Minutes + summary!.carryBonus50Minutes) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(summary!.carryBase50Minutes + summary!.carryBonus50Minutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryBase50Minutes + summary!.carryBonus50Minutes) }}</span></td>
|
||||||
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(summary!.carryFromPreviousYearMinutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryFromPreviousYearMinutes) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(summary!.carryFromPreviousYearMinutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryFromPreviousYearMinutes) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(summary!.carryFromPreviousYearMinutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(summary!.carryFromPreviousYearMinutes) }}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -86,6 +89,7 @@
|
|||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(monthReport.base50) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.base50) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(monthReport.base50) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.base50) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(monthReport.bonus50) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.bonus50) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(monthReport.bonus50) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.bonus50) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(monthReport.total50) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.total50) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(monthReport.total50) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.total50) }}</span></td>
|
||||||
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(monthReport.total) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.total) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(monthReport.total) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.total) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(monthReport.total) }} <span class="text-neutral-400">/ {{ formatCentiemes(monthReport.total) }}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -126,10 +130,14 @@
|
|||||||
<span v-if="week">{{ formatMinutes(week.base50Minutes + week.bonus50Minutes) }}</span>
|
<span v-if="week">{{ formatMinutes(week.base50Minutes + week.bonus50Minutes) }}</span>
|
||||||
<span v-else>0 h</span>
|
<span v-else>0 h</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">
|
||||||
<span v-if="week">{{ formatMinutes(week.totalMinutes) }}</span>
|
<span v-if="week">{{ formatMinutes(week.totalMinutes) }}</span>
|
||||||
<span v-else>0 h</span>
|
<span v-else>0 h</span>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">
|
||||||
|
<span v-if="week">{{ formatMinutes(week.cumulativeBalanceMinutes) }} <span class="text-neutral-400">/ {{ formatCentiemes(week.cumulativeBalanceMinutes) }}</span></span>
|
||||||
|
<span v-else> </span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<!-- Total row -->
|
<!-- Total row -->
|
||||||
@@ -142,7 +150,8 @@
|
|||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-t-2">{{ formatMinutes(totals.base50) }}</td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-t-2">{{ formatMinutes(totals.base50) }}</td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-t-2">{{ formatMinutes(totals.bonus50) }}</td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-t-2">{{ formatMinutes(totals.bonus50) }}</td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2 border-t-2">{{ formatMinutes(totals.total50) }}</td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2 border-t-2">{{ formatMinutes(totals.total50) }}</td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-t-2">{{ formatMinutes(totals.total) }}</td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2 border-t-2">{{ formatMinutes(totals.total) }}</td>
|
||||||
|
<td class="px-4 py-[10px] text-center text-neutral-500 border border-primary-500 border-t-2">-</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<!-- Payé row -->
|
<!-- Payé row -->
|
||||||
@@ -155,7 +164,8 @@
|
|||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ currentPayment ? formatMinutes(-currentPayment.paidBase50Minutes) : '0 h' }} <span class="text-neutral-400">/ {{ formatCentiemes(currentPayment ? -currentPayment.paidBase50Minutes : 0) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ currentPayment ? formatMinutes(-currentPayment.paidBase50Minutes) : '0 h' }} <span class="text-neutral-400">/ {{ formatCentiemes(currentPayment ? -currentPayment.paidBase50Minutes : 0) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ currentPayment ? formatMinutes(-currentPayment.paidBonus50Minutes) : '0 h' }} <span class="text-neutral-400">/ {{ formatCentiemes(currentPayment ? -currentPayment.paidBonus50Minutes : 0) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ currentPayment ? formatMinutes(-currentPayment.paidBonus50Minutes) : '0 h' }} <span class="text-neutral-400">/ {{ formatCentiemes(currentPayment ? -currentPayment.paidBonus50Minutes : 0) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ currentPayment ? formatMinutes(-(currentPayment.paidBase50Minutes + currentPayment.paidBonus50Minutes)) : '0 h' }} <span class="text-neutral-400">/ {{ formatCentiemes(currentPayment ? -(currentPayment.paidBase50Minutes + currentPayment.paidBonus50Minutes) : 0) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ currentPayment ? formatMinutes(-(currentPayment.paidBase50Minutes + currentPayment.paidBonus50Minutes)) : '0 h' }} <span class="text-neutral-400">/ {{ formatCentiemes(currentPayment ? -(currentPayment.paidBase50Minutes + currentPayment.paidBonus50Minutes) : 0) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(paidTotal) }} <span class="text-neutral-400">/ {{ formatCentiemes(paidTotal) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(paidTotal) }} <span class="text-neutral-400">/ {{ formatCentiemes(paidTotal) }}</span></td>
|
||||||
|
<td class="px-4 py-[10px] text-center text-neutral-500 border border-primary-500">-</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<!-- Reste row -->
|
<!-- Reste row -->
|
||||||
@@ -168,7 +178,8 @@
|
|||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(reste.base50) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.base50) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(reste.base50) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.base50) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(reste.bonus50) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.bonus50) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(reste.bonus50) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.bonus50) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(reste.total50) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.total50) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(reste.total50) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.total50) }}</span></td>
|
||||||
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500">{{ formatMinutes(reste.total) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.total) }}</span></td>
|
<td class="px-4 py-[10px] text-center font-bold text-primary-500 border border-primary-500 border-r-2">{{ formatMinutes(reste.total) }} <span class="text-neutral-400">/ {{ formatCentiemes(reste.total) }}</span></td>
|
||||||
|
<td class="px-4 py-[10px] text-center text-neutral-500 border border-primary-500">-</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -482,6 +482,7 @@ export const documentationSections: DocSection[] = [
|
|||||||
blocks: [
|
blocks: [
|
||||||
{ type: 'list', content: 'Report N-1 : solde de l\'exercice précédent\nAcquis : cumul des heures supplémentaires de l\'exercice en cours\nDisponible : report + acquis − payé\nPayé : RTT convertis en salaire (soustraits du disponible)' },
|
{ type: 'list', content: 'Report N-1 : solde de l\'exercice précédent\nAcquis : cumul des heures supplémentaires de l\'exercice en cours\nDisponible : report + acquis − payé\nPayé : RTT convertis en salaire (soustraits du disponible)' },
|
||||||
{ type: 'note', content: 'Les contrats INTERIM et le mode PRESENCE n\'accumulent pas de RTT (affiché à 0).' },
|
{ type: 'note', content: 'Les contrats INTERIM et le mode PRESENCE n\'accumulent pas de RTT (affiché à 0).' },
|
||||||
|
{ type: 'paragraph', content: 'La colonne "Cumul" affiche le solde RTT à la fin de chaque semaine : Report N-1 + somme des heures hebdomadaires jusqu\'à la semaine concernée − paiements RTT des mois précédents. Un paiement enregistré sur le mois M n\'est déduit qu\'à partir des semaines du mois M+1. Permet la comparaison ligne à ligne avec un suivi RH externe (Excel).' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export type EmployeeRttWeekSummary = {
|
|||||||
base50Minutes: number
|
base50Minutes: number
|
||||||
bonus50Minutes: number
|
bonus50Minutes: number
|
||||||
totalMinutes: number
|
totalMinutes: number
|
||||||
|
cumulativeBalanceMinutes: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RttMonthPayment = {
|
export type RttMonthPayment = {
|
||||||
|
|||||||
@@ -17,5 +17,6 @@ final class EmployeeRttWeekSummary
|
|||||||
public int $base50Minutes = 0,
|
public int $base50Minutes = 0,
|
||||||
public int $bonus50Minutes = 0,
|
public int $bonus50Minutes = 0,
|
||||||
public int $totalMinutes = 0,
|
public int $totalMinutes = 0,
|
||||||
|
public int $cumulativeBalanceMinutes = 0,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,6 +164,18 @@ final readonly class EmployeeRttSummaryProvider implements ProviderInterface
|
|||||||
$monthBuckets[$m]['bonus50'] += $payment->getBonus50Minutes();
|
$monthBuckets[$m]['bonus50'] += $payment->getBonus50Minutes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$runningCumul = $summary->carryFromPreviousYearMinutes;
|
||||||
|
$prevMonth = null;
|
||||||
|
foreach ($summary->weeks as $week) {
|
||||||
|
if (null !== $prevMonth && $week->month !== $prevMonth && isset($monthBuckets[$prevMonth])) {
|
||||||
|
$b = $monthBuckets[$prevMonth];
|
||||||
|
$runningCumul -= $b['base25'] + $b['bonus25'] + $b['base50'] + $b['bonus50'];
|
||||||
|
}
|
||||||
|
$runningCumul += $week->totalMinutes;
|
||||||
|
$week->cumulativeBalanceMinutes = $runningCumul;
|
||||||
|
$prevMonth = $week->month;
|
||||||
|
}
|
||||||
|
|
||||||
$monthPayments = [];
|
$monthPayments = [];
|
||||||
$totalPaidMinutes = 0;
|
$totalPaidMinutes = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user