feat: add profit and special discount fields to ProductVariant model
- Updated ProductVariant model to include 'profit' and 'special_discount_percent' fields. - Added corresponding fields in the admin interface for ProductVariant. - Created migration to add new fields to the database. feat: implement special discount code functionality in cart - Added composables for submitting and deleting special discount codes. - Updated CartSummary and CartItem components to handle special discount codes. - Enhanced API endpoints to support special discount operations. - Updated global types to include special discount code details in the cart.
This commit is contained in:
@@ -2,9 +2,11 @@
|
||||
// imports
|
||||
|
||||
import useDeleteDiscountCode from "~/composables/api/orders/useDeleteDiscountCode";
|
||||
import useDeleteSpecialDiscountCode from "~/composables/api/orders/useDeleteSpecialDiscountCode";
|
||||
import useGetCartOrders from "~/composables/api/orders/useGetCartOrders";
|
||||
import usePayOrder from "~/composables/api/orders/usePayOrder";
|
||||
import useSubmitDiscountCode from "~/composables/api/orders/useSubmitDiscountCode";
|
||||
import useSubmitSpecialDiscountCode from "~/composables/api/orders/useSubmitSpecialDiscountCode";
|
||||
import { useToast } from "~/composables/global/useToast";
|
||||
import { QUERY_KEYS } from "~/constants";
|
||||
|
||||
@@ -19,11 +21,16 @@ const { addToast } = useToast();
|
||||
const { data: cart, isLoading: cartIsLoading } = useGetCartOrders();
|
||||
|
||||
const discountCode = ref(cart.value?.discount_code?.code || "");
|
||||
const specialDiscountCode = ref(cart.value?.special_discount_code?.code || "");
|
||||
|
||||
const { mutateAsync: submitDiscountCode, isPending: submitDiscountCodeIsPending } = useSubmitDiscountCode();
|
||||
|
||||
const { mutateAsync: deleteDiscountCode, isPending: deleteDiscountCodeIsPending } = useDeleteDiscountCode();
|
||||
|
||||
const { mutateAsync: submitSpecialDiscountCode, isPending: submitSpecialDiscountCodeIsPending } = useSubmitSpecialDiscountCode();
|
||||
|
||||
const { mutateAsync: deleteSpecialDiscountCode, isPending: deleteSpecialDiscountCodeIsPending } = useDeleteSpecialDiscountCode();
|
||||
|
||||
const { mutateAsync: pay, isPending: paymentIsPending } = usePayOrder();
|
||||
|
||||
// computed
|
||||
@@ -32,6 +39,8 @@ const nextPage = computed(() => route.meta.nextPage as { name: string; label: st
|
||||
|
||||
const hasSubmittedDiscountCode = computed(() => !!cart.value?.discount_code);
|
||||
|
||||
const hasSubmittedSpecialDiscountCode = computed(() => !!cart.value?.special_discount_code);
|
||||
|
||||
// methods
|
||||
|
||||
const handleSubmitDiscountCode = () => {
|
||||
@@ -72,6 +81,44 @@ const handleDeleteDiscountCode = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmitSpecialDiscountCode = () => {
|
||||
submitSpecialDiscountCode(
|
||||
{ code: specialDiscountCode.value },
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.cart] });
|
||||
},
|
||||
onError: () => {
|
||||
addToast({
|
||||
message: "خطایی در ثبت کد تخفیف ویژه رخ داد",
|
||||
options: {
|
||||
status: "error",
|
||||
},
|
||||
});
|
||||
specialDiscountCode.value = "";
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const handleDeleteSpecialDiscountCode = () => {
|
||||
deleteSpecialDiscountCode(undefined, {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.cart] });
|
||||
specialDiscountCode.value = "";
|
||||
},
|
||||
onError: () => {
|
||||
addToast({
|
||||
message: "خطایی در حذف کد تخفیف ویژه رخ داد",
|
||||
options: {
|
||||
status: "error",
|
||||
},
|
||||
});
|
||||
specialDiscountCode.value = "";
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handlePayment = () => {
|
||||
pay(
|
||||
{
|
||||
@@ -95,6 +142,30 @@ const handlePayment = () => {
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// watch
|
||||
|
||||
watch(
|
||||
() => cart.value?.discount_code,
|
||||
(newCode) => {
|
||||
if (newCode) {
|
||||
discountCode.value = newCode.code;
|
||||
} else {
|
||||
discountCode.value = "";
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => cart.value?.special_discount_code,
|
||||
(newCode) => {
|
||||
if (newCode) {
|
||||
specialDiscountCode.value = newCode.code;
|
||||
} else {
|
||||
specialDiscountCode.value = "";
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -154,6 +225,17 @@ const handlePayment = () => {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="cart?.special_discount_total && cart.special_discount_total !== '0 تومان'"
|
||||
class="flex items-center justify-between w-full text-green-700"
|
||||
>
|
||||
<span class="max-w-1/2 text-sm"> تخفیف ویژه: </span>
|
||||
|
||||
<span class="max-w-1/2 text-sm">
|
||||
{{ cart?.special_discount_total }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between w-full text-slate-800">
|
||||
<span class="max-w-1/2 text-sm"> مالیات ارزش افزوده: </span>
|
||||
|
||||
@@ -193,6 +275,30 @@ const handlePayment = () => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex justify-between">
|
||||
<Input
|
||||
v-model="specialDiscountCode"
|
||||
placeholder="کد تخفیف ویژه"
|
||||
class="!py-3 !pe-2 ps-2.5 w-full !rounded-none !border-e-[0px] !rounded-s-100"
|
||||
:disabled="hasSubmittedSpecialDiscountCode"
|
||||
/>
|
||||
<button
|
||||
@click="hasSubmittedSpecialDiscountCode ? handleDeleteSpecialDiscountCode() : handleSubmitSpecialDiscountCode()"
|
||||
class="text-xs px-5 rounded-e-100 py-1.5 text-white bg-green-600 hover:bg-transparent hover:text-green-600 border-[1.5px] border-green-600 hover:border-green-600 transition-all disabled:cursor-not-allowed"
|
||||
:disabled="!specialDiscountCode.length || submitSpecialDiscountCodeIsPending || deleteSpecialDiscountCodeIsPending"
|
||||
>
|
||||
<Icon
|
||||
v-if="submitSpecialDiscountCodeIsPending || deleteSpecialDiscountCodeIsPending"
|
||||
name="svg-spinners:180-ring-with-bg"
|
||||
size="20"
|
||||
class="**:fill-white"
|
||||
/>
|
||||
<span v-else>
|
||||
{{ hasSubmittedSpecialDiscountCode ? "حذف" : "ثبت" }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
v-if="nextPage?.name == 'payment'"
|
||||
start-icon="ci:arrow-right"
|
||||
|
||||
@@ -232,13 +232,19 @@ watch(
|
||||
</div>
|
||||
|
||||
<div class="flex items-end gap-2">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col items-end">
|
||||
<span
|
||||
v-if="data.discount > 0"
|
||||
class="typo-p-sm relative flex-center w-fit line-through"
|
||||
class="typo-p-sm relative flex-center w-fit line-through text-slate-400"
|
||||
>
|
||||
{{ data.price }}
|
||||
</span>
|
||||
<span
|
||||
v-if="data.special_discount_amount"
|
||||
class="typo-p-xs text-green-600 font-medium"
|
||||
>
|
||||
تخفیف ویژه: {{ data.special_discount_amount }}
|
||||
</span>
|
||||
<span class="typo-p-xl relative flex-center w-fit font-medium">
|
||||
{{ data.final_price }}
|
||||
</span>
|
||||
@@ -296,13 +302,19 @@ watch(
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col items-end">
|
||||
<span
|
||||
v-if="data.discount > 0"
|
||||
class="typo-p-xs relative flex-center w-fit line-through"
|
||||
class="typo-p-xs relative flex-center w-fit line-through text-slate-400"
|
||||
>
|
||||
{{ data.price }}
|
||||
</span>
|
||||
<span
|
||||
v-if="data.special_discount_amount && data.special_discount_amount !== '0 تومان'"
|
||||
class="text-[10px] text-green-600 font-medium"
|
||||
>
|
||||
تخفیف ویژه: {{ data.special_discount_amount }}
|
||||
</span>
|
||||
<span class="typo-p-md relative flex-center w-fit font-medium">
|
||||
{{ data.final_price }}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user