Functional Weave
Code in TypeScript

fleet.service-due@1.0.0

README.md

1,590 bytes · view raw

# fleet.service-due

When a vehicle's next service is due under a "every N months or N miles,
whichever comes first" schedule, how far away each limit is, and whether the
service is overdue.

## Whichever comes first

The time limit is a date: the last service plus `intervalMonths`, clamped to
the month end by `dates.add-months` (a service on 29 February 2024 with a
12-month interval is due on 28 February 2025). The mileage limit is a mileage,
so to compare the two it is turned into a date: the average miles a day since
the last service, projected forward from `onDate`, rounded **up** to a whole
day. `nextDueDate` is the earlier of the two and `dueBy` says which; a tie
counts as `date`.

There is no projection (and `projectedMileageDate` is null) when the service
was today or the vehicle has not moved, since there is no average to project;
`nextDueDate` then falls back to the date limit alone, or is null for a
mileage-only schedule. Once the due mileage is reached the service is due
from `onDate`.

## Overdue

`overdue` is true once `onDate` is after `dueDate` or `currentMileage` is above
`dueMileage`. On the due date, or at exactly the due mileage, the service is
due but not yet overdue; `daysRemaining` or `milesRemaining` is then 0, and
both go negative once past.

## Inputs

`intervalMonths` or `intervalMiles` may be 0 to schedule by the other alone,
but not both. `onDate` is passed in, never read from a clock. An `onDate`
before the last service, or a mileage below the last service's (a clocked
odometer, or the wrong vehicle), is an error rather than a guess.