discountAmount and packingFee in create order admin

This commit is contained in:
hamid zarghami
2026-07-01 12:28:51 +03:30
parent c7b4e77421
commit d52ff4f07e
3 changed files with 93 additions and 12 deletions
@@ -29,6 +29,8 @@ interface OrderSummaryData {
} | null> } | null>
subTotal: number subTotal: number
deliveryFee: number deliveryFee: number
packingFee: number
discountAmount: number
total: number total: number
totalItems: number totalItems: number
} }
@@ -129,7 +131,7 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
return ( return (
<> <>
<div className='bg-white rounded-4xl p-5 flex-1 min-h-0 flex flex-col h-full'> <div className='bg-white rounded-4xl p-4 flex-1 min-h-0 flex flex-col h-full'>
<div className='flex items-center justify-between flex-shrink-0'> <div className='flex items-center justify-between flex-shrink-0'>
<div className='flex items-center gap-2 text-sm font-light'> <div className='flex items-center gap-2 text-sm font-light'>
<ShoppingCart size={18} color='#000' /> <ShoppingCart size={18} color='#000' />
@@ -143,12 +145,12 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
</div> </div>
{(customerName || formik.values.userPhone) && ( {(customerName || formik.values.userPhone) && (
<div className='mt-3 p-3 bg-[#F8F9FC] rounded-xl flex-shrink-0'> <div className='mt-2 p-2.5 bg-[#F8F9FC] rounded-xl flex-shrink-0'>
<div className='text-xs font-medium truncate'> <div className='text-[11px] font-medium truncate'>
{customerName || 'مشتری'} {customerName || 'مشتری'}
</div> </div>
{formik.values.userPhone && ( {formik.values.userPhone && (
<div className='text-[11px] text-description mt-0.5'> <div className='text-[10px] text-description mt-0.5'>
{formik.values.userPhone} {formik.values.userPhone}
</div> </div>
)} )}
@@ -158,7 +160,7 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
<button <button
type='button' type='button'
onClick={() => setIsDeliveryModalOpen(true)} onClick={() => setIsDeliveryModalOpen(true)}
className={`mt-3 w-full text-right p-3 rounded-xl border transition-colors flex-shrink-0 ${ className={`mt-2 w-full text-right p-2.5 rounded-xl border transition-colors flex-shrink-0 ${
isDeliverySelected && isPaymentSelected isDeliverySelected && isPaymentSelected
? 'border-border hover:border-primary/40 hover:bg-[#F8F9FC]' ? 'border-border hover:border-primary/40 hover:bg-[#F8F9FC]'
: 'border-dashed border-primary/50 bg-primary/5 hover:bg-primary/10' : 'border-dashed border-primary/50 bg-primary/5 hover:bg-primary/10'
@@ -178,7 +180,7 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
</p> </p>
) : null} ) : null}
<div className='mt-2 space-y-2'> <div className='mt-1.5 space-y-1.5'>
<div className='flex items-center gap-2 text-xs'> <div className='flex items-center gap-2 text-xs'>
<Truck size={15} color='#8C90A3' className='flex-shrink-0' /> <Truck size={15} color='#8C90A3' className='flex-shrink-0' />
<span <span
@@ -221,8 +223,8 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
</div> </div>
</button> </button>
<div className='mt-4 pt-3 border-t border-border border-dashed flex-1 min-h-0 flex flex-col'> <div className='mt-3 pt-2.5 border-t border-border border-dashed flex-1 min-h-0 flex flex-col'>
<div className='text-xs text-description mb-2 flex-shrink-0'>سبد سفارش</div> <div className='text-xs text-description mb-1.5 flex-shrink-0'>سبد سفارش</div>
<div className='flex-1 min-h-0 overflow-y-auto relative'> <div className='flex-1 min-h-0 overflow-y-auto relative'>
{orderSummary.lineItems.length === 0 ? ( {orderSummary.lineItems.length === 0 ? (
@@ -233,7 +235,7 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
</div> </div>
</div> </div>
) : ( ) : (
<div className='space-y-2.5 pb-2'> <div className='space-y-2 pb-2'>
{orderSummary.lineItems.map((item) => { {orderSummary.lineItems.map((item) => {
if (!item) return null if (!item) return null
return ( return (
@@ -319,7 +321,51 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
)} )}
</div> </div>
<div className='mt-3 space-y-2 text-xs pt-3 border-t border-border flex-shrink-0'> <div className='mt-2 space-y-2 text-xs pt-2.5 border-t border-border flex-shrink-0'>
<div className='grid grid-cols-2 gap-2.5 mb-2'>
<div>
<div className='text-xs mb-1.5'>
<span className='font-medium'>هزینه بستهبندی</span>
<span className='text-description mr-1'>(اختیاری)</span>
</div>
<input
name='packingFee'
type='number'
inputMode='numeric'
min={0}
placeholder='تومان'
className='w-full h-10 rounded-xl border border-border px-3 text-sm outline-none focus:border-primary'
value={formik.values.packingFee || ''}
onChange={(e) =>
formik.setFieldValue(
'packingFee',
Math.max(Number(e.target.value) || 0, 0)
)
}
/>
</div>
<div>
<div className='text-xs mb-1.5'>
<span className='font-medium'>تخفیف مبلغی</span>
<span className='text-description mr-1'>(اختیاری)</span>
</div>
<input
name='discountAmount'
type='number'
inputMode='numeric'
min={0}
placeholder='تومان'
className='w-full h-10 rounded-xl border border-border px-3 text-sm outline-none focus:border-primary'
value={formik.values.discountAmount || ''}
onChange={(e) =>
formik.setFieldValue(
'discountAmount',
Math.max(Number(e.target.value) || 0, 0)
)
}
/>
</div>
</div>
<div className='flex justify-between'> <div className='flex justify-between'>
<span className='text-description'>جمع آیتمها</span> <span className='text-description'>جمع آیتمها</span>
<span>{formatPrice(orderSummary.subTotal)}</span> <span>{formatPrice(orderSummary.subTotal)}</span>
@@ -330,6 +376,20 @@ const CreateOrderSidebar: FC<CreateOrderSidebarProps> = ({
<span>{formatPrice(orderSummary.deliveryFee)}</span> <span>{formatPrice(orderSummary.deliveryFee)}</span>
</div> </div>
)} )}
{orderSummary.packingFee > 0 && (
<div className='flex justify-between'>
<span className='text-description'>هزینه بستهبندی</span>
<span>{formatPrice(orderSummary.packingFee)}</span>
</div>
)}
{orderSummary.discountAmount > 0 && (
<div className='flex justify-between'>
<span className='text-description'>تخفیف</span>
<span className='text-green-600'>
-{formatPrice(orderSummary.discountAmount)}
</span>
</div>
)}
<div className='flex justify-between font-bold text-sm pt-2 border-t-2 border-gray-200'> <div className='flex justify-between font-bold text-sm pt-2 border-t-2 border-gray-200'>
<span>جمع کل</span> <span>جمع کل</span>
<span>{formatPrice(orderSummary.total)}</span> <span>{formatPrice(orderSummary.total)}</span>
+21 -2
View File
@@ -33,6 +33,8 @@ export interface CreateOrderFormValues {
items: CreateOrderItem[] items: CreateOrderItem[]
deliveryMethodId: string deliveryMethodId: string
paymentMethodId: string paymentMethodId: string
discountAmount: number
packingFee: number
description: string description: string
tableNumber: string tableNumber: string
userAddress: CreateOrderUserAddress userAddress: CreateOrderUserAddress
@@ -97,6 +99,8 @@ export const useCreateOrderForm = () => {
items: [], items: [],
deliveryMethodId: '', deliveryMethodId: '',
paymentMethodId: '', paymentMethodId: '',
discountAmount: 0,
packingFee: 0,
description: '', description: '',
tableNumber: '', tableNumber: '',
userAddress: emptyUserAddress(), userAddress: emptyUserAddress(),
@@ -117,6 +121,8 @@ export const useCreateOrderForm = () => {
}) })
) )
.min(1, 'حداقل یک آیتم الزامی است'), .min(1, 'حداقل یک آیتم الزامی است'),
discountAmount: Yup.number().min(0, 'تخفیف نمی‌تواند منفی باشد'),
packingFee: Yup.number().min(0, 'هزینه بسته‌بندی نمی‌تواند منفی باشد'),
}), }),
onSubmit: async (values) => { onSubmit: async (values) => {
const selectedDelivery = deliveryMethods.find( const selectedDelivery = deliveryMethods.find(
@@ -160,6 +166,8 @@ export const useCreateOrderForm = () => {
items: values.items, items: values.items,
deliveryMethodId: values.deliveryMethodId, deliveryMethodId: values.deliveryMethodId,
paymentMethodId: values.paymentMethodId, paymentMethodId: values.paymentMethodId,
discountAmount: values.discountAmount || 0,
packingFee: values.packingFee || 0,
} }
if (values.description.trim()) { if (values.description.trim()) {
@@ -383,16 +391,27 @@ export const useCreateOrderForm = () => {
const subTotal = lineItems.reduce((sum, item) => sum + (item?.totalPrice || 0), 0) const subTotal = lineItems.reduce((sum, item) => sum + (item?.totalPrice || 0), 0)
const deliveryFee = selectedDeliveryMethod?.deliveryFee || 0 const deliveryFee = selectedDeliveryMethod?.deliveryFee || 0
const packingFee = formik.values.packingFee || 0
const discountAmount = formik.values.discountAmount || 0
const totalItems = lineItems.reduce((sum, item) => sum + (item?.quantity || 0), 0) const totalItems = lineItems.reduce((sum, item) => sum + (item?.quantity || 0), 0)
const total = Math.max(subTotal + deliveryFee + packingFee - discountAmount, 0)
return { return {
lineItems, lineItems,
subTotal, subTotal,
deliveryFee, deliveryFee,
total: subTotal + deliveryFee, packingFee,
discountAmount,
total,
totalItems, totalItems,
} }
}, [formik.values.items, foodsMap, selectedDeliveryMethod]) }, [
formik.values.items,
formik.values.packingFee,
formik.values.discountAmount,
foodsMap,
selectedDeliveryMethod,
])
const addFoodToOrder = (foodId: string) => { const addFoodToOrder = (foodId: string) => {
const existingIndex = formik.values.items.findIndex((item) => item.foodId === foodId) const existingIndex = formik.values.items.findIndex((item) => item.foodId === foodId)
+2
View File
@@ -269,6 +269,8 @@ export interface CreateOrderType {
items: CreateOrderItem[]; items: CreateOrderItem[];
deliveryMethodId: string; deliveryMethodId: string;
paymentMethodId: string; paymentMethodId: string;
discountAmount: number;
packingFee: number;
description?: string; description?: string;
tableNumber?: string; tableNumber?: string;
addressId?: string; addressId?: string;