42 lines
1.6 KiB
TypeScript
42 lines
1.6 KiB
TypeScript
/** (#67) Warranty status computation for object asset tracking.
|
|
*
|
|
* Pure, side-effect-free, and `today`-injectable so it can be unit-tested
|
|
* deterministically without faking the system clock.
|
|
*/
|
|
|
|
import { daysBetweenIso, haToday } from "./ha-time";
|
|
|
|
export type WarrantyStatusKind = "valid" | "expiring" | "expired" | "none";
|
|
|
|
export interface WarrantyStatus {
|
|
kind: WarrantyStatusKind;
|
|
/** Whole days until expiry (negative once expired); null when no date. */
|
|
days: number | null;
|
|
/** The ISO date string echoed back, or null when absent/invalid. */
|
|
date: string | null;
|
|
}
|
|
|
|
/** Days before expiry at which the warranty is flagged as "expiring" (amber). */
|
|
export const WARRANTY_WARN_DAYS = 60;
|
|
|
|
/**
|
|
* Classify an object's warranty expiry date relative to `today`.
|
|
*
|
|
* @param iso ISO `YYYY-MM-DD` warranty expiry date (null/undefined/""/invalid → "none").
|
|
* @param today Reference day "YYYY-MM-DD"; defaults to HA's today (the
|
|
* browser's date was a day off around midnight on a device in
|
|
* another zone). Injectable for deterministic tests.
|
|
*/
|
|
export function warrantyStatus(
|
|
iso: string | null | undefined,
|
|
today: string = haToday(),
|
|
): WarrantyStatus {
|
|
if (!iso) return { kind: "none", days: null, date: null };
|
|
// Whole calendar days between two date-only strings — no time of day, no zone.
|
|
const days = daysBetweenIso(today, iso);
|
|
if (!Number.isFinite(days)) return { kind: "none", days: null, date: null };
|
|
if (days < 0) return { kind: "expired", days, date: iso };
|
|
if (days <= WARRANTY_WARN_DAYS) return { kind: "expiring", days, date: iso };
|
|
return { kind: "valid", days, date: iso };
|
|
}
|