This commit is contained in:
+311
-197
@@ -1,13 +1,23 @@
|
|||||||
import { useState, type FC } from 'react'
|
import { useState, type FC, type ReactNode } from 'react'
|
||||||
import { useFormik } from 'formik'
|
import { useFormik } from 'formik'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import moment from 'moment-jalaali'
|
import moment from 'moment-jalaali'
|
||||||
import { Link, useNavigate, useSearchParams } from 'react-router-dom'
|
import { Link, useNavigate, useSearchParams } from 'react-router-dom'
|
||||||
|
import {
|
||||||
|
Box1,
|
||||||
|
Calendar,
|
||||||
|
DocumentText,
|
||||||
|
Profile2User,
|
||||||
|
ReceiptText,
|
||||||
|
TickSquare,
|
||||||
|
WalletMoney,
|
||||||
|
} from 'iconsax-react'
|
||||||
import Input from '@/components/Input'
|
import Input from '@/components/Input'
|
||||||
import Textarea from '@/components/Textarea'
|
import Textarea from '@/components/Textarea'
|
||||||
import Select from '@/components/Select'
|
import Select from '@/components/Select'
|
||||||
import UploadBox from '@/components/UploadBox'
|
import UploadBox from '@/components/UploadBox'
|
||||||
import Button from '@/components/Button'
|
import Button from '@/components/Button'
|
||||||
|
import BackButton from '@/components/BackButton'
|
||||||
import { useMultiUpload } from '@/pages/uploader/hooks/useUploader'
|
import { useMultiUpload } from '@/pages/uploader/hooks/useUploader'
|
||||||
import type { ConvertToOrderItemType } from './types/Types'
|
import type { ConvertToOrderItemType } from './types/Types'
|
||||||
import { useConverToOrder, useGetProducts } from './hooks/useOrderData'
|
import { useConverToOrder, useGetProducts } from './hooks/useOrderData'
|
||||||
@@ -24,6 +34,35 @@ import { Checkbox } from '@/components/ui/checkbox'
|
|||||||
const formatAmount = (amount: number) =>
|
const formatAmount = (amount: number) =>
|
||||||
Number(amount).toLocaleString('fa-IR') + ' ریال'
|
Number(amount).toLocaleString('fa-IR') + ' ریال'
|
||||||
|
|
||||||
|
type InfoFieldProps = {
|
||||||
|
label: string
|
||||||
|
value: ReactNode
|
||||||
|
icon?: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
const InfoField: FC<InfoFieldProps> = ({ label, value, icon }) => (
|
||||||
|
<div className="rounded-2xl border border-border/70 bg-[#FBFCFF] p-4">
|
||||||
|
<div className="mb-2 flex items-center gap-2 text-[12px] text-[#7D8597]">
|
||||||
|
{icon}
|
||||||
|
<span>{label}</span>
|
||||||
|
</div>
|
||||||
|
<div className="text-[15px] font-medium text-[#1F2937]">{value}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
type SummaryRowProps = {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
valueClassName?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const SummaryRow: FC<SummaryRowProps> = ({ label, value, valueClassName }) => (
|
||||||
|
<div className="flex items-center justify-between rounded-xl border border-border/70 bg-white px-4 py-3">
|
||||||
|
<span className="text-[13px] text-[#6B7280]">{label}</span>
|
||||||
|
<span className={`text-[14px] font-semibold ${valueClassName ?? ''}`}>{value}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
const getInitialValues = (invoiceItemId: string | null): ConvertToOrderItemType => ({
|
const getInitialValues = (invoiceItemId: string | null): ConvertToOrderItemType => ({
|
||||||
invoiceItemId: invoiceItemId ?? '',
|
invoiceItemId: invoiceItemId ?? '',
|
||||||
productId: '',
|
productId: '',
|
||||||
@@ -46,11 +85,10 @@ const getValidationSchema = (invoiceItemId: string | null) =>
|
|||||||
estimatedDays: Yup.number().required('تخمین روز اجباری است.').min(0, 'باید عدد مثبت باشد'),
|
estimatedDays: Yup.number().required('تخمین روز اجباری است.').min(0, 'باید عدد مثبت باشد'),
|
||||||
title: Yup.string().required('عنوان اجباری است.'),
|
title: Yup.string().required('عنوان اجباری است.'),
|
||||||
description: Yup.string(),
|
description: Yup.string(),
|
||||||
designerId: Yup.string().required('این فیلد اجباری است')
|
designerId: Yup.string().required('این فیلد اجباری است'),
|
||||||
})
|
})
|
||||||
|
|
||||||
const ConvertToOrders: FC = () => {
|
const ConvertToOrders: FC = () => {
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
const invoiceItemId = searchParams.get('invoiceItemId')
|
const invoiceItemId = searchParams.get('invoiceItemId')
|
||||||
@@ -99,7 +137,7 @@ const ConvertToOrders: FC = () => {
|
|||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error(extractErrorMessage(error))
|
toast.error(extractErrorMessage(error))
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -110,186 +148,150 @@ const ConvertToOrders: FC = () => {
|
|||||||
: invoiceItem?.invoice?.user?.phone ?? '-'
|
: invoiceItem?.invoice?.user?.phone ?? '-'
|
||||||
|
|
||||||
const discounts = invoiceItem ? formatItemDiscountDisplay(invoiceItem) : null
|
const discounts = invoiceItem ? formatItemDiscountDisplay(invoiceItem) : null
|
||||||
|
const isSubmitting = multiUpload.isPending || isPending
|
||||||
|
const backTo = invoiceItem?.invoice?.id
|
||||||
|
? Paths.perfomaInvoice.detail + invoiceItem.invoice.id
|
||||||
|
: Paths.order.list
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-5">
|
<div className="mt-5 space-y-8">
|
||||||
<h1 className="text-lg font-light">تبدیل به سفارش</h1>
|
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||||
|
<div className="space-y-3">
|
||||||
{invoiceItemId && (
|
<BackButton to={backTo} />
|
||||||
<div className="mt-8 rounded-3xl bg-white p-6">
|
<div className="flex items-center gap-2 text-[#111827]">
|
||||||
<div className="font-light">اطلاعات آیتم پیش فاکتور</div>
|
<DocumentText size={20} color="#111827" />
|
||||||
|
<h1 className="text-xl font-medium">تبدیل به سفارش</h1>
|
||||||
{isInvoiceItemLoading ? (
|
</div>
|
||||||
<div className="mt-6 flex min-h-[120px] items-center justify-center text-[#888888]">
|
{invoiceItemId && invoiceItem?.product?.title && (
|
||||||
در حال بارگذاری...
|
<p className="text-sm text-[#6B7280]">
|
||||||
</div>
|
ایجاد سفارش از آیتم «{invoiceItem.product.title}»
|
||||||
) : invoiceItem ? (
|
</p>
|
||||||
<div className="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">پیش فاکتور</div>
|
|
||||||
<Link
|
|
||||||
to={Paths.perfomaInvoice.detail + invoiceItem.invoice.id}
|
|
||||||
className="text-[15px] text-primary hover:underline"
|
|
||||||
>
|
|
||||||
#{invoiceItem.invoice.invoiceNumber}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">مشتری</div>
|
|
||||||
<div className="text-[15px]">{customerName}</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">محصول</div>
|
|
||||||
<div className="text-[15px]">{invoiceItem.product?.title ?? '-'}</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">تعداد</div>
|
|
||||||
<div className="text-[15px]">{invoiceItem.quantity ?? '-'}</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">مبلغ واحد</div>
|
|
||||||
<div className="text-[15px]">
|
|
||||||
{invoiceItem.unitPrice != null
|
|
||||||
? formatAmount(invoiceItem.unitPrice)
|
|
||||||
: '-'}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">تخفیف (مبلغ)</div>
|
|
||||||
<div className="text-[15px]">{discounts?.value ?? '-'}</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">تخفیف (درصد)</div>
|
|
||||||
<div className="text-[15px]">{discounts?.percent ?? '-'}</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">مبلغ کل</div>
|
|
||||||
<div className="text-[15px] font-semibold">
|
|
||||||
{formatAmount(invoiceItem.total ?? 0)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">تاریخ تایید</div>
|
|
||||||
<div className="text-[15px]">
|
|
||||||
{invoiceItem.confirmedAt
|
|
||||||
? moment(invoiceItem.confirmedAt).format('jYYYY/jMM/jDD HH:mm')
|
|
||||||
: '-'}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{invoiceItem.description && (
|
|
||||||
<div className="sm:col-span-2 lg:col-span-3">
|
|
||||||
<div className="mb-1.5 text-[13px] text-[#888888]">توضیحات</div>
|
|
||||||
<div className="whitespace-pre-wrap text-[15px]">
|
|
||||||
{invoiceItem.description}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="mt-6 text-[15px] text-red-500">
|
|
||||||
آیتم پیش فاکتور یافت نشد.
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="bg-white rounded-3xl p-6 mt-8">
|
<Button
|
||||||
<form
|
type="button"
|
||||||
onSubmit={formik.handleSubmit}
|
className="w-fit px-5"
|
||||||
className="space-y-6"
|
onClick={() => formik.handleSubmit()}
|
||||||
|
isLoading={isSubmitting}
|
||||||
>
|
>
|
||||||
{!invoiceItemId && (
|
<div className="flex items-center gap-2">
|
||||||
<div className="rowTwoInput">
|
<TickSquare size={20} color="black" />
|
||||||
<div className="w-full">
|
<span>ثبت سفارش</span>
|
||||||
<UserSearch
|
</div>
|
||||||
label="کاربر"
|
</Button>
|
||||||
placeholder="جستجوی کاربر (نام، موبایل، ...)"
|
</div>
|
||||||
value={formik.values.userId}
|
|
||||||
onChange={(id) => {
|
<div
|
||||||
formik.setFieldValue('userId', id)
|
className={
|
||||||
formik.setFieldTouched('userId', true)
|
invoiceItemId
|
||||||
}}
|
? 'grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_320px]'
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="rounded-3xl border border-border/70 bg-white p-6 shadow-sm">
|
||||||
|
<div className="font-medium text-[#111827]">اطلاعات سفارش</div>
|
||||||
|
<p className="mt-1 text-[13px] text-[#6B7280]">
|
||||||
|
جزئیات مورد نیاز برای ثبت سفارش را تکمیل کنید.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form onSubmit={formik.handleSubmit} className="mt-6 space-y-6">
|
||||||
|
{!invoiceItemId && (
|
||||||
|
<div className="rowTwoInput">
|
||||||
|
<div className="w-full">
|
||||||
|
<UserSearch
|
||||||
|
label="کاربر"
|
||||||
|
placeholder="جستجوی کاربر (نام، موبایل، ...)"
|
||||||
|
value={formik.values.userId}
|
||||||
|
onChange={(id) => {
|
||||||
|
formik.setFieldValue('userId', id)
|
||||||
|
formik.setFieldTouched('userId', true)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{formik.touched.userId && formik.errors.userId ? (
|
||||||
|
<div className="mt-2 mr-2 text-right text-xs font-medium text-red-600">
|
||||||
|
{formik.errors.userId}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
<Select
|
||||||
|
items={
|
||||||
|
products?.data?.map((item) => ({
|
||||||
|
label: item.title,
|
||||||
|
value: String(item.id),
|
||||||
|
})) ?? []
|
||||||
|
}
|
||||||
|
label="محصول"
|
||||||
|
placeholder="انتخاب محصول"
|
||||||
|
{...formik.getFieldProps('productId')}
|
||||||
|
error_text={
|
||||||
|
formik.touched.productId && formik.errors.productId
|
||||||
|
? formik.errors.productId
|
||||||
|
: ''
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{formik.touched.userId && formik.errors.userId ? (
|
|
||||||
<div className="text-xs text-right text-red-600 mt-2 mr-2 font-medium">
|
|
||||||
{formik.errors.userId}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="rowTwoInput">
|
||||||
<Select
|
<Select
|
||||||
items={
|
items={
|
||||||
products?.data?.map((item) => ({
|
admins?.data?.map((item) => ({
|
||||||
|
label: item.firstName + ' ' + item.lastName,
|
||||||
|
value: item.id,
|
||||||
|
})) || []
|
||||||
|
}
|
||||||
|
label="طراح"
|
||||||
|
placeholder="انتخاب طراح"
|
||||||
|
{...formik.getFieldProps('designerId')}
|
||||||
|
error_text={
|
||||||
|
formik.touched.designerId && formik.errors.designerId
|
||||||
|
? formik.errors.designerId
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Select
|
||||||
|
items={
|
||||||
|
categories?.data?.map((item) => ({
|
||||||
label: item.title,
|
label: item.title,
|
||||||
value: String(item.id),
|
value: String(item.id),
|
||||||
})) ?? []
|
})) ?? []
|
||||||
}
|
}
|
||||||
label="محصول"
|
label="نوع"
|
||||||
placeholder="انتخاب محصول"
|
placeholder="انتخاب نوع"
|
||||||
{...formik.getFieldProps('productId')}
|
{...formik.getFieldProps('typeId')}
|
||||||
error_text={
|
error_text={
|
||||||
formik.touched.productId && formik.errors.productId
|
formik.touched.typeId && formik.errors.typeId
|
||||||
? formik.errors.productId
|
? formik.errors.typeId
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="rowTwoInput">
|
<div className="rowTwoInput">
|
||||||
|
<Input
|
||||||
<Select
|
label="تخمین روز"
|
||||||
items={admins?.data?.map((item) => {
|
type="number"
|
||||||
return {
|
{...formik.getFieldProps('estimatedDays')}
|
||||||
label: item.firstName + ' ' + item.lastName,
|
error_text={
|
||||||
value: item.id
|
formik.touched.estimatedDays && formik.errors.estimatedDays
|
||||||
|
? formik.errors.estimatedDays
|
||||||
|
: ''
|
||||||
}
|
}
|
||||||
}) || []}
|
/>
|
||||||
label="طراح"
|
|
||||||
placeholder="انتخاب طراح"
|
|
||||||
{...formik.getFieldProps('designerId')}
|
|
||||||
error_text={
|
|
||||||
formik.touched.designerId && formik.errors.designerId ? formik.errors.designerId : ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Select
|
<Input
|
||||||
items={
|
label="عنوان"
|
||||||
categories?.data?.map((item) => ({
|
{...formik.getFieldProps('title')}
|
||||||
label: item.title,
|
error_text={
|
||||||
value: String(item.id),
|
formik.touched.title && formik.errors.title
|
||||||
})) ?? []
|
? formik.errors.title
|
||||||
}
|
: ''
|
||||||
label="نوع"
|
}
|
||||||
placeholder="انتخاب نوع"
|
/>
|
||||||
{...formik.getFieldProps('typeId')}
|
</div>
|
||||||
error_text={
|
|
||||||
formik.touched.typeId && formik.errors.typeId ? formik.errors.typeId : ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="rowTwoInput">
|
|
||||||
<Input
|
|
||||||
label="تخمین روز"
|
|
||||||
type="number"
|
|
||||||
{...formik.getFieldProps('estimatedDays')}
|
|
||||||
error_text={
|
|
||||||
formik.touched.estimatedDays && formik.errors.estimatedDays
|
|
||||||
? formik.errors.estimatedDays
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
label="عنوان"
|
|
||||||
{...formik.getFieldProps('title')}
|
|
||||||
error_text={
|
|
||||||
formik.touched.title && formik.errors.title ? formik.errors.title : ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Textarea
|
<Textarea
|
||||||
label="توضیحات"
|
label="توضیحات"
|
||||||
placeholder="توضیحات را وارد کنید..."
|
placeholder="توضیحات را وارد کنید..."
|
||||||
@@ -300,53 +302,165 @@ const ConvertToOrders: FC = () => {
|
|||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
{invoiceItemId && (
|
{invoiceItemId && (
|
||||||
<div>
|
|
||||||
<div
|
<div
|
||||||
className={`flex items-center gap-2 ${
|
className={`rounded-2xl border border-border/70 bg-[#FBFCFF] p-4 ${
|
||||||
!hasLinkedRequest && !isInvoiceItemLoading
|
!hasLinkedRequest && !isInvoiceItemLoading
|
||||||
? 'pointer-events-none opacity-50'
|
? 'opacity-60'
|
||||||
: ''
|
: ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<div
|
||||||
id="keepRequestChats"
|
className={`flex items-center gap-2 ${
|
||||||
checked={formik.values.keepRequestChats}
|
!hasLinkedRequest && !isInvoiceItemLoading
|
||||||
onCheckedChange={(checked) =>
|
? 'pointer-events-none'
|
||||||
formik.setFieldValue('keepRequestChats', !!checked)
|
: ''
|
||||||
}
|
}`}
|
||||||
/>
|
|
||||||
<label
|
|
||||||
htmlFor="keepRequestChats"
|
|
||||||
className="cursor-pointer select-none text-[13px]"
|
|
||||||
>
|
>
|
||||||
انتقال چتهای درخواست به سفارش
|
<Checkbox
|
||||||
</label>
|
id="keepRequestChats"
|
||||||
|
checked={formik.values.keepRequestChats}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
formik.setFieldValue('keepRequestChats', !!checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="keepRequestChats"
|
||||||
|
className="cursor-pointer select-none text-[13px] text-[#1F2937]"
|
||||||
|
>
|
||||||
|
انتقال چتهای درخواست به سفارش
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{!hasLinkedRequest && !isInvoiceItemLoading && (
|
||||||
|
<p className="mt-2 text-xs text-[#888888]">
|
||||||
|
این پیشفاکتور به درخواستی متصل نیست.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!hasLinkedRequest && !isInvoiceItemLoading && (
|
)}
|
||||||
<p className="mt-2 text-xs text-[#888888]">
|
|
||||||
این پیشفاکتور به درخواستی متصل نیست.
|
<div className="rounded-2xl border border-dashed border-border/70 bg-[#FBFCFF] p-4">
|
||||||
</p>
|
<UploadBox
|
||||||
|
label="پیوستها"
|
||||||
|
isMultiple
|
||||||
|
onChange={setAttachmentFiles}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-end xl:hidden">
|
||||||
|
<Button type="submit" className="w-fit px-5" isLoading={isSubmitting}>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<TickSquare size={20} color="black" />
|
||||||
|
<span>ثبت سفارش</span>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{invoiceItemId && (
|
||||||
|
<aside className="h-fit space-y-4">
|
||||||
|
<div className="rounded-3xl border border-border/70 bg-[#F7F9FF] p-5 shadow-sm">
|
||||||
|
<div className="mb-4 flex items-center gap-2 text-[#111827]">
|
||||||
|
<ReceiptText size={18} color="#111827" />
|
||||||
|
<span className="font-medium">آیتم پیش فاکتور</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isInvoiceItemLoading ? (
|
||||||
|
<div className="flex min-h-[140px] items-center justify-center text-[#888888]">
|
||||||
|
در حال بارگذاری...
|
||||||
|
</div>
|
||||||
|
) : invoiceItem ? (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<InfoField
|
||||||
|
label="پیش فاکتور"
|
||||||
|
icon={<ReceiptText size={14} color="#7D8597" />}
|
||||||
|
value={
|
||||||
|
<Link
|
||||||
|
to={Paths.perfomaInvoice.detail + invoiceItem.invoice.id}
|
||||||
|
className="text-primary hover:underline"
|
||||||
|
>
|
||||||
|
#{invoiceItem.invoice.invoiceNumber}
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<InfoField
|
||||||
|
label="مشتری"
|
||||||
|
value={customerName}
|
||||||
|
icon={<Profile2User size={14} color="#7D8597" />}
|
||||||
|
/>
|
||||||
|
<InfoField
|
||||||
|
label="محصول"
|
||||||
|
value={invoiceItem.product?.title ?? '-'}
|
||||||
|
icon={<Box1 size={14} color="#7D8597" />}
|
||||||
|
/>
|
||||||
|
<InfoField
|
||||||
|
label="تاریخ تایید"
|
||||||
|
icon={<Calendar size={14} color="#7D8597" />}
|
||||||
|
value={
|
||||||
|
invoiceItem.confirmedAt
|
||||||
|
? moment(invoiceItem.confirmedAt).format(
|
||||||
|
'jYYYY/jMM/jDD HH:mm',
|
||||||
|
)
|
||||||
|
: '-'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{invoiceItem.description && (
|
||||||
|
<div className="rounded-2xl border border-border/70 bg-white p-4">
|
||||||
|
<div className="mb-2 text-[12px] text-[#7D8597]">
|
||||||
|
توضیحات
|
||||||
|
</div>
|
||||||
|
<div className="whitespace-pre-wrap text-[14px] text-[#1F2937]">
|
||||||
|
{invoiceItem.description}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="rounded-xl border border-red-100 bg-red-50 px-3 py-3 text-[13px] text-red-700">
|
||||||
|
آیتم پیش فاکتور یافت نشد.
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div>
|
{invoiceItem && !isInvoiceItemLoading && (
|
||||||
<UploadBox
|
<div className="rounded-3xl border border-border/70 bg-[#F7F9FF] p-5 shadow-sm">
|
||||||
label="پیوستها"
|
<div className="mb-4 flex items-center gap-2 text-[#111827]">
|
||||||
isMultiple
|
<WalletMoney size={18} color="#111827" />
|
||||||
onChange={setAttachmentFiles}
|
<span className="font-medium">خلاصه مالی</span>
|
||||||
/>
|
</div>
|
||||||
</div>
|
<div className="space-y-2">
|
||||||
|
<SummaryRow
|
||||||
<div className="flex justify-end">
|
label="تعداد"
|
||||||
<Button type="submit" isLoading={multiUpload.isPending || isPending}>
|
value={String(invoiceItem.quantity ?? '-')}
|
||||||
ثبت
|
/>
|
||||||
</Button>
|
<SummaryRow
|
||||||
</div>
|
label="مبلغ واحد"
|
||||||
</form>
|
value={
|
||||||
|
invoiceItem.unitPrice != null
|
||||||
|
? formatAmount(invoiceItem.unitPrice)
|
||||||
|
: '-'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SummaryRow
|
||||||
|
label="تخفیف (مبلغ)"
|
||||||
|
value={discounts?.value ?? '-'}
|
||||||
|
/>
|
||||||
|
<SummaryRow
|
||||||
|
label="تخفیف (درصد)"
|
||||||
|
value={discounts?.percent ?? '-'}
|
||||||
|
/>
|
||||||
|
<SummaryRow
|
||||||
|
label="مبلغ کل"
|
||||||
|
value={formatAmount(invoiceItem.total ?? 0)}
|
||||||
|
valueClassName="text-[#111827]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</aside>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user