@open-tender/utils
Version:
A library of utils for use with Open Tender applications that utilize our cloud-based Order API.
146 lines (145 loc) • 6.66 kB
JavaScript
import { serviceTypeNamesMap } from './constants';
import { dateToZonedDateStr, fmtDate, formatDateStr, isoToDate, makeOrderTimes, makeReadableDateStrFromIso, makeWeekday, time24ToDate, timezoneMap } from './datetimes';
import { capitalize } from './helpers';
import { format } from 'date-fns';
import { utcToZonedTime } from 'date-fns-tz';
export const makeOrderAddress = (address) => {
const { street, unit, city, state, postal_code } = address || {};
return street
? `${street}${unit ? `, ${unit}` : ''}`
: postal_code
? `${postal_code} ${city}, ${state}`
: 'No address provided';
};
export const makeFullAddress = (address) => {
const { street, city, state, postal_code } = address || {};
return `${street ? `${street}, ` : ''}${city}, ${state} ${postal_code}`;
};
export const makeOrderTypeFromParam = (param) => {
switch (param) {
case 'outpost':
return ['OLO', 'PICKUP', true];
case 'pickup':
return ['OLO', 'PICKUP'];
case 'delivery':
return ['OLO', 'DELIVERY'];
case 'catering':
return ['CATERING', 'DELIVERY'];
case 'merch':
return ['MERCH', 'DELIVERY'];
default:
return null;
}
};
export const makeServiceTypeName = (serviceType, isCatering, isOutpost, outpostName) => {
let serviceTypeName = serviceTypeNamesMap[serviceType];
if (isCatering) {
serviceTypeName = `Catering ${serviceTypeName}`;
}
else if (isOutpost) {
serviceTypeName = `${outpostName || 'Outpost'} ${serviceTypeName}`;
}
return serviceTypeName;
};
export const makeOrderTypeName = (orderType, serviceType) => {
return orderType === 'OLO'
? serviceTypeNamesMap[serviceType]
: capitalize(orderType);
};
const makeOrderMsg = (tz, serviceType, requestedAt, firstTime, orderTime, waitTime) => {
var _a, _b;
if (!firstTime && !orderTime)
return null;
let readableDate;
if (firstTime) {
const seconds = firstTime.utc ? isoToDate(firstTime.utc).getSeconds() : 0;
const estimate = requestedAt !== 'asap' && seconds ? 'at about' : 'at';
readableDate =
requestedAt === 'asap' && firstTime.has_asap
? `in about ${waitTime} minutes`
: makeReadableDateStrFromIso(firstTime.utc, tz, true)
.replace('Today', 'today')
.replace('Tomorrow', 'TOMORROW')
.replace('@', estimate);
}
else {
const orderTimes = makeOrderTimes([orderTime], tz);
const { start_time, end_time } = orderTimes[0];
const startTime = time24ToDate(start_time);
const startTimeStr = (_a = formatDateStr(startTime.toISOString(), 'h:mma')) === null || _a === void 0 ? void 0 : _a.toLowerCase();
const endTime = time24ToDate(end_time);
const endTimeStr = (_b = formatDateStr(endTime.toISOString(), 'h:mma')) === null || _b === void 0 ? void 0 : _b.toLowerCase();
const todayWeekday = makeWeekday();
const weekday = orderTimes[0].weekday === todayWeekday
? ''
: `${capitalize(orderTimes[0].weekday)}, ${fmtDate(orderTimes[0].date, 'MMMM d')} @ `;
readableDate =
startTimeStr === endTimeStr
? `${weekday}${startTimeStr}`
: `${weekday}${startTimeStr} to ${endTimeStr}`;
}
const serviceTypeName = serviceTypeNamesMap[serviceType];
const orderMsg = `The first available ${serviceTypeName === null || serviceTypeName === void 0 ? void 0 : serviceTypeName.toLowerCase()} time is ${readableDate}`;
return orderMsg;
};
export const makeNotAcceptingOrdersMsg = (serviceType) => {
const serviceTypeName = serviceTypeNamesMap[serviceType];
if (!serviceTypeName) {
return 'This location is not currently accepting orders.';
}
return `This location is not currently accepting ${serviceTypeName.toLowerCase()} orders.`;
};
export const makeRevenueCenterMsg = (revenueCenter, serviceType, requestedAt, statusMessages) => {
var _a;
const settings = revenueCenter;
const { first_times, order_times, wait_times } = settings;
const tz = timezoneMap[(_a = revenueCenter === null || revenueCenter === void 0 ? void 0 : revenueCenter.timezone) !== null && _a !== void 0 ? _a : 'US/Central'];
const st = serviceType === 'WALKIN' ? 'PICKUP' : serviceType;
const firstTime = first_times ? first_times[st] : null;
const orderTime = order_times ? order_times[st] : null;
const waitTime = wait_times ? wait_times[st] : null;
const tempClosed = revenueCenter.status === 'CLOSED_TEMPORARILY';
const statusMsg = !tempClosed
? statusMessages[revenueCenter.status]
: null;
const orderMsg = !statusMsg && (firstTime || (orderTime && orderTime.length))
? makeOrderMsg(tz, serviceType, requestedAt, firstTime, orderTime ? orderTime[0] : null, waitTime !== null && waitTime !== void 0 ? waitTime : 0)
: null;
let message = orderMsg ||
(statusMsg ? statusMsg.subtitle : makeNotAcceptingOrdersMsg(serviceType));
let color = orderMsg ? 'success' : 'alert';
if (tempClosed) {
color = 'alert';
message = message.charAt(0).toLowerCase() + message.substring(1);
message = `This location is temporarily closed for technical or operational reasons. Please try back later today, otherwise ${message} if you want to place an order now.`;
}
return { message, color };
};
export const getRevenueCenterStatus = (revenueCenter, serviceType) => {
const { first_times, status, timezone, revenue_center_type, is_outpost } = revenueCenter;
if (revenue_center_type !== 'OLO' || is_outpost)
return null;
if (status !== 'OPEN' && status !== 'HIDDEN')
return 'Closed';
const tz = timezoneMap[timezone];
const firstTimes = first_times ? first_times[serviceType] : null;
if (!firstTimes)
return 'Closed';
const { date, has_asap, utc } = firstTimes;
const firstDt = utcToZonedTime(utc, tz);
const now = new Date();
const today = dateToZonedDateStr(now, tz, 'yyyy-MM-dd');
const tomorrow = dateToZonedDateStr(now, tz, 'yyyy-MM-dd', 1);
const isToday = date === today;
const isTomorrow = date === tomorrow;
if (isToday) {
if (has_asap) {
return 'Open Now';
}
else {
return 'Currently closed, order for later today';
}
}
const nextDay = isTomorrow ? 'tomorrow' : format(firstDt, 'EEEE');
return `Closed for today, order for ${nextDay}`;
};