@open-tender/store
Version:
A library of hooks, reducers, utility functions, and types for use with Open Tender applications that utilize our in-store POS API
529 lines (528 loc) • 22 kB
JavaScript
import { __assign, __spreadArray } from "tslib";
import { isoToDate, isoToDateStr } from '@open-tender/utils';
import { currentLocalDate, currentLocalDateStr, DATE, formatDate, makeIntervals, minutesLeft, timezoneMap } from '@open-tender/utils';
export var prepStatus = {
TODO: 'TODO',
IN_PROGRESS: 'IN_PROGRESS',
DONE: 'DONE',
COMPLETED: 'COMPLETED',
FULFILLED: 'FULFILLED'
};
export var makeOrdersParams = function (_a) {
var businessDate = _a.businessDate, receiptType = _a.receiptType, channelType = _a.channelType, prepStatus = _a.prepStatus, search = _a.search, sortBy = _a.sortBy, sortDirection = _a.sortDirection, parentOrderId = _a.parentOrderId;
var args = {};
if (businessDate) {
args = __assign(__assign({}, args), { business_date: businessDate });
}
if (receiptType) {
args = __assign(__assign({}, args), { receipt_type: receiptType });
}
if (channelType) {
args = __assign(__assign({}, args), { channel_type: channelType.join(',') });
}
if (prepStatus) {
args = __assign(__assign({}, args), { prep_status: prepStatus.join(',') });
}
if (search) {
args = __assign(__assign({}, args), { search: search });
}
if (sortBy) {
args = __assign(__assign({}, args), { sort_by: sortBy });
}
if (sortDirection) {
args = __assign(__assign({}, args), { sort_direction: sortDirection });
}
if (parentOrderId) {
args = __assign(__assign({}, args), { parent_receipt_uuid: parentOrderId });
}
return args;
};
export var notDone = function (prep_status) {
var notDoneStates = [prepStatus.TODO, prepStatus.IN_PROGRESS];
return notDoneStates.includes(prep_status);
};
export var isDone = function (prep_status) {
var doneStates = [
prepStatus.DONE,
prepStatus.COMPLETED,
prepStatus.FULFILLED
];
return doneStates.includes(prep_status);
};
export var notCompleted = function (prep_status) {
var notCompletedStates = [
prepStatus.TODO,
prepStatus.IN_PROGRESS,
prepStatus.DONE
];
return notCompletedStates.includes(prep_status);
};
export var isCompleted = function (prep_status) {
var completeStates = [prepStatus.COMPLETED, prepStatus.FULFILLED];
return completeStates.includes(prep_status);
};
export var isFutureOrder = function (order) {
var timezone = order.timezone, order_prep = order.order_prep;
if (!order_prep)
return false;
var fire_at = order_prep.fire_at, prep_status = order_prep.prep_status;
var tz = timezoneMap[timezone];
var fireDate = fire_at ? isoToDate(fire_at, tz) : null;
var currentDate = currentLocalDate(tz);
return notDone(prep_status) && fireDate && fireDate > currentDate;
};
export var makeKdsOrder = function (order) {
return order;
};
export var makeKdsOrders = function (orders) {
return orders.filter(function (i) { var _a; return ((_a = i.order_prep) === null || _a === void 0 ? void 0 : _a.expected_at) && i.order_prep.fire_at && i.tickets; });
};
export var makeCurrentOrders = function (orders) {
return orders.filter(function (i) {
var tz = timezoneMap[i.timezone];
if (!i.order_prep)
return false;
var _a = i.order_prep, fire_at = _a.fire_at, prep_status = _a.prep_status;
if (!fire_at)
return false;
var fireDate = isoToDate(fire_at, tz);
var currentDate = currentLocalDate(tz);
return notCompleted(prep_status) && fireDate < currentDate;
});
};
export var makeFutureOrders = function (orders) {
return orders.filter(function (i) {
var tz = timezoneMap[i.timezone];
if (!i.order_prep)
return false;
var _a = i.order_prep, fire_at = _a.fire_at, prep_status = _a.prep_status;
if (!fire_at)
return false;
var fireDate = isoToDate(fire_at, tz);
var currentDate = currentLocalDate(tz);
return notDone(prep_status) && fireDate > currentDate;
});
};
export var makeIncompleteOrders = function (orders) {
return orders.filter(function (i) {
var tz = timezoneMap[i.timezone];
if (!i.order_prep)
return false;
var _a = i.order_prep, fire_at = _a.fire_at, prep_status = _a.prep_status;
if (!fire_at)
return false;
var fireDate = isoToDate(fire_at, tz);
return notCompleted(prep_status) && fireDate;
});
};
export var makeCompletedOrders = function (orders) {
return orders.filter(function (i) {
var tz = timezoneMap[i.timezone];
if (!i.order_prep)
return false;
var _a = i.order_prep, fire_at = _a.fire_at, prep_status = _a.prep_status;
if (!fire_at)
return false;
var fireDate = isoToDate(fire_at, tz);
var fireDateStr = formatDate(fireDate, 'yyyy-MM-dd');
var currentDate = currentLocalDate(tz);
var currentDateStr = formatDate(currentDate, 'yyyy-MM-dd');
return isCompleted(prep_status) && fireDateStr === currentDateStr;
});
};
export var makeOrdersOfType = function (orders, orderType) {
switch (orderType) {
case 'FUTURE':
return makeFutureOrders(orders);
case 'INCOMPLETE':
return makeIncompleteOrders(orders);
case 'COMPLETED':
return makeCompletedOrders(orders);
default:
return makeCurrentOrders(orders);
}
};
export var filterOrdersByItemType = function (orders, itemTypeIds) {
if (!itemTypeIds)
return orders;
return orders
.reduce(function (arr, i) {
var _a;
var tickets = (_a = i.tickets) === null || _a === void 0 ? void 0 : _a.filter(function (t) {
return itemTypeIds.includes(t.item_type_id);
});
return __spreadArray(__spreadArray([], arr, true), [__assign(__assign({}, i), { tickets: tickets })], false);
}, [])
.filter(function (i) { var _a; return (_a = i.tickets) === null || _a === void 0 ? void 0 : _a.length; });
};
export var filterOrdersByPrepType = function (orders, prepType) {
var statusFunc = prepType === 'ASSEMBLY' ? notDone : notCompleted;
return orders
.reduce(function (arr, i) {
var _a;
var tickets = (_a = i.tickets) === null || _a === void 0 ? void 0 : _a.filter(function (t) { return statusFunc(t.ticket_status); });
return __spreadArray(__spreadArray([], arr, true), [__assign(__assign({}, i), { tickets: tickets })], false);
}, [])
.filter(function (i) { var _a; return (_a = i.tickets) === null || _a === void 0 ? void 0 : _a.length; });
};
export var filterOrdersToday = function (orders) {
if (!orders.length)
return [];
var tz = timezoneMap[orders[0].timezone];
var today = currentLocalDateStr(tz);
return orders.filter(function (i) {
if (i.requested_at === 'asap')
return true;
var requesteDateStr = isoToDateStr(i.requested_at, tz, DATE);
return today === requesteDateStr;
});
};
export var makeOrdersForPrepStation = function (orders, prepStation, orderType) {
var item_type_ids = prepStation.item_type_ids, prep_type = prepStation.prep_type, expo_done_only = prepStation.expo_done_only;
var ordersOfType = makeOrdersOfType(orders, orderType);
if (orderType === 'COMPLETED') {
return filterOrdersByItemType(ordersOfType, item_type_ids);
}
var filteredOrders = prep_type === 'ASSEMBLY'
? ordersOfType.filter(function (i) {
return i.order_prep ? notDone(i.order_prep.prep_status) : false;
})
: ordersOfType.filter(function (i) {
return !i.order_prep
? false
: expo_done_only
? i.order_prep.prep_status === 'DONE'
: notCompleted(i.order_prep.prep_status);
});
var filtered = filterOrdersByItemType(filteredOrders, item_type_ids);
return prep_type === 'EXPO'
? filtered
: filtered.filter(function (i) { var _a; return (_a = i.tickets) === null || _a === void 0 ? void 0 : _a.filter(function (t) { return notDone(t.ticket_status); }).length; });
};
export var makeOrderItemSignature = function (item, withNotes) {
if (withNotes === void 0) { withNotes = false; }
var groups = item.groups || [];
var optionIds = groups
.reduce(function (arr, group) {
var ids = group.options
.filter(function (o) { return o.quantity > 0; })
.reduce(function (optionsArr, o) {
var optionArr = new Array(o.quantity);
optionArr.fill(o.id);
return __spreadArray(__spreadArray([], optionsArr, true), optionArr, true);
}, []);
return __spreadArray(__spreadArray([], arr, true), ids, true);
}, [])
.sort(function (a, b) { return a - b; });
var itemIds = __spreadArray([item.id], optionIds, true).join('.');
return withNotes ? "".concat(itemIds, ".").concat(item.made_for, ".").concat(item.notes) : itemIds;
};
export var makeItemCounts = function (orders, withMods) {
if (withMods === void 0) { withMods = true; }
return orders.reduce(function (obj, order) {
order.cart.forEach(function (item) {
var itemId = withMods ? makeOrderItemSignature(item) : "".concat(item.id);
var existing = obj[itemId];
obj[itemId] = existing
? { item: item, count: (existing.count += item.quantity) }
: { item: item, count: item.quantity };
});
return obj;
}, {});
};
var updateCounts = function (counts, ticketCounts) {
// console.log('BEFORE', counts, ticketCounts)
var updated = Object.entries(counts).reduce(function (obj, _a) {
var _b;
var key = _a[0], count = _a[1];
return __assign(__assign({}, obj), (_b = {}, _b[key] = count + (ticketCounts[key] || 0), _b));
}, {});
updated.Orders = counts.Orders + 1;
// console.log('AFTER', updated)
return updated;
};
export var makeKdsCounts = function (itemTypes, orders) {
if (!itemTypes || !orders) {
return { current: null, future: null, qa: null };
}
console.time('makeKdsCounts');
var itemTypeCounts = itemTypes
.filter(function (i) { return i.is_default; })
.reduce(function (obj, i) {
var _a;
return (__assign(__assign({}, obj), (_a = {}, _a[i.name] = 0, _a)));
}, {});
var current = __assign({ Orders: 0 }, itemTypeCounts);
var qa = __assign({ Orders: 0 }, itemTypeCounts);
var future = __assign({ Orders: 0 }, itemTypeCounts);
var openOrders = orders.filter(function (i) { return i.order_prep && notCompleted(i.order_prep.prep_status); });
openOrders.forEach(function (order) {
if (!order.order_prep || !order.tickets)
return;
var _a = order.order_prep, fire_at = _a.fire_at, prep_status = _a.prep_status;
var tz = timezoneMap[order.timezone];
var fireDate = fire_at ? isoToDate(fire_at, tz) : null;
var currentDate = currentLocalDate(tz);
var isDone = prep_status === prepStatus.DONE;
var isCurrent = fireDate ? fireDate < currentDate : false;
var ticketCounts = order.tickets.reduce(function (obj, ticket) {
var _a;
var count = obj[ticket.item_type_name] || 0;
return __assign(__assign({}, obj), (_a = {}, _a[ticket.item_type_name] = count + ticket.item_nos.length, _a));
}, {});
if (isDone) {
qa = updateCounts(qa, ticketCounts);
}
else if (isCurrent) {
current = updateCounts(current, ticketCounts);
}
else {
future = updateCounts(future, ticketCounts);
}
});
console.timeEnd('makeKdsCounts');
return { current: current, future: future, qa: qa };
};
export var makeCurrentAndFutureOrders = function (orders) {
var current = [];
var future = [];
orders.forEach(function (i) {
var tz = timezoneMap[i.timezone];
if (!i.order_prep)
return;
var _a = i.order_prep, fire_at = _a.fire_at, prep_status = _a.prep_status;
var fireDate = fire_at ? isoToDate(fire_at, tz) : null;
if (isCompleted(prep_status) || !fireDate)
return;
var currentDate = currentLocalDate(tz);
if (fireDate < currentDate) {
current.push(i);
}
else if (fireDate > currentDate) {
future.push(i);
}
});
return { current: current, future: future };
};
export var makeKdsStationCount = function (orders, itemTypeIds, prepType) {
var byItemType = filterOrdersByItemType(orders, itemTypeIds);
var filtered = filterOrdersByPrepType(byItemType, prepType);
var tickets = filtered.reduce(function (arr, i) { return __spreadArray(__spreadArray([], arr, true), (i.tickets || []), true); }, []);
return { orders: filtered.length, tickets: tickets.length };
};
export var makeKdsStationCounts = function (orders, prepStations) {
var _a = makeCurrentAndFutureOrders(orders), currentOrders = _a.current, futureOrders = _a.future;
var currentAssembly = currentOrders.filter(function (i) {
return i.order_prep ? notDone(i.order_prep.prep_status) : false;
});
var futureAssembly = futureOrders.filter(function (i) {
return i.order_prep ? notDone(i.order_prep.prep_status) : false;
});
var currentExpoDone = currentOrders.filter(function (i) {
return i.order_prep ? i.order_prep.prep_status === 'DONE' : false;
});
var currentExpo = currentOrders.filter(function (i) {
return i.order_prep ? notCompleted(i.order_prep.prep_status) : false;
});
var futureExpoDone = futureOrders.filter(function (i) {
return i.order_prep ? i.order_prep.prep_status === 'DONE' : false;
});
var futureExpo = futureOrders.filter(function (i) {
return i.order_prep ? notCompleted(i.order_prep.prep_status) : false;
});
return prepStations.reduce(function (obj, i) {
var _a;
var currentFiltered = i.prep_type === 'ASSEMBLY'
? currentAssembly
: i.expo_done_only
? currentExpoDone
: currentExpo;
var current = makeKdsStationCount(currentFiltered, i.item_type_ids, i.prep_type);
var futureFiltered = i.prep_type === 'ASSEMBLY'
? futureAssembly
: i.expo_done_only
? futureExpoDone
: futureExpo;
var future = makeKdsStationCount(futureFiltered, i.item_type_ids, i.prep_type);
return __assign(__assign({}, obj), (_a = {}, _a[i.prep_station_id] = { CURRENT: current, FUTURE: future }, _a));
}, {});
};
export var makeOrderBuckets = function (orders, tz) {
var intervals = makeIntervals(tz);
var withOrders = intervals.map(function (interval) {
var inBucket = orders.filter(function (order) {
if (!order.order_prep)
return false;
var ready_at = order.order_prep.ready_at;
if (!ready_at)
return false;
var readyAt = isoToDate(ready_at, tz);
return readyAt > interval.start && readyAt <= interval.end;
});
return __assign(__assign({}, interval), { orders: inBucket });
});
return withOrders;
};
export var makeOrderBucketsCounts = function (itemTypes, orders) {
if (itemTypes === void 0) { itemTypes = []; }
if (orders === void 0) { orders = []; }
var itemTypeCounts = itemTypes
.filter(function (i) { return i.is_default; })
.reduce(function (obj, i) {
var _a;
return (__assign(__assign({}, obj), (_a = {}, _a[i.name] = 0, _a)));
}, {});
var counts = __assign({ Orders: 0 }, itemTypeCounts);
orders.forEach(function (order) {
var _a;
var ticketCounts = (_a = order.tickets) === null || _a === void 0 ? void 0 : _a.reduce(function (obj, ticket) {
var _a;
var count = obj[ticket.item_type_name] || 0;
return __assign(__assign({}, obj), (_a = {}, _a[ticket.item_type_name] = count + ticket.item_nos.length, _a));
}, {});
if (ticketCounts)
counts = updateCounts(counts, ticketCounts);
});
return counts;
};
export var makeTicketCounts = function (tickets) {
return tickets.reduce(function (obj, i) {
var _a;
var count = obj[i.item_type_id.toString()] || 0;
return __assign(__assign({}, obj), (_a = {}, _a[i.item_type_id] = count + i.item_nos.length, _a));
}, {});
};
export var makeItemTypeSettings = function (itemType) {
var _a = itemType || {}, is_default = _a.is_default, is_grouped = _a.is_grouped, is_hidden_assembly = _a.is_hidden_assembly, is_hidden_qa = _a.is_hidden_qa, print_on_completed = _a.print_on_completed;
return {
is_default: is_default,
is_grouped: is_grouped,
is_hidden_assembly: is_hidden_assembly,
is_hidden_qa: is_hidden_qa,
print_on_completed: print_on_completed
};
};
export var makeItemTypesMap = function (itemTypes) {
return itemTypes.reduce(function (obj, i) {
var _a;
return (__assign(__assign({}, obj), (_a = {}, _a[i.item_type_id] = i, _a)));
}, {});
};
export var makeCartLookup = function (cart) {
return cart.reduce(function (obj, i) {
var _a;
if (!i.item_no)
return obj;
return __assign(__assign({}, obj), (_a = {}, _a[i.item_no.toString()] = i, _a));
}, {});
};
export var makeModifiersMetadataLookup = function (cart) {
return cart.reduce(function (obj, i) {
var _a;
return (__assign(__assign({}, obj), (_a = {}, _a[i.item_no.toString()] = i, _a)));
}, {});
};
export var makeTicketGroups = function (tickets, itemTypes, isAssembly, cart, modifiersMetadata) {
var lookup = cart
? makeCartLookup(cart)
: modifiersMetadata
? makeModifiersMetadataLookup(modifiersMetadata)
: {};
var itemTypesMap = makeItemTypesMap(itemTypes);
var grouped = tickets.reduce(function (obj, i) {
var _a;
var items = i.item_nos.map(function (n) { return lookup[n.toString()]; });
var settings = makeItemTypeSettings(itemTypesMap[i.item_type_id]);
var hideTicket = isAssembly && settings.is_hidden_assembly;
var ticket = __assign(__assign(__assign({}, i), { items: items }), settings);
var group = obj[i.item_type_id.toString()] || [];
var newGroup = hideTicket ? group : __spreadArray(__spreadArray([], group, true), [ticket], false);
return __assign(__assign({}, obj), (_a = {}, _a[i.item_type_id] = newGroup, _a));
}, {});
var groups = Object.values(grouped);
return groups.filter(function (group) { return group.length; });
};
export var makeDisplayCounts = function (counts) {
if (!counts)
return '';
return Object.entries(counts).map(function (_a) {
var value = _a[1];
return value;
});
};
export var displayCounts = function (counts) {
if (!counts)
return '';
var countStr = Object.entries(counts)
// .map(([key, value]) => `${value}-${key.charAt(0)}`)
.map(function (_a) {
var value = _a[1];
return "".concat(value);
})
.join('/');
return " (".concat(countStr, ")");
};
export var makeBucketColor = function (settings, minutes) {
var _a = settings || {}, warning_minutes = _a.warning_minutes, alert_minutes = _a.alert_minutes;
if (!warning_minutes && !alert_minutes)
return '';
return minutes < warning_minutes
? 'error'
: minutes < alert_minutes
? 'alert'
: 'text';
};
export var makeOrderPrepTimes = function (order, amPm, warningMinutes, alertMinutes) {
if (amPm === void 0) { amPm = false; }
if (warningMinutes === void 0) { warningMinutes = 5; }
if (alertMinutes === void 0) { alertMinutes = 10; }
var order_prep = order.order_prep, timezone = order.timezone, requested_at = order.requested_at;
if (!order_prep)
return null;
var ready_at = order_prep.ready_at, expected_at = order_prep.expected_at, prep_status = order_prep.prep_status;
if (!ready_at || !expected_at || requested_at === 'asap')
return null;
var tz = timezoneMap[timezone];
var current = currentLocalDate(tz);
var readyBy = isoToDate(ready_at || expected_at, tz);
var requested = isoToDate(requested_at, tz);
var expected = isoToDate(expected_at, tz);
var delayed = minutesLeft(expected, requested);
var minutes = minutesLeft(readyBy, current);
var readyTime = formatDate(readyBy, amPm ? 'h:mm a' : 'h:mm');
var requestedTime = formatDate(requested, amPm ? 'h:mm a' : 'h:mm');
var expectedTime = formatDate(expected, amPm ? 'h:mm a' : 'h:mm');
var expectedDate = formatDate(expected, 'EEE, MMM d');
var todayDate = formatDate(current, 'yyyy-MM-dd');
var dateStr = formatDate(expected, 'yyyy-MM-dd');
dateStr = dateStr === todayDate ? '' : formatDate(expected, 'EEE, MMM d');
var status = isCompleted(prep_status)
? 'COMPLETE'
: minutes < warningMinutes
? 'WARNING'
: minutes < alertMinutes
? 'ALERT'
: 'PREP';
return {
delayed: delayed,
requested: requested,
requestedTime: requestedTime,
expected: expected,
expectedDate: expectedDate,
expectedTime: expectedTime,
readyBy: readyBy,
readyTime: readyTime,
dateStr: dateStr,
status: status
};
};
export var makeHeaderStatusColor = function (status) {
switch (status) {
case 'WARNING':
return 'error';
case 'ALERT':
return 'alert';
default:
return 'default';
}
};