fix(planning): prioritize complete holiday weeks

This commit is contained in:
nessar committed 2026-08-30 17:16:30 +02:00
1 parent 5a81e38b95
commit 31314f3969
7 files changed
+355 -25

No files matched your search

+133 -1
View File
@@ -547,7 +547,7 @@ describe('planLeave', () => {
expect(result.metrics.supportingPlacements).toBe(
result.placements.filter((placement) => placement.supporting).length,
);
expect(result.placements).toHaveLength(3);
expect(result.placements.length).toBeGreaterThan(0);
expect(result.placements.every((placement) => placement.supporting)).toBe(true);
});
@@ -578,6 +578,138 @@ describe('planLeave', () => {
]);
});
it.each([
[
'11 November',
{ start: '2026-11-01', end: '2026-12-01' },
'2026-11-30',
['2026-11-09', '2026-11-10', '2026-11-12', '2026-11-13'],
],
[
'14 July',
{ start: '2027-07-01', end: '2027-08-01' },
'2027-07-31',
['2027-07-12', '2027-07-13', '2027-07-15', '2027-07-16'],
],
] as const)('takes the full week around %s', async (_, holidayHorizon, expiryDate, dates) => {
const result = isPlan(
await runInNonBrowser({
horizon: holidayHorizon,
balances: [balance('cp', 'cp', 4, expiryDate)],
rules: [],
}),
);
expect(result.placements.map((placement) => placement.date)).toEqual(dates);
expect(result.timeOffPeriods).toHaveLength(1);
expect(result.timeOffPeriods[0].duration).toBe(9);
});
it('uses the 11 November and 14 July weeks in the representative default plan', async () => {
const result = isPlan(
await runInNonBrowser({
horizon: { start: '2026-08-29', end: '2027-08-29' },
balances: [
{
...balance('cp', 'cp', 10, '2027-08-29'),
availableFrom: '2026-08-29',
},
{
...balance('rtt', 'rtt', 10, '2027-08-29'),
availableFrom: '2026-08-29',
},
{
...balance('other', 'other', 4, '2027-08-29'),
availableFrom: '2026-08-29',
},
],
rules: [
{
id: 'default-samedi-malin',
name: 'Samedi Malin',
type: 'if_then',
force: 'preference',
dayOfWeek: 6,
placeDays: 2,
placeType: 'cp',
placement: 'auto',
rewardDays: 1,
rewardType: 'other',
},
{
id: 'default-christmas',
name: 'Christmas holidays',
type: 'time_window',
force: 'preference',
startDate: '2026-12-20',
endDate: '2027-01-03',
placeDays: 5,
placeType: 'any',
},
],
}),
);
expect(result.placements.map((placement) => placement.date)).toEqual(
expect.arrayContaining([
'2026-11-09',
'2026-11-10',
'2026-11-12',
'2026-11-13',
'2027-07-12',
'2027-07-13',
'2027-07-15',
'2027-07-16',
]),
);
});
it('moves a satisfied time-window preference to complete a holiday week', async () => {
const result = isPlan(
await runInNonBrowser({
horizon: { start: '2027-07-01', end: '2027-08-01' },
balances: [balance('cp', 'cp', 4, '2027-07-31')],
rules: [
{
id: 'july',
type: 'time_window',
force: 'preference',
startDate: '2027-07-01',
endDate: '2027-07-31',
placeDays: 4,
placeType: 'any',
},
],
}),
);
expect(result.preferences[0].satisfied).toBe(4);
expect(result.placements.map((placement) => placement.date)).toEqual([
'2027-07-12',
'2027-07-13',
'2027-07-15',
'2027-07-16',
]);
});
it('uses deferred leave as supporting placements to complete a holiday week', async () => {
const result = isPlan(
await runInNonBrowser({
horizon: { start: '2027-07-01', end: '2027-08-01' },
balances: [balance('cp', 'cp', 4, '2028-07-31')],
rules: [],
}),
);
expect(result.placements.map((placement) => placement.date)).toEqual([
'2027-07-12',
'2027-07-13',
'2027-07-15',
'2027-07-16',
]);
expect(result.placements.every((placement) => placement.supporting)).toBe(true);
});
it('moves a time-window obligation to improve a later quality stage', async () => {
const result = isPlan(
await runInNonBrowser({