mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
Drop empty leftover dateless days when a trip gets a shorter dated range (#1083)
generateDays kept all unused dateless placeholder days after switching to an explicit (shorter) date range, so day_count (COUNT(*) FROM days) stayed inflated. Delete the empty leftovers (no assignments/notes/accommodations) like the dateless path already does, while preserving any that still hold content. Adds TRIP-SVC-017.
This commit is contained in:
@@ -122,12 +122,26 @@ export function generateDays(tripId: number | bigint | string, startDate: string
|
||||
del.run(dated[i].id);
|
||||
}
|
||||
|
||||
// Any remaining unused dateless days: keep as dateless, just renumber.
|
||||
// Any remaining unused dateless days: drop the empty placeholders so day_count
|
||||
// reflects the dated range, but keep ones that still hold content (assignments,
|
||||
// notes, accommodations) — mirrors the dateless-path trimming above (#1083).
|
||||
// Base must be max(targetDates.length, dated.length) to avoid colliding with
|
||||
// positives already assigned by the main loop or the overflow loop above.
|
||||
const isEmptyDay = db.prepare(
|
||||
`SELECT NOT EXISTS (SELECT 1 FROM day_assignments da WHERE da.day_id = @id)
|
||||
AND NOT EXISTS (SELECT 1 FROM day_notes dn WHERE dn.day_id = @id)
|
||||
AND NOT EXISTS (SELECT 1 FROM day_accommodations dac WHERE dac.start_day_id = @id OR dac.end_day_id = @id) AS empty`
|
||||
);
|
||||
const maxAssigned = Math.max(targetDates.length, dated.length);
|
||||
let keptDateless = 0;
|
||||
for (let i = datelessIdx; i < dateless.length; i++) {
|
||||
setDayNumber.run(maxAssigned + (i - datelessIdx) + 1, dateless[i].id);
|
||||
const empty = (isEmptyDay.get({ id: dateless[i].id }) as { empty: number }).empty;
|
||||
if (empty) {
|
||||
del.run(dateless[i].id);
|
||||
} else {
|
||||
setDayNumber.run(maxAssigned + keptDateless + 1, dateless[i].id);
|
||||
keptDateless++;
|
||||
}
|
||||
}
|
||||
|
||||
// Final renumber to compact and eliminate any gaps/negatives
|
||||
|
||||
@@ -242,6 +242,33 @@ describe('generateDays', () => {
|
||||
const nums = daysAfter.map(d => d.day_number).sort((a, b) => a - b);
|
||||
expect(nums).toEqual([1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('TRIP-SVC-017: switching a dateless trip to a shorter dated range drops empty leftover days but keeps ones with content (#1083)', () => {
|
||||
const { user } = createUser(testDb);
|
||||
// A 7-day trip, then cleared to dateless placeholders (day_count = 7).
|
||||
const trip = createTrip(testDb, user.id, { start_date: '2025-12-01', end_date: '2025-12-07' });
|
||||
generateDays(trip.id, null, null);
|
||||
const dateless = getDays(trip.id);
|
||||
expect(dateless).toHaveLength(7);
|
||||
expect(dateless.every(d => d.date === null)).toBe(true);
|
||||
|
||||
// Give the LAST dateless day real content so it must be preserved.
|
||||
const place = createPlace(testDb, trip.id);
|
||||
const assignment = createDayAssignment(testDb, dateless[6].id, place.id);
|
||||
|
||||
// Now set an explicit 2-day range. The first two dateless days are reused for
|
||||
// the dates; the four empty leftovers must be removed, the one with content kept.
|
||||
generateDays(trip.id, '2026-01-10', '2026-01-11');
|
||||
|
||||
const daysAfter = getDays(trip.id);
|
||||
const dated = daysAfter.filter(d => d.date !== null);
|
||||
const stillDateless = daysAfter.filter(d => d.date === null);
|
||||
expect(dated.map(d => d.date)).toEqual(['2026-01-10', '2026-01-11']);
|
||||
// day_count is COUNT(*) FROM days: 2 dated + 1 content-bearing dateless = 3 (not the stale 7)
|
||||
expect(daysAfter).toHaveLength(3);
|
||||
expect(stillDateless).toHaveLength(1);
|
||||
expect(getAssignments(stillDateless[0].id)[0].id).toBe(assignment.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exportICS', () => {
|
||||
|
||||
Reference in New Issue
Block a user