Compare commits

..

5 Commits

Author SHA1 Message Date
hamid zarghami 8e27bf39e8 Card owner
deploy to danak / build_and_deploy (push) Has been cancelled
2026-06-15 12:55:28 +03:30
hamid zarghami 20309be061 cardOwner 2026-06-15 12:55:28 +03:30
hamid zarghami 22e443cf7b payment with card to card 2026-06-15 12:55:28 +03:30
hamid zarghami 1dd639c0b1 added cardNumber in list 2026-06-15 12:55:28 +03:30
hamid zarghami da738a8adc in create payment cardnumber 2026-06-15 12:55:28 +03:30
13 changed files with 326 additions and 205 deletions
+1 -1
View File
@@ -770,7 +770,7 @@
"payment": { "payment": {
"Online": "آنلاین", "Online": "آنلاین",
"Cash": "نقدی", "Cash": "نقدی",
"CardOnDelivery": "کارت هنگام تحویل", "CreditCard": "کارت به کارت",
"Wallet": "کیف پول", "Wallet": "کیف پول",
"zarinpal": "زرین‌پال", "zarinpal": "زرین‌پال",
"payments": "پرداخت ها", "payments": "پرداخت ها",
+14 -10
View File
@@ -1,7 +1,7 @@
import { type FC, useState } from 'react' import { type FC, useState } from 'react'
import { import {
useGetOrderById, useGetOrderById,
useVerifyCashPayment, useVerifyPayment,
useChangeOrderStatus, useChangeOrderStatus,
useRefundPayment useRefundPayment
} from './hooks/useOrderData' } from './hooks/useOrderData'
@@ -14,6 +14,7 @@ import ModalConfrim from '@/components/ModalConfrim'
import CustomerInfo from './components/CustomerInfo' import CustomerInfo from './components/CustomerInfo'
import OrderItemsDetails from './components/OrderItemsDetails' import OrderItemsDetails from './components/OrderItemsDetails'
import PaymentInfo from './components/PaymentInfo' import PaymentInfo from './components/PaymentInfo'
import PaymentVerificationBox from './components/PaymentVerificationBox'
import OrderActions from './components/OrderActions' import OrderActions from './components/OrderActions'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { extractErrorMessage } from '@/config/func' import { extractErrorMessage } from '@/config/func'
@@ -22,7 +23,7 @@ import { printOrderReceipt } from './print/orderReceiptPrint'
const OrderDetails: FC = () => { const OrderDetails: FC = () => {
const { id } = useParams() const { id } = useParams()
const { data: orderData, isLoading } = useGetOrderById(id!) const { data: orderData, isLoading } = useGetOrderById(id!)
const { mutate: verifyCashPayment, isPending: isVerifyingPayment } = useVerifyCashPayment() const { mutate: verifyPayment, isPending: isVerifyingPayment } = useVerifyPayment()
const { mutate: changeOrderStatus, isPending: isChangingStatus } = useChangeOrderStatus() const { mutate: changeOrderStatus, isPending: isChangingStatus } = useChangeOrderStatus()
const { mutate: refundPayment, isPending: isRefunding } = useRefundPayment() const { mutate: refundPayment, isPending: isRefunding } = useRefundPayment()
@@ -89,6 +90,7 @@ const OrderDetails: FC = () => {
// منطق نمایش دکمه‌ها // منطق نمایش دکمه‌ها
const isCashPayment = order.paymentMethod?.method === PaymentMethodEnum.Cash const isCashPayment = order.paymentMethod?.method === PaymentMethodEnum.Cash
const isCreditCardPayment = order.paymentMethod?.method === PaymentMethodEnum.CreditCard
const isPendingPayment = order.status === OrderStatus.PENDING_PAYMENT const isPendingPayment = order.status === OrderStatus.PENDING_PAYMENT
const isOrderPaid = order.status === OrderStatus.PAID const isOrderPaid = order.status === OrderStatus.PAID
const isPreparing = order.status === OrderStatus.PREPARING const isPreparing = order.status === OrderStatus.PREPARING
@@ -102,9 +104,7 @@ const OrderDetails: FC = () => {
const isDineInOrCarDelivery = order.deliveryMethod?.method === DeliveryMethodEnum.DineIn || order.deliveryMethod?.method === DeliveryMethodEnum.DeliveryCar const isDineInOrCarDelivery = order.deliveryMethod?.method === DeliveryMethodEnum.DineIn || order.deliveryMethod?.method === DeliveryMethodEnum.DeliveryCar
const isCustomerPickup = order.deliveryMethod?.method === DeliveryMethodEnum.CustomerPickup const isCustomerPickup = order.deliveryMethod?.method === DeliveryMethodEnum.CustomerPickup
// نمایش دکمه تایید پرداخت نقدی const showVerifyPaymentBox = (isCashPayment || isCreditCardPayment) && isPaymentPending && !isCanceled
// وقتی روش پرداخت نقدی است و وضعیت پرداخت Pending باشد
const showVerifyCashPaymentButton = isCashPayment && isPaymentPending
// نمایش دکمه ارسال به آشپزخانه // نمایش دکمه ارسال به آشپزخانه
// برای pendingPayment با پرداخت نقدی یا برای paid // برای pendingPayment با پرداخت نقدی یا برای paid
@@ -114,10 +114,10 @@ const OrderDetails: FC = () => {
// همیشه نمایش داده می‌شود مگر اینکه سفارش قبلاً کنسل شده باشد // همیشه نمایش داده می‌شود مگر اینکه سفارش قبلاً کنسل شده باشد
const showCancelButton = !isCanceled const showCancelButton = !isCanceled
const handleVerifyCashPayment = () => { const handleVerifyPayment = () => {
const paymentId = order.paymentId || order.payments?.[0]?.id const paymentId = order.paymentId || order.payments?.[0]?.id
if (paymentId) { if (paymentId) {
verifyCashPayment(paymentId, { verifyPayment(paymentId, {
onSuccess: () => { onSuccess: () => {
// Success handled by query invalidation // Success handled by query invalidation
}, },
@@ -232,9 +232,15 @@ const OrderDetails: FC = () => {
getPaymentStatusTextColor={getPaymentStatusTextColor} getPaymentStatusTextColor={getPaymentStatusTextColor}
getPaymentStatusText={getPaymentStatusText} getPaymentStatusText={getPaymentStatusText}
/> />
{showVerifyPaymentBox && (
<PaymentVerificationBox
order={order}
isVerifyingPayment={isVerifyingPayment}
onVerifyPayment={handleVerifyPayment}
/>
)}
<OrderActions <OrderActions
onPrint={handlePrintOrder} onPrint={handlePrintOrder}
showVerifyCashPaymentButton={showVerifyCashPaymentButton}
showSendToKitchenButton={showSendToKitchenButton} showSendToKitchenButton={showSendToKitchenButton}
showCancelButton={showCancelButton} showCancelButton={showCancelButton}
isPreparing={isPreparing} isPreparing={isPreparing}
@@ -242,9 +248,7 @@ const OrderDetails: FC = () => {
isDineInOrCarDelivery={isDineInOrCarDelivery} isDineInOrCarDelivery={isDineInOrCarDelivery}
isCustomerPickup={isCustomerPickup} isCustomerPickup={isCustomerPickup}
isCanceled={isCanceled} isCanceled={isCanceled}
isVerifyingPayment={isVerifyingPayment}
isChangingStatus={isChangingStatus} isChangingStatus={isChangingStatus}
onVerifyCashPayment={handleVerifyCashPayment}
onSendToKitchen={handleSendToKitchen} onSendToKitchen={handleSendToKitchen}
onDeliverToCourier={handleDeliverToCourier} onDeliverToCourier={handleDeliverToCourier}
onDeliverToWaiter={handleDeliverToWaiter} onDeliverToWaiter={handleDeliverToWaiter}
+2 -17
View File
@@ -3,7 +3,6 @@ import { type FC, useState, useEffect } from 'react'
interface OrderActionsProps { interface OrderActionsProps {
onPrint: () => void onPrint: () => void
showVerifyCashPaymentButton: boolean
showSendToKitchenButton: boolean showSendToKitchenButton: boolean
showCancelButton: boolean showCancelButton: boolean
isPreparing: boolean isPreparing: boolean
@@ -11,9 +10,7 @@ interface OrderActionsProps {
isDineInOrCarDelivery: boolean isDineInOrCarDelivery: boolean
isCustomerPickup: boolean isCustomerPickup: boolean
isCanceled: boolean isCanceled: boolean
isVerifyingPayment: boolean
isChangingStatus: boolean isChangingStatus: boolean
onVerifyCashPayment: () => void
onSendToKitchen: () => void onSendToKitchen: () => void
onDeliverToCourier: () => void onDeliverToCourier: () => void
onDeliverToWaiter: () => void onDeliverToWaiter: () => void
@@ -23,7 +20,6 @@ interface OrderActionsProps {
const OrderActions: FC<OrderActionsProps> = ({ const OrderActions: FC<OrderActionsProps> = ({
onPrint, onPrint,
showVerifyCashPaymentButton,
showSendToKitchenButton, showSendToKitchenButton,
showCancelButton, showCancelButton,
isPreparing, isPreparing,
@@ -31,9 +27,7 @@ const OrderActions: FC<OrderActionsProps> = ({
isDineInOrCarDelivery, isDineInOrCarDelivery,
isCustomerPickup, isCustomerPickup,
isCanceled, isCanceled,
isVerifyingPayment,
isChangingStatus, isChangingStatus,
onVerifyCashPayment,
onSendToKitchen, onSendToKitchen,
onDeliverToCourier, onDeliverToCourier,
onDeliverToWaiter, onDeliverToWaiter,
@@ -43,10 +37,10 @@ const OrderActions: FC<OrderActionsProps> = ({
const [loadingAction, setLoadingAction] = useState<string | null>(null) const [loadingAction, setLoadingAction] = useState<string | null>(null)
useEffect(() => { useEffect(() => {
if (!isChangingStatus && !isVerifyingPayment) { if (!isChangingStatus) {
setLoadingAction(null) setLoadingAction(null)
} }
}, [isChangingStatus, isVerifyingPayment]) }, [isChangingStatus])
const handleSendToKitchen = () => { const handleSendToKitchen = () => {
setLoadingAction('sendToKitchen') setLoadingAction('sendToKitchen')
@@ -81,15 +75,6 @@ const OrderActions: FC<OrderActionsProps> = ({
className='bg-slate-700 hover:bg-slate-800' className='bg-slate-700 hover:bg-slate-800'
/> />
{!isCanceled && showVerifyCashPaymentButton && (
<Button
label='تایید پرداخت'
onClick={onVerifyCashPayment}
isloading={isVerifyingPayment}
className='bg-green-600 hover:bg-green-700'
/>
)}
{!isCanceled && showSendToKitchenButton && ( {!isCanceled && showSendToKitchenButton && (
<Button <Button
label='ارسال به آشپزخانه' label='ارسال به آشپزخانه'
+128 -167
View File
@@ -1,178 +1,139 @@
import type { FC } from 'react' import { formatFaNumber, formatPrice } from "@/helpers/func";
import type { Order } from '../types/Types' import { PaymentMethodEnum } from "@/pages/paymentMethods/enum/Enum";
import { DeliveryMethodEnum } from '@/pages/shipmentMethod/enum/Enum' import { DeliveryMethodEnum } from "@/pages/shipmentMethod/enum/Enum";
import { PaymentMethodEnum } from '@/pages/paymentMethods/enum/Enum' import type { FC } from "react";
import { formatPrice, formatFaNumber } from '@/helpers/func' import type { Order } from "../types/Types";
interface PaymentInfoProps { interface PaymentInfoProps {
order: Order order: Order;
getPaymentStatusColor: (status: string) => string getPaymentStatusColor: (status: string) => string;
getPaymentStatusTextColor: (status: string) => string getPaymentStatusTextColor: (status: string) => string;
getPaymentStatusText: (status: string) => string getPaymentStatusText: (status: string) => string;
} }
const PaymentInfo: FC<PaymentInfoProps> = ({ const PaymentInfo: FC<PaymentInfoProps> = ({ order, getPaymentStatusColor, getPaymentStatusTextColor, getPaymentStatusText }) => {
order, const paymentStatus = order.payments?.[0]?.status;
getPaymentStatusColor,
getPaymentStatusTextColor,
getPaymentStatusText
}) => {
const paymentStatus = order.payments?.[0]?.status const getDeliveryMethodText = (method: string): string => {
const methodMap: Record<string, string> = {
[DeliveryMethodEnum.DineIn]: "سرو در رستوران",
[DeliveryMethodEnum.CustomerPickup]: "دریافت از محل",
[DeliveryMethodEnum.DeliveryCar]: "تحویل به خودرو",
[DeliveryMethodEnum.DeliveryCourier]: "بیرون بر",
};
return methodMap[method] || method;
};
const getDeliveryMethodText = (method: string): string => { const getPaymentMethodText = (method: string): string => {
const methodMap: Record<string, string> = { const methodMap: Record<string, string> = {
[DeliveryMethodEnum.DineIn]: 'سرو در رستوران', [PaymentMethodEnum.Cash]: "پرداخت نقدی",
[DeliveryMethodEnum.CustomerPickup]: 'دریافت از محل', [PaymentMethodEnum.Online]: "پرداخت آنلاین",
[DeliveryMethodEnum.DeliveryCar]: 'تحویل به خودرو', [PaymentMethodEnum.CreditCard]: "پرداخت کارت به کارت",
[DeliveryMethodEnum.DeliveryCourier]: 'بیرون بر', [PaymentMethodEnum.Wallet]: "کیف پول",
} };
return methodMap[method] || method return methodMap[method] || method;
} };
const getPaymentMethodText = (method: string): string => { return (
const methodMap: Record<string, string> = { <div className="w-[330px] h-fit bg-white rounded-4xl p-8">
[PaymentMethodEnum.Cash]: 'پرداخت نقدی', <div className="flex justify-between items-center">
[PaymentMethodEnum.Online]: 'پرداخت آنلاین', <div className="font-light">اطلاعات پرداخت</div>
[PaymentMethodEnum.CardOnDelivery]: 'پرداخت در محل',
[PaymentMethodEnum.Wallet]: 'کیف پول',
}
return methodMap[method] || method
}
return ( <div className="flex gap-1.5 items-center">
<div className='w-[330px] h-fit bg-white rounded-4xl p-8'> <div className={`size-2 rounded-full ${getPaymentStatusColor(paymentStatus)}`}></div>
<div className='flex justify-between items-center'> <div className={`text-[13px] ${getPaymentStatusTextColor(paymentStatus)}`}>{getPaymentStatusText(paymentStatus)}</div>
<div className='font-light'>
اطلاعات پرداخت
</div>
<div className='flex gap-1.5 items-center'>
<div className={`size-2 rounded-full ${getPaymentStatusColor(paymentStatus)}`}></div>
<div className={`text-[13px] ${getPaymentStatusTextColor(paymentStatus)}`}>
{getPaymentStatusText(paymentStatus)}
</div>
</div>
</div>
<div className='mt-10'>
<div className='flex text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
روش ارسال
</div>
<div>{order.deliveryMethod ? getDeliveryMethodText(order.deliveryMethod.method) : '-'}</div>
</div>
{order.deliveryMethod?.description && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
توضیحات روش ارسال
</div>
<div>{order.deliveryMethod.description}</div>
</div>
)}
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
روش پرداخت
</div>
<div>{order.paymentMethod ? getPaymentMethodText(order.paymentMethod.method) : '-'}</div>
</div>
{order.paymentMethod?.description && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
توضیحات روش پرداخت
</div>
<div>{order.paymentMethod.description}</div>
</div>
)}
{order.paymentMethod?.gateway && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
درگاه پرداخت
</div>
<div>{order.paymentMethod.gateway}</div>
</div>
)}
{order.paymentId && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
شناسه پرداخت
</div>
<div className='font-mono text-xs'>{order.paymentId}</div>
</div>
)}
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
جمع آیتمها
</div>
<div>{formatPrice(order.subTotal)}</div>
</div>
{order.itemsDiscount > 0 && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
تخفیف آیتمها
</div>
<div className='text-green-600'>-{formatPrice(order.itemsDiscount)}</div>
</div>
)}
{order.couponDiscount > 0 && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
تخفیف کوپن
</div>
<div className='text-green-600'>-{formatPrice(order.couponDiscount)}</div>
</div>
)}
{order.totalDiscount > 0 && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description font-medium'>
جمع تخفیفها
</div>
<div className='text-green-600 font-medium'>-{formatPrice(order.totalDiscount)}</div>
</div>
)}
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
هزینه ارسال
</div>
<div>{formatPrice(order.deliveryFee)}</div>
</div>
{order.tax > 0 && (
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
مالیات
</div>
<div>{formatPrice(order.tax)}</div>
</div>
)}
<div className='flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4'>
<div className='text-description'>
تعداد آیتمها
</div>
<div>{formatFaNumber(order.totalItems)}</div>
</div>
<div className='flex mt-4 text-[13px] font-bold justify-between items-center'>
<div>
مبلغ کل
</div>
<div>{formatPrice(order.total)}</div>
</div>
</div>
</div> </div>
) </div>
}
export default PaymentInfo <div className="mt-10">
<div className="flex text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">روش ارسال</div>
<div>{order.deliveryMethod ? getDeliveryMethodText(order.deliveryMethod.method) : "-"}</div>
</div>
{order.deliveryMethod?.description && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">توضیحات روش ارسال</div>
<div>{order.deliveryMethod.description}</div>
</div>
)}
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">روش پرداخت</div>
<div>{order.paymentMethod ? getPaymentMethodText(order.paymentMethod.method) : "-"}</div>
</div>
{order.paymentMethod?.description && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">توضیحات روش پرداخت</div>
<div>{order.paymentMethod.description}</div>
</div>
)}
{order.paymentMethod?.gateway && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">درگاه پرداخت</div>
<div>{order.paymentMethod.gateway}</div>
</div>
)}
{order.paymentId && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">شناسه پرداخت</div>
<div className="font-mono text-xs">{order.paymentId}</div>
</div>
)}
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">جمع آیتمها</div>
<div>{formatPrice(order.subTotal)}</div>
</div>
{order.itemsDiscount > 0 && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">تخفیف آیتمها</div>
<div className="text-green-600">-{formatPrice(order.itemsDiscount)}</div>
</div>
)}
{order.couponDiscount > 0 && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">تخفیف کوپن</div>
<div className="text-green-600">-{formatPrice(order.couponDiscount)}</div>
</div>
)}
{order.totalDiscount > 0 && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description font-medium">جمع تخفیفها</div>
<div className="text-green-600 font-medium">-{formatPrice(order.totalDiscount)}</div>
</div>
)}
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">هزینه ارسال</div>
<div>{formatPrice(order.deliveryFee)}</div>
</div>
{order.tax > 0 && (
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">مالیات</div>
<div>{formatPrice(order.tax)}</div>
</div>
)}
<div className="flex mt-4 text-[13px] font-light justify-between items-center border-b border-border border-dashed pb-4">
<div className="text-description">تعداد آیتمها</div>
<div>{formatFaNumber(order.totalItems)}</div>
</div>
<div className="flex mt-4 text-[13px] font-bold justify-between items-center">
<div>مبلغ کل</div>
<div>{formatPrice(order.total)}</div>
</div>
</div>
</div>
);
};
export default PaymentInfo;
@@ -0,0 +1,67 @@
import Button from '@/components/Button'
import { PaymentMethodEnum } from '@/pages/paymentMethods/enum/Enum'
import type { FC } from 'react'
import type { Order } from '../types/Types'
interface PaymentVerificationBoxProps {
order: Order
isVerifyingPayment: boolean
onVerifyPayment: () => void
}
const PaymentVerificationBox: FC<PaymentVerificationBoxProps> = ({
order,
isVerifyingPayment,
onVerifyPayment,
}) => {
const payment = order.payments?.[0]
const isCreditCard = order.paymentMethod?.method === PaymentMethodEnum.CreditCard
const hasDescription = Boolean(payment?.description)
const hasAttachments = Boolean(payment?.attachments && payment.attachments.length > 0)
return (
<div className='w-[330px] h-fit bg-white rounded-4xl p-8 mt-6'>
<div className='font-light'>اطلاعات تایید پرداخت</div>
<div className='mt-6 space-y-4 text-[13px] font-light'>
{isCreditCard && hasDescription && (
<div>
<div className='text-description mb-2'>توضیحات پرداخت</div>
<div className='text-gray-700 bg-gray-50 p-3 rounded-lg'>{payment?.description}</div>
</div>
)}
{isCreditCard && hasAttachments && (
<div>
<div className='text-description mb-2'>پیوست پرداخت</div>
<div className='flex gap-3 flex-wrap'>
{payment?.attachments?.map((attachment, index) => (
<a
key={index}
href={attachment}
target='_blank'
rel='noopener noreferrer'
>
<img
src={attachment}
alt={`پیوست پرداخت ${index + 1}`}
className='w-24 h-24 object-cover rounded-xl border border-border'
/>
</a>
))}
</div>
</div>
)}
<Button
label='تایید پرداخت'
onClick={onVerifyPayment}
isloading={isVerifyingPayment}
className='bg-green-600 hover:bg-green-700 w-full'
/>
</div>
</div>
)
}
export default PaymentVerificationBox
+2 -2
View File
@@ -28,10 +28,10 @@ export const useConfirmOrder = () => {
}); });
}; };
export const useVerifyCashPayment = () => { export const useVerifyPayment = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: (paymentId: string) => api.verifyCashPayment(paymentId), mutationFn: (paymentId: string) => api.verifyPayment(paymentId),
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["order"] }); queryClient.invalidateQueries({ queryKey: ["order"] });
queryClient.invalidateQueries({ queryKey: ["orders"] }); queryClient.invalidateQueries({ queryKey: ["orders"] });
+2 -2
View File
@@ -64,8 +64,8 @@ export const confirmOrder = async (orderId: string): Promise<void> => {
await axios.patch(`/admin/orders/${orderId}/confirm`); await axios.patch(`/admin/orders/${orderId}/confirm`);
}; };
export const verifyCashPayment = async (paymentId: string): Promise<void> => { export const verifyPayment = async (paymentId: string): Promise<void> => {
await axios.post(`/admin/payments/verify-cash-method/${paymentId}`); await axios.post(`/admin/payments/verify/${paymentId}`);
}; };
export const changeOrderStatus = async ( export const changeOrderStatus = async (
+6 -2
View File
@@ -45,7 +45,7 @@ export interface OrderRestaurant {
menuColor: string | null; menuColor: string | null;
latitude: number | null; latitude: number | null;
longitude: number | null; longitude: number | null;
serviceArea: ServiceArea; serviceArea: ServiceArea | null;
isActive: boolean; isActive: boolean;
establishedYear: number | null; establishedYear: number | null;
phone: string; phone: string;
@@ -62,6 +62,8 @@ export interface OrderRestaurant {
score: RestaurantScore; score: RestaurantScore;
plan: string; plan: string;
subscriptionId: string; subscriptionId: string;
subscriptionStartDate: string;
subscriptionEndDate: string;
} }
export interface OrderDeliveryMethod { export interface OrderDeliveryMethod {
@@ -108,6 +110,7 @@ export interface OrderPaymentMethod {
method: string; method: string;
gateway: string | null; gateway: string | null;
description: string; description: string;
cardNumber: string | null;
enabled: boolean; enabled: boolean;
order: number; order: number;
merchantId: string | null; merchantId: string | null;
@@ -122,7 +125,7 @@ export interface OrderFood {
category: string; category: string;
title: string; title: string;
desc: string; desc: string;
content: string[]; content: string[] | null;
price: number; price: number;
order: number | null; order: number | null;
prepareTime: number | null; prepareTime: number | null;
@@ -172,6 +175,7 @@ export interface OrderPayment {
paidAt: string | null; paidAt: string | null;
failedAt: string | null; failedAt: string | null;
description: string | null; description: string | null;
attachments: string[] | null;
} }
export interface CouponDetail { export interface CouponDetail {
+41 -1
View File
@@ -25,7 +25,7 @@ const CreatePaymentMethod: FC = () => {
const paymentMethods = [ const paymentMethods = [
{ label: t(`payment.${PaymentMethodEnum.Online}`), value: PaymentMethodEnum.Online }, { label: t(`payment.${PaymentMethodEnum.Online}`), value: PaymentMethodEnum.Online },
{ label: t(`payment.${PaymentMethodEnum.Cash}`), value: PaymentMethodEnum.Cash }, { label: t(`payment.${PaymentMethodEnum.Cash}`), value: PaymentMethodEnum.Cash },
{ label: t(`payment.${PaymentMethodEnum.CardOnDelivery}`), value: PaymentMethodEnum.CardOnDelivery }, { label: t(`payment.${PaymentMethodEnum.CreditCard}`), value: PaymentMethodEnum.CreditCard },
{ label: t(`payment.${PaymentMethodEnum.Wallet}`), value: PaymentMethodEnum.Wallet }, { label: t(`payment.${PaymentMethodEnum.Wallet}`), value: PaymentMethodEnum.Wallet },
] ]
@@ -41,6 +41,8 @@ const CreatePaymentMethod: FC = () => {
enabled: true, enabled: true,
order: 0, order: 0,
merchantId: '', merchantId: '',
cardNumber: '',
cardOwner: '',
}, },
validationSchema: Yup.object().shape({ validationSchema: Yup.object().shape({
method: Yup.string().required('روش پرداخت الزامی است'), method: Yup.string().required('روش پرداخت الزامی است'),
@@ -57,6 +59,16 @@ const CreatePaymentMethod: FC = () => {
then: (schema) => schema.required('شناسه مرچنت الزامی است'), then: (schema) => schema.required('شناسه مرچنت الزامی است'),
otherwise: (schema) => schema.notRequired(), otherwise: (schema) => schema.notRequired(),
}), }),
cardNumber: Yup.string().when('method', {
is: PaymentMethodEnum.CreditCard,
then: (schema) => schema.required('شماره کارت الزامی است'),
otherwise: (schema) => schema.notRequired(),
}),
cardOwner: Yup.string().when('method', {
is: PaymentMethodEnum.CreditCard,
then: (schema) => schema.required('نام صاحب کارت الزامی است'),
otherwise: (schema) => schema.notRequired(),
}),
}), }),
onSubmit: (values) => { onSubmit: (values) => {
const submitValues: CreateRestaurantPaymentMethodType = { const submitValues: CreateRestaurantPaymentMethodType = {
@@ -70,6 +82,12 @@ const CreatePaymentMethod: FC = () => {
merchantId: values.merchantId, merchantId: values.merchantId,
} }
: {}), : {}),
...(values.method === PaymentMethodEnum.CreditCard
? {
cardNumber: values.cardNumber,
cardOwner: values.cardOwner,
}
: {}),
} }
createPaymentMethod(submitValues, { createPaymentMethod(submitValues, {
@@ -141,6 +159,28 @@ const CreatePaymentMethod: FC = () => {
</div> </div>
</> </>
)} )}
{formik.values.method === PaymentMethodEnum.CreditCard && (
<>
<div className='mt-6'>
<Input
label='شماره کارت'
name='cardNumber'
value={formik.values.cardNumber}
onChange={formik.handleChange}
error_text={formik.touched.cardNumber && formik.errors.cardNumber ? formik.errors.cardNumber : ''}
/>
</div>
<div className='mt-6'>
<Input
label='نام صاحب کارت'
name='cardOwner'
value={formik.values.cardOwner}
onChange={formik.handleChange}
error_text={formik.touched.cardOwner && formik.errors.cardOwner ? formik.errors.cardOwner : ''}
/>
</div>
</>
)}
<div className='mt-6'> <div className='mt-6'>
<Textarea <Textarea
label='توضیحات' label='توضیحات'
+43 -1
View File
@@ -27,7 +27,7 @@ const UpdatePaymentMethod: FC = () => {
const paymentMethods = [ const paymentMethods = [
{ label: t(`payment.${PaymentMethodEnum.Online}`), value: PaymentMethodEnum.Online }, { label: t(`payment.${PaymentMethodEnum.Online}`), value: PaymentMethodEnum.Online },
{ label: t(`payment.${PaymentMethodEnum.Cash}`), value: PaymentMethodEnum.Cash }, { label: t(`payment.${PaymentMethodEnum.Cash}`), value: PaymentMethodEnum.Cash },
{ label: t(`payment.${PaymentMethodEnum.CardOnDelivery}`), value: PaymentMethodEnum.CardOnDelivery }, { label: t(`payment.${PaymentMethodEnum.CreditCard}`), value: PaymentMethodEnum.CreditCard },
{ label: t(`payment.${PaymentMethodEnum.Wallet}`), value: PaymentMethodEnum.Wallet }, { label: t(`payment.${PaymentMethodEnum.Wallet}`), value: PaymentMethodEnum.Wallet },
] ]
@@ -45,6 +45,8 @@ const UpdatePaymentMethod: FC = () => {
enabled: data.enabled ?? true, enabled: data.enabled ?? true,
order: data.order || 0, order: data.order || 0,
merchantId: data.merchantId || '', merchantId: data.merchantId || '',
cardNumber: data.cardNumber || '',
cardOwner: data.cardOwner || '',
} }
} }
return { return {
@@ -54,6 +56,8 @@ const UpdatePaymentMethod: FC = () => {
enabled: true, enabled: true,
order: 0, order: 0,
merchantId: '', merchantId: '',
cardNumber: '',
cardOwner: '',
} }
}, [paymentMethodData]) }, [paymentMethodData])
@@ -75,6 +79,16 @@ const UpdatePaymentMethod: FC = () => {
then: (schema) => schema.required('شناسه مرچنت الزامی است'), then: (schema) => schema.required('شناسه مرچنت الزامی است'),
otherwise: (schema) => schema.notRequired(), otherwise: (schema) => schema.notRequired(),
}), }),
cardNumber: Yup.string().when('method', {
is: PaymentMethodEnum.CreditCard,
then: (schema) => schema.required('شماره کارت الزامی است'),
otherwise: (schema) => schema.notRequired(),
}),
cardOwner: Yup.string().when('method', {
is: PaymentMethodEnum.CreditCard,
then: (schema) => schema.required('نام صاحب کارت الزامی است'),
otherwise: (schema) => schema.notRequired(),
}),
}), }),
onSubmit: (values) => { onSubmit: (values) => {
if (!id) return if (!id) return
@@ -90,6 +104,12 @@ const UpdatePaymentMethod: FC = () => {
merchantId: values.merchantId, merchantId: values.merchantId,
} }
: {}), : {}),
...(values.method === PaymentMethodEnum.CreditCard
? {
cardNumber: values.cardNumber,
cardOwner: values.cardOwner,
}
: {}),
} }
updateRestaurantPaymentMethod( updateRestaurantPaymentMethod(
@@ -180,6 +200,28 @@ const UpdatePaymentMethod: FC = () => {
</div> </div>
</> </>
)} )}
{formik.values.method === PaymentMethodEnum.CreditCard && (
<>
<div className='mt-6'>
<Input
label='شماره کارت'
name='cardNumber'
value={formik.values.cardNumber}
onChange={formik.handleChange}
error_text={formik.touched.cardNumber && formik.errors.cardNumber ? formik.errors.cardNumber : ''}
/>
</div>
<div className='mt-6'>
<Input
label='نام صاحب کارت'
name='cardOwner'
value={formik.values.cardOwner}
onChange={formik.handleChange}
error_text={formik.touched.cardOwner && formik.errors.cardOwner ? formik.errors.cardOwner : ''}
/>
</div>
</>
)}
<div className='mt-6'> <div className='mt-6'>
<Textarea <Textarea
label='توضیحات' label='توضیحات'
@@ -60,6 +60,20 @@ export const getPaymentMethodTableColumns = ({ onDelete, isDeleting }: GetPaymen
return item.merchantId || '-' return item.merchantId || '-'
} }
}, },
{
key: 'cardNumber',
title: 'شماره کارت',
render: (item: RestaurantPaymentMethod) => {
return item.cardNumber || '-'
}
},
{
key: 'cardOwner',
title: 'نام صاحب کارت',
render: (item: RestaurantPaymentMethod) => {
return item.cardOwner || '-'
}
},
{ {
key: 'actions', key: 'actions',
title: '', title: '',
+2 -2
View File
@@ -1,8 +1,8 @@
export const enum PaymentMethodEnum { export enum PaymentMethodEnum {
Online = "Online", Online = "Online",
Cash = "Cash", Cash = "Cash",
CardOnDelivery = "CardOnDelivery",
Wallet = "Wallet", Wallet = "Wallet",
CreditCard = "CreditCard",
} }
export const enum PaymentGatewayEnum { export const enum PaymentGatewayEnum {
+4
View File
@@ -67,6 +67,8 @@ export type RestaurantPaymentMethod = {
enabled: boolean; enabled: boolean;
order: number; order: number;
merchantId: string; merchantId: string;
cardNumber?: string;
cardOwner?: string;
}; };
export type RestaurantPaymentMethodResponse = IResponse< export type RestaurantPaymentMethodResponse = IResponse<
@@ -80,6 +82,8 @@ export type CreateRestaurantPaymentMethodType = {
enabled: boolean; enabled: boolean;
order: number; order: number;
merchantId?: string; merchantId?: string;
cardNumber?: string;
cardOwner?: string;
}; };
export type GetRestaurantPaymentMethodsParams = { export type GetRestaurantPaymentMethodsParams = {