@tictuk/item-availability
Version:
Provides functions to check availability
76 lines (57 loc) • 2.04 kB
text/typescript
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 };