apply coupon discount
This commit is contained in:
@@ -35,6 +35,12 @@ export interface GiftDetailsType {
|
||||
isSecret: boolean;
|
||||
}
|
||||
|
||||
interface DiscountData {
|
||||
value: number;
|
||||
isGift: boolean;
|
||||
isDiscount: boolean;
|
||||
}
|
||||
|
||||
interface CartState {
|
||||
restaurant: Partial<RestaurantDetails>;
|
||||
items: CartItem[];
|
||||
@@ -57,6 +63,7 @@ interface CartState {
|
||||
useLoyaltyPoints: boolean;
|
||||
loyaltyValidationError: string | null;
|
||||
scheduledDate: string;
|
||||
discount: DiscountData;
|
||||
}
|
||||
|
||||
// localStorage keys
|
||||
@@ -81,6 +88,7 @@ export const CART_STORAGE_KEYS = {
|
||||
LOYALTY_VALIDATION_ERROR: "fascano_loyalty_validation_error",
|
||||
RESTAURANT: "fascano_restaurant",
|
||||
SCHEDULED_DATE: "fascano_scheduled_date",
|
||||
DISCOUNT: "fascano_discount",
|
||||
} as const;
|
||||
|
||||
// Utility functions for localStorage
|
||||
@@ -97,11 +105,15 @@ const getFromLocalStorage = <T>(key: string, defaultValue: T): T => {
|
||||
};
|
||||
|
||||
// Generate a unique identifier for cart items based on product ID, variant, extras, and comment
|
||||
const generateUniqueId = (item: Omit<CartItem, "quantity" | "uniqueId">): string => {
|
||||
const variantStr = item.variant || '';
|
||||
const extrasStr = item.extras ? item.extras.sort().join(',') : '';
|
||||
const extrasGroupStr = item.extrasgroup ? item.extrasgroup.sort().join(',') : '';
|
||||
const commentStr = item.comment || '';
|
||||
const generateUniqueId = (
|
||||
item: Omit<CartItem, "quantity" | "uniqueId">,
|
||||
): string => {
|
||||
const variantStr = item.variant || "";
|
||||
const extrasStr = item.extras ? item.extras.sort().join(",") : "";
|
||||
const extrasGroupStr = item.extrasgroup
|
||||
? item.extrasgroup.sort().join(",")
|
||||
: "";
|
||||
const commentStr = item.comment || "";
|
||||
|
||||
return `${item.id}-${variantStr}-${extrasStr}-${extrasGroupStr}-${commentStr}`;
|
||||
};
|
||||
@@ -153,6 +165,11 @@ const initialState: CartState = {
|
||||
),
|
||||
restaurant: getFromLocalStorage(CART_STORAGE_KEYS.RESTAURANT, { taxes: [] }),
|
||||
scheduledDate: getFromLocalStorage(CART_STORAGE_KEYS.SCHEDULED_DATE, ""),
|
||||
discount: getFromLocalStorage(CART_STORAGE_KEYS.DISCOUNT, {
|
||||
value: 0,
|
||||
isGift: false,
|
||||
isDiscount: false,
|
||||
}),
|
||||
};
|
||||
|
||||
const orderSlice = createSlice({
|
||||
@@ -189,7 +206,9 @@ const orderSlice = createSlice({
|
||||
if (existingItem) {
|
||||
// Update quantity of existing item with same configuration
|
||||
state.items = state.items.map((i) =>
|
||||
i.uniqueId === uniqueId ? { ...i, quantity: i.quantity + quantity } : i,
|
||||
i.uniqueId === uniqueId
|
||||
? { ...i, quantity: i.quantity + quantity }
|
||||
: i,
|
||||
);
|
||||
} else {
|
||||
// Add new item with its unique identifier
|
||||
@@ -220,7 +239,11 @@ const orderSlice = createSlice({
|
||||
},
|
||||
updateQuantity(
|
||||
state,
|
||||
action: PayloadAction<{ id: number | string; uniqueId: string; quantity: number }>,
|
||||
action: PayloadAction<{
|
||||
id: number | string;
|
||||
uniqueId: string;
|
||||
quantity: number;
|
||||
}>,
|
||||
) {
|
||||
const { uniqueId, quantity } = action.payload;
|
||||
state.items = state.items.map((item) =>
|
||||
@@ -236,7 +259,9 @@ const orderSlice = createSlice({
|
||||
}
|
||||
},
|
||||
removeItem(state, action: PayloadAction<string>) {
|
||||
state.items = state.items.filter((item) => item.uniqueId !== action.payload);
|
||||
state.items = state.items.filter(
|
||||
(item) => item.uniqueId !== action.payload,
|
||||
);
|
||||
|
||||
// Validate loyalty points if enabled
|
||||
if (state.useLoyaltyPoints) {
|
||||
@@ -538,6 +563,17 @@ const orderSlice = createSlice({
|
||||
);
|
||||
}
|
||||
},
|
||||
updateDiscount(state, action: PayloadAction<DiscountData>) {
|
||||
state.discount = action.payload;
|
||||
|
||||
// Sync to localStorage
|
||||
if (typeof window !== "undefined") {
|
||||
localStorage.setItem(
|
||||
CART_STORAGE_KEYS.DISCOUNT,
|
||||
JSON.stringify(state.discount),
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -569,6 +605,7 @@ export const {
|
||||
reset,
|
||||
updateRestaurant,
|
||||
updateScheduledDate,
|
||||
updateDiscount,
|
||||
} = orderSlice.actions;
|
||||
|
||||
// Tax calculation helper functions
|
||||
@@ -586,11 +623,13 @@ const calculateTotalTax = (subtotal: number, taxes: Tax[]): number => {
|
||||
// Selectors
|
||||
export const selectCart = (state: RootState) => state.order;
|
||||
export const selectCartItems = (state: RootState) => state.order.items;
|
||||
|
||||
export const selectCartTotal = (state: RootState) =>
|
||||
state.order.items.reduce(
|
||||
(total, item) => total + item.price * item.quantity,
|
||||
0,
|
||||
);
|
||||
|
||||
export const selectCartItemsQuantity =
|
||||
(uniqueId: string) => (state: RootState) => {
|
||||
const item = state.order.items.find((i) => i.uniqueId === uniqueId);
|
||||
@@ -617,6 +656,13 @@ export const selectHighestPricedLoyaltyItem = (state: RootState) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const selectDiscountTotal = (state: RootState) =>
|
||||
(state.order.discount.value / 100) * selectCartTotal(state) +
|
||||
(state.order.useLoyaltyPoints &&
|
||||
state.order.restaurant?.is_loyalty_enabled === 1
|
||||
? selectHighestPricedLoyaltyItem(state)?.price || 0
|
||||
: 0);
|
||||
|
||||
export const selectLoyaltyValidation = (state: RootState) => {
|
||||
const useLoyaltyPoints = state.order.useLoyaltyPoints;
|
||||
const loyaltyItems = selectLoyaltyItems(state);
|
||||
@@ -636,13 +682,13 @@ export const selectLoyaltyValidation = (state: RootState) => {
|
||||
export const selectTaxes = (state: RootState) => state.order.restaurant.taxes;
|
||||
|
||||
export const selectTaxAmount = (state: RootState) => {
|
||||
const subtotal = selectCartTotal(state);
|
||||
const subtotal = selectCartTotal(state) - selectDiscountTotal(state);
|
||||
const taxes = selectTaxes(state);
|
||||
return calculateTotalTax(subtotal, taxes || []);
|
||||
};
|
||||
|
||||
export const selectGrandTotal = (state: RootState) => {
|
||||
const loyaltyDiscount = selectHighestPricedLoyaltyItem(state)?.price || 0;
|
||||
const totalDiscount = selectDiscountTotal(state);
|
||||
const taxAmount = selectTaxAmount(state);
|
||||
const subtotal = selectCartTotal(state);
|
||||
const deliveryFee =
|
||||
@@ -650,11 +696,7 @@ export const selectGrandTotal = (state: RootState) => {
|
||||
? Number(state.order.restaurant?.delivery_fees) || 0
|
||||
: 0;
|
||||
|
||||
return (
|
||||
subtotal +
|
||||
taxAmount -
|
||||
(state.order.useLoyaltyPoints && state.order.restaurant?.is_loyalty_enabled === 1 ? loyaltyDiscount : 0) +
|
||||
deliveryFee
|
||||
);};
|
||||
return subtotal + taxAmount - totalDiscount + deliveryFee;
|
||||
};
|
||||
|
||||
export default orderSlice.reducer;
|
||||
|
||||
Reference in New Issue
Block a user