UNPKG

@tictuk/item-availability

Version:

Provides functions to check availability

76 lines (57 loc) 2.04 kB
import Availability from './availability'; import AvailabilityException from './availability-exception'; import { toDate, ExceptionDate } from './exception-date'; import Item from './item'; const MINUTES_IN_A_DAY = 1440; export function isItemAvailableNow(item: Item) { return isItemAvailable(item, new Date()); } export function isItemAvailable(item: Item, date: Date) { const availability = (item?.condition?.conditions ?? [])[3]?.availability; if (!availability) { return true; } return isAvailable(availability, date); } export function isAvailableNow(availability: Availability) { return isAvailable(availability, new Date()); } export function isAvailable(availability: Availability, date: Date) { const exceptionAvailability = _isAvailableInExceptions(availability, date); if (exceptionAvailability === 'available') { return true; } else if (exceptionAvailability === 'unavailable') { return false; } return _isRegularlyAvailable(availability, date); } function _isRegularlyAvailable(availability: Availability, date: Date) { const weekMinute = date.getDay() * MINUTES_IN_A_DAY + date.getHours() * 60 + date.getMinutes(); for (const segment of availability.weekly) { if ( weekMinute >= segment.minuteOfWeek && segment.minuteOfWeek + segment.durationMins >= weekMinute ) { return true; } } return !availability.weekly.length; } function _isAvailableInExceptions(availability: Availability, date: Date) { if (!availability.exceptions) { return 'not-mentioned'; } for (const exception of availability.exceptions) { if (_isDateInsideException(exception, date)) { return exception.available ? 'available' : 'unavailable'; } } return 'not-mentioned'; } function _isDateInsideException(exception: AvailabilityException, date: Date) { const start = toDate(exception.start); const end = toDate(exception.end); return date > start && date < end; } export { Item, Availability, AvailabilityException, ExceptionDate };