diff --git a/shared/src/roadtrip/roadtripModel.spec.ts b/shared/src/roadtrip/roadtripModel.spec.ts index f6bbd03b1..c7efffe43 100644 --- a/shared/src/roadtrip/roadtripModel.spec.ts +++ b/shared/src/roadtrip/roadtripModel.spec.ts @@ -865,6 +865,20 @@ describe('a check-in is a door opening, not an appointment', () => { expect(schedule.warnings).toEqual([]); }); + it('sets the hour when nothing before it does, instead of being worked backwards', () => { + // Booked to check in at ten, with a stop pinned to three in the afternoon behind it. + // Read only as a floor, the chain worked the hotel backwards out of the afternoon + // and put it at 13:46: true enough as arithmetic, and nothing anybody asked for. + const schedule = computeSchedule( + [{ anchor: null, earliest: '10:00', dwellMinutes: 60 }, { anchor: '15:00', dwellMinutes: 60 }], + [14 * 60], + ); + expect(schedule.entries[0]!.arrival).toBe('10:00'); + expect(schedule.entries[0]!.anchored).toBe(true); + expect(schedule.entries[1]!.arrival).toBe('15:00'); + expect(schedule.warnings).toEqual([]); + }); + it('is simply arrived at when the drive gets there later', () => { const schedule = computeSchedule( [{ anchor: '15:00', dwellMinutes: 60 }, { anchor: null, earliest: '11:00', dwellMinutes: 60 }], diff --git a/shared/src/roadtrip/roadtripModel.ts b/shared/src/roadtrip/roadtripModel.ts index 1d49e3416..e56dfc9ee 100644 --- a/shared/src/roadtrip/roadtripModel.ts +++ b/shared/src/roadtrip/roadtripModel.ts @@ -199,10 +199,16 @@ export function computeSchedule( // A door that opens at eleven is not an appointment at eleven. Reaching the stop // later than that is simply reaching it; only a time somebody pinned can be missed. const opens = parseClock(stop.earliest ?? null); - const waited = anchor === null && opens !== null && resolved.arrival !== null - ? opens + Math.round((resolved.arrival - opens) / DAY_MINUTES) * DAY_MINUTES + // With nothing before it deciding the hour, the door IS the hour: a night booked + // to check in at ten starts the day at ten rather than being worked backwards out + // of whatever comes after it. Reached later, it is only a floor, and a floor below + // the arrival changes nothing. + const waited = anchor === null && opens !== null + ? resolved.arrival === null + ? opens + dayOffset * DAY_MINUTES + : opens + Math.round((resolved.arrival - opens) / DAY_MINUTES) * DAY_MINUTES : null; - const held = waited !== null && waited > resolved.arrival!; + const held = waited !== null && (resolved.arrival === null || waited > resolved.arrival); const arrival = held ? waited : resolved.arrival; const lateBy = resolved.lateBy; if (lateBy !== null) warnings.push({ index: i, code: 'late', minutes: lateBy });