@open-tender/cloud
Version:
A library of hooks, reducers, utility functions, and types for use with Open Tender applications that utilize our cloud-based Order API.
267 lines (266 loc) • 12.3 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.groupOrderReducer = exports.selectGroupOrderPrepTimes = exports.selectGroupOrderTests = exports.selectGroupOrderClosed = exports.selectSpendingLimit = exports.selectGroupOrderToken = exports.selectGroupOrder = exports.adjustGroupOrder = exports.resetGroupOrder = exports.addCustomerGroupOrder = exports.reloadGuestOrder = exports.updateGroupOrder = exports.fetchGroupOrder = exports.joinGroupOrder = exports.makeCartPayload = exports.GroupOrderActionType = void 0;
const tslib_1 = require("tslib");
const toolkit_1 = require("@reduxjs/toolkit");
const types_1 = require("./types");
const types_2 = require("@open-tender/types");
const utils_1 = require("@open-tender/utils");
const order_1 = require("./order");
const customer_1 = require("./customer");
const initialState = {
cart: [],
cartGuest: null,
cartGuests: [],
cartId: null,
cartOwner: null,
closed: false,
cutoffAt: null,
guestCount: null,
guestLimit: null,
isCartOwner: false,
requestedAt: null,
revenueCenterId: null,
serviceType: null,
spendingLimit: null,
token: null,
error: null,
loading: 'idle'
};
var GroupOrderActionType;
(function (GroupOrderActionType) {
GroupOrderActionType["JoinGroupOrder"] = "groupOrder/joinGroupOrder";
GroupOrderActionType["FetchGroupOrder"] = "groupOrder/fetchGroupOrder";
GroupOrderActionType["UpdateGroupOrder"] = "groupOrder/updateGroupOrder";
GroupOrderActionType["ReloadGuestOrder"] = "groupOrder/reloadGuestOrder";
GroupOrderActionType["AddCustomerGroupOrder"] = "customer/addCustomerGroupOrder";
})(GroupOrderActionType = exports.GroupOrderActionType || (exports.GroupOrderActionType = {}));
const makeCartPayload = (response, cartGuestId) => {
const { customer = null, closed, cart_id: cartId, token, cart, revenue_center_id: revenueCenterId, service_type: serviceType, requested_at: requestedAt, cutoff_at: cutoffAt, spending_limit: spendingLimit, guest_limit: guestLimit, guest_count: guestCount, cart_guests: cartGuests } = response;
const filteredCart = cartGuestId
? cart.filter(i => i.cart_guest_id === cartGuestId)
: cart;
return {
cartId,
token,
revenueCenterId,
serviceType,
requestedAt,
cutoffAt,
guestLimit,
guestCount,
spendingLimit,
closed,
cartOwner: customer,
cart: filteredCart,
cartGuests: cartGuests || []
};
};
exports.makeCartPayload = makeCartPayload;
exports.joinGroupOrder = (0, toolkit_1.createAsyncThunk)(GroupOrderActionType.JoinGroupOrder, (requestData, { dispatch, getState, rejectWithValue }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const { api } = getState().config;
if (!api)
return null;
try {
const data = {
cart_id: requestData.cart_id,
first_name: requestData.first_name,
last_name: requestData.last_name
};
const response = yield api.postCartGuest(data);
const { cart_guest_id: cartGuestId, first_name: firstName, last_name: lastName } = response;
const { revenueCenter } = getState().order;
dispatch((0, order_1.resetOrder)());
const { serviceType, requestedAt } = getState().groupOrder;
dispatch((0, order_1.setMenuVars)({ revenueCenter, serviceType, requestedAt }));
dispatch((0, order_1.setCart)([]));
const payload = { cartGuestId, firstName, lastName };
return payload;
}
catch (err) {
return rejectWithValue(err);
}
}));
exports.fetchGroupOrder = (0, toolkit_1.createAsyncThunk)(GroupOrderActionType.FetchGroupOrder, (id, { getState, rejectWithValue }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const { api } = getState().config;
if (!api)
return;
try {
const response = yield api.getCart(id);
const { cartGuest } = getState().groupOrder;
const cartGuestId = cartGuest ? cartGuest.cartGuestId : null;
const payload = (0, exports.makeCartPayload)(response, cartGuestId);
return payload;
}
catch (err) {
return rejectWithValue(err);
}
}));
exports.updateGroupOrder = (0, toolkit_1.createAsyncThunk)(GroupOrderActionType.UpdateGroupOrder, (_, { dispatch, getState, rejectWithValue }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const { api } = getState().config;
if (!api)
return;
const { cartId, cartGuest } = getState().groupOrder;
const orderCart = getState().order.cart;
if (!orderCart || !cartGuest)
return;
try {
const data = {
cart: (0, utils_1.makeSimpleCart)(orderCart),
cart_guest_id: cartGuest.cartGuestId
};
const response = yield api.putCart(cartId, data);
const payload = (0, exports.makeCartPayload)(response, cartGuest.cartGuestId);
return payload;
}
catch (err) {
yield dispatch((0, exports.fetchGroupOrder)(cartId));
return rejectWithValue(err);
}
}));
exports.reloadGuestOrder = (0, toolkit_1.createAsyncThunk)(GroupOrderActionType.ReloadGuestOrder, (_, { dispatch, getState, rejectWithValue }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
const { api } = getState().config;
if (!api)
return;
try {
const { revenueCenterId, serviceType } = getState().groupOrder;
const { cart: items } = getState().groupOrder;
const menuItems = yield api.getMenuItems(revenueCenterId, serviceType);
const { cart } = (0, utils_1.rehydrateCart)(menuItems, items);
dispatch((0, order_1.setCart)(cart));
return;
}
catch (err) {
return rejectWithValue(err);
}
}));
exports.addCustomerGroupOrder = (0, toolkit_1.createAsyncThunk)(GroupOrderActionType.AddCustomerGroupOrder, ({ spendingLimit, callback }, { dispatch, getState, rejectWithValue }) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
try {
const api = getState().config.api;
const token = (0, customer_1.selectToken)(getState());
if (!token)
throw new Error(types_2.MISSING_CUSTOMER);
const cartData = (0, customer_1.makeCartData)(getState().order, spendingLimit);
const response = yield api.postCustomerGroupOrder(token, cartData);
const customer = getState().customer.account.profile;
const payload = Object.assign(Object.assign({}, (0, exports.makeCartPayload)(response)), { isCartOwner: true, cartOwner: customer });
if (callback)
callback();
return payload;
}
catch (err) {
const error = err;
return (0, customer_1.checkAuth)(error, dispatch, () => rejectWithValue(error));
}
}));
const groupOrderSlice = (0, toolkit_1.createSlice)({
name: types_1.ReducerType.GroupOrder,
initialState,
reducers: {
resetGroupOrder: () => initialState,
adjustGroupOrder: (state, action) => {
return Object.assign(Object.assign({}, state), action.payload);
}
},
extraReducers: builder => {
builder
.addCase(exports.joinGroupOrder.fulfilled, (state, action) => {
state.loading = 'idle';
state.error = null;
state.cartGuest = action.payload;
})
.addCase(exports.joinGroupOrder.pending, state => {
state.loading = 'pending';
})
.addCase(exports.joinGroupOrder.rejected, (state, action) => {
state.loading = 'idle';
state.error = action.payload;
})
.addCase(exports.fetchGroupOrder.fulfilled, (state, action) => {
return Object.assign(Object.assign(Object.assign({}, state), { loading: 'idle', error: null }), action.payload);
})
.addCase(exports.fetchGroupOrder.pending, state => {
state.loading = 'pending';
})
.addCase(exports.fetchGroupOrder.rejected, (state, action) => {
state.loading = 'idle';
state.error = action.payload;
})
.addCase(exports.updateGroupOrder.fulfilled, (state, action) => {
return Object.assign(Object.assign(Object.assign({}, state), { loading: 'idle', error: null }), action.payload);
})
.addCase(exports.updateGroupOrder.pending, state => {
state.loading = 'pending';
})
.addCase(exports.updateGroupOrder.rejected, (state, action) => {
state.loading = 'idle';
state.error = action.payload;
})
.addCase(exports.reloadGuestOrder.fulfilled, state => {
state.loading = 'idle';
})
.addCase(exports.reloadGuestOrder.pending, state => {
state.loading = 'pending';
})
.addCase(exports.reloadGuestOrder.rejected, (state, action) => {
state.loading = 'idle';
state.error = action.payload;
})
.addCase(exports.addCustomerGroupOrder.fulfilled, (state, action) => {
return Object.assign(Object.assign(Object.assign({}, state), action.payload), { loading: 'idle', error: null });
})
.addCase(exports.addCustomerGroupOrder.pending, state => {
state.loading = 'pending';
})
.addCase(exports.addCustomerGroupOrder.rejected, (state, action) => {
state.error = action.payload;
state.loading = 'idle';
});
}
});
_a = groupOrderSlice.actions, exports.resetGroupOrder = _a.resetGroupOrder, exports.adjustGroupOrder = _a.adjustGroupOrder;
const selectGroupOrder = (state) => state.groupOrder;
exports.selectGroupOrder = selectGroupOrder;
const selectGroupOrderToken = (state) => state.groupOrder.token;
exports.selectGroupOrderToken = selectGroupOrderToken;
exports.selectSpendingLimit = (0, toolkit_1.createSelector)((state) => {
const { cartGuest, spendingLimit } = state.groupOrder;
return { cartGuest, spendingLimit };
}, ({ cartGuest, spendingLimit }) => {
return cartGuest && spendingLimit ? parseFloat(spendingLimit) : null;
});
exports.selectGroupOrderClosed = (0, toolkit_1.createSelector)((state) => {
const { cartGuest, cutoffAt, closed } = state.groupOrder;
const tz = (0, order_1.selectTimezone)(state);
return { cartGuest, cutoffAt, closed, tz };
}, ({ cartGuest, cutoffAt, closed, tz }) => {
const cutoffDate = cutoffAt ? (0, utils_1.isoToDate)(cutoffAt, tz) : null;
const pastCutoff = cutoffDate ? (0, utils_1.currentLocalDate)(tz) > cutoffDate : false;
return cartGuest && (closed || pastCutoff);
});
exports.selectGroupOrderTests = (0, toolkit_1.createSelector)((state) => {
const { closed, cutoffAt, guestLimit, guestCount } = state.groupOrder;
const tz = (0, order_1.selectTimezone)(state);
return { closed, cutoffAt, guestLimit, guestCount, tz };
}, ({ closed, cutoffAt, guestLimit, guestCount, tz }) => {
const cutoffDate = cutoffAt ? (0, utils_1.isoToDate)(cutoffAt, tz) : null;
const pastCutoff = cutoffDate ? new Date() > cutoffDate : false;
const spotsRemaining = guestLimit ? guestLimit - (guestCount !== null && guestCount !== void 0 ? guestCount : 0) : null;
const atCapacity = spotsRemaining !== null && spotsRemaining <= 0;
return { closed, pastCutoff, atCapacity };
});
exports.selectGroupOrderPrepTimes = (0, toolkit_1.createSelector)((state) => {
const { revenueCenter, serviceType } = state.order;
return { revenueCenter, serviceType };
}, ({ revenueCenter, serviceType }) => {
if (!revenueCenter || !serviceType)
return {};
const { wait_times, group_ordering } = revenueCenter;
const { prep_time, lead_time: leadTime } = group_ordering || {};
const st = serviceType === 'WALKIN' ? 'PICKUP' : serviceType;
const waitTime = wait_times && wait_times[st] ? wait_times[st] : 0;
const prepTime = (waitTime !== null && waitTime !== void 0 ? waitTime : 0) + (prep_time !== null && prep_time !== void 0 ? prep_time : 0);
return { prepTime, leadTime };
});
exports.groupOrderReducer = groupOrderSlice.reducer;