// this is a method from /src/state/menu-options/legacy-menu-options.tsx
const getItemIdAndType = useCallback((id: string) => {
const [type, ...idSplit] = id.split('-');
const itemID = idSplit.join('-');
return { type, itemID };
}, []);
// this is a method from /src/state/menu-options/legacy-menu-options.tsx
const queryMenuData = useCallback(
async (
menuItemId: string,
menuItemType: string,
dataQuery: DocumentNode,
availabilityQuery: DocumentNode
) => {
const { type } = getItemIdAndType(`${menuItemType}-` + menuItemId);
const result = await Promise.all([
client.query({
fetchPolicy: 'no-cache',
context: { uri },
query: dataQuery,
variables: {
id: menuItemId,
},
}),
client.query({
fetchPolicy: 'no-cache',
context: { uri },
query: availabilityQuery,
variables: {
id: menuItemId,
},
}),
]);
const { data: rawData, loading } = result.reduce(
(finalResponse, res) => {
const capitalizedType = type[0].toUpperCase() + type.slice(1);
const data = res?.data;
return {
data: data?.[capitalizedType]
? [...finalResponse.data, data[capitalizedType]]
: finalResponse.data,
loading: res.loading || finalResponse.loading,
};
},
{ data: [], loading: false }
);
const [uiData, availability] = rawData;
const eitinha = merge(uiData, availability);
return eitinha;
},
[client, getItemIdAndType, uri]
);
// this method was adjusted
const applyOfferAtCheckout = useCallback(
async (offer: LoyaltyOffer, standardOffersLimit: number) => {
try {
if (appliedOffers?.length >= standardOffersLimit) {
removeFromCart({ cartId: appliedOffers[0].cartId });
}
if (isDiscountLoyaltyOffer(offer)) {
dispatch(actions.loyalty.setCmsOffers([offer]));
dispatch(actions.loyalty.setSelectedOffer(offer));
dispatch(actions.loyalty.setPersonalizedOffers([offer]));
dispatch(actions.loyalty.unshiftPersonalizedOffer(offer));
dispatch(actions.loyalty.setAppliedOffers([offer]));
// Discount offers should not show menu item details
dispatch(
actions.loyalty.applyOffer({
id: offer.loyaltyEngineId,
type: OfferType.PERSONALIZED,
isStackable: offer.isStackable,
isSurprise: isSurpriseOffer(offer),
cmsId: offer._id,
cartId: 'discount-offer',
})
);
}
if (!isDiscountLoyaltyOffer(offer) && offer?.incentives?.length && offer?.incentives[0]) {
// Dispatching to select the offer. The legacy flow only does this. The other dispatches
// aren't necessary.
dispatch(actions.loyalty.setSelectedOffer(offer));
// getting only the first incentive item for PoC purposes. This needs to be fixed at task 3
const offerItemIncentive = offer.incentives[0];
const offerItemType = offerItemIncentive._type;
// Swap items don't have an id. We need to ensure this to not get a Typescript error
const offerItemId =
offerItemIncentive.__typename === 'Combo' || offerItemIncentive.__typename === 'Picker'
? offerItemIncentive._id
: '';
// We need to check what document we'll need to use (Combo/Picker)
const itemQueryDoc =
offerItemIncentive.__typename === 'Combo' ? GetComboDocument : GetPickerDocument;
const itemAvailabilityQueryDoc =
offerItemIncentive.__typename === 'Combo'
? GetComboAvailabilityDocument
: GetPickerAvailabilityDocument;
// Get all the needed menu data
const offerItemData = await queryMenuData(
offerItemId,
offerItemType,
itemQueryDoc,
itemAvailabilityQueryDoc
);
// Compute the selected option as the menu page does. This is important because
// for Picker items the item will be converted to Item type
const computedOfferItem = ProductWizardUtils.ComputeSelectedOption(offerItemData);
// Set default selections as the menu page does. This is important. Without this
// the sub-items will not be shown
const defaultSelections = ProductWizardUtils.SetDefaultSelections({
menuObject: computedOfferItem,
});
// We need to convert the menu object from the query to a cart item valid structure. This
// is important. We can't use a Sanity menu object directly
const { mainEntry, upsellEntries, modifiersInjected } = transformMenuObjectToCartItem(
computedOfferItem,
priceForItemOptionModifier,
pricingFunction,
priceForComboSlotSelection,
{
quantity: 1, // The offer should be 1:1 always. This could will be iterable (Task 3)
modifierSelections:
transformUserSelectionsModifierToModifierSelection(defaultSelections),
pickerSelections: defaultSelections.pickerAspects,
comboSlotSelections: transformUserSelectionsComboToComboSlotSelections(
defaultSelections.comboSlot,
computedOfferItem as ICombo
),
location,
existingCartId: editingCartEntry?.cartId,
}
);
// We need to pass new params to totalPrice method to avoid problems with the price calculator
// All price-related problems will have relation with this method
const isOfferBenefit = incentiveIsOfferBenefit(offer);
const offerPrice = totalPrice(modifiersInjected, computedOfferItem, isOfferBenefit, offer);
// Dispatching to apply the offer
dispatch(
actions.loyalty.applyOffer({
id: offer.loyaltyEngineId,
type: (offer as LoyaltyAppliedOffer).type,
cartId: mainEntry?.cartId,
isStackable: offer.isStackable,
isSurprise: isSurpriseOffer(offer),
cmsId: offer._id,
})
);
dispatch(actions.loyalty.setSelectedOffer(null));
// Adds the item on the cart
upsertCart([
{
...mainEntry,
price: offerPrice,
offerVendorConfigs: offer.vendorConfigs,
...(mainEntry && { type: mapEntryTypeToOfferType(mainEntry.type) }),
},
...upsellEntries,
]);
}
queryLoyaltyUserStandardOffers({ loyaltyId: user?.loyaltyId || '' });
refreshLoyaltyUserStandardOffers();
} catch (e: any) {
trackEvent(createRbiApplyPromoCodeEvent(offer.loyaltyEngineId!, 'Failed', e.message));
}
},
[
appliedOffers,
dispatch,
editingCartEntry?.cartId,
location,
priceForComboSlotSelection,
priceForItemOptionModifier,
pricingFunction,
queryLoyaltyUserStandardOffers,
queryMenuData,
refreshLoyaltyUserStandardOffers,
removeFromCart,
totalPrice,
trackEvent,
upsertCart,
user?.loyaltyId,
]
); |