import { FC, useCallback, useEffect, useRef, useState } from 'react' import { useGetAllCompanies } from '../company/hooks/useCompanyData' import { useFormik } from 'formik' import * as Yup from 'yup' import { useDropzone } from 'react-dropzone' import { CreateBillType } from './types/Types' import { useCreateBill, useCreateBillWithExcel } from './hooks/useBillData' import Button from '../../components/Button' import Input from '../../components/Input' import { DocumentUpload, TickCircle } from 'iconsax-react' import { toast } from 'react-toastify' import { ErrorType } from '../../helpers/types' import { Pages } from '../../config/Pages' import { useNavigate } from 'react-router-dom' import { CompanyItemType } from '../company/types/CompanyTypes' import PageLoading from '../../components/PageLoading' const CreateBill: FC = () => { const navigate = useNavigate() const getCompanies = useGetAllCompanies() const createBill = useCreateBill() const createBillWithExcel = useCreateBillWithExcel() const [excelFile, setExcelFile] = useState(null) const onDropExcel = useCallback((acceptedFiles: File[]) => { setExcelFile(acceptedFiles[0] ?? null) }, []) const { getRootProps, getInputProps } = useDropzone({ onDrop: onDropExcel, accept: { 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'], 'application/vnd.ms-excel': ['.xls'], }, maxFiles: 1, multiple: false, }) const companies: CompanyItemType[] = getCompanies.data?.data?.companies ?? [] const formik = useFormik({ initialValues: { title: '', waterRate: 0, dueDays: 0, values: [], }, enableReinitialize: true, validationSchema: Yup.object({ title: Yup.string().trim(), waterRate: Yup.number().min(0, 'نرخ آب باید عدد مثبت باشد').required('نرخ آب الزامی است'), dueDays: Yup.number().min(0, 'تعداد روز مهلت باید عدد مثبت باشد').required('تعداد روز مهلت الزامی است'), values: Yup.array() .of( Yup.object({ companyId: Yup.string().required(), waterUsage: Yup.number().min(0, 'مصرف آب باید عدد مثبت باشد').required('مصرف آب الزامی است'), }) ) .min(1, 'حداقل یک شرکت باید مصرف داشته باشد') .required('اطلاعات مصرف شرکت‌ها الزامی است'), }), onSubmit: async (values) => { const filteredValues = values.values.filter((v) => v.companyId && (v.waterUsage ?? 0) >= 0) if (filteredValues.length === 0) { toast.error('حداقل یک شرکت با مصرف معتبر وارد کنید') return } values.dueDays = Number(values.dueDays) values.waterRate = Number(values.waterRate) await createBill.mutateAsync( { ...values, values: filteredValues }, { onSuccess: () => { toast.success('قبض آب با موفقیت ثبت شد') navigate(Pages.bill.list) }, onError: (error: ErrorType) => { toast.error(error.response?.data?.error?.message?.[0] ?? 'خطا در ثبت قبض') }, } ) }, }) const initializedRef = useRef(false) useEffect(() => { if (companies.length > 0 && !initializedRef.current) { initializedRef.current = true formik.setFieldValue( 'values', companies.map((c) => ({ companyId: c.id, waterUsage: 0 })) ) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [companies]) if (getCompanies.isLoading) { return } if (companies.length === 0 && !getCompanies.isLoading) { return (
شرکتی ثبت نشده است. ابتدا شرکت اضافه کنید.
) } const setWaterUsage = (companyId: string, waterUsage: number) => { const next = formik.values.values.map((v) => v.companyId === companyId ? { ...v, waterUsage } : v ) formik.setFieldValue('values', next) } const handleSubmitExcel = () => { const waterRate = Number(formik.values.waterRate) const dueDays = Number(formik.values.dueDays) if (waterRate < 0 || dueDays < 0) { toast.error('نرخ آب و تعداد روز مهلت را وارد کنید') return } if (!excelFile) { toast.error('فایل اکسل را انتخاب کنید') return } createBillWithExcel.mutate( { title: formik.values.title?.trim() || undefined, waterRate, dueDays, file: excelFile }, { onSuccess: () => { toast.success('قبض آب با موفقیت از طریق اکسل ثبت شد') navigate(Pages.bill.list) }, onError: (error: ErrorType) => { toast.error(error.response?.data?.error?.message?.[0] ?? 'خطا در ثبت قبض با اکسل') }, } ) } return (
افزودن قبض آب
فایل اکسل
{excelFile ? ( {excelFile.name} ) : ( کلیک یا فایل را اینجا رها کنید )}
اطلاعات قبض
مصرف آب به تفکیک شرکت

مصرف آب هر شرکت را در ردیف مربوطه وارد کنید.

{companies.map((company, index) => { const value = formik.values.values.find((v) => v.companyId === company.id) const usage = value?.waterUsage ?? 0 return ( ) })}
ردیف نام شرکت مصرف آب
{index + 1} {company.name} setWaterUsage(company.id, Number(e.target.value) || 0)} error_text={ Array.isArray(formik.errors.values) && formik.errors.values[index] && (formik.errors.values[index] as { waterUsage?: string })?.waterUsage ? (formik.errors.values[index] as { waterUsage: string }).waterUsage : '' } className="!mb-0" />
{formik.touched.values && typeof formik.errors.values === 'string' && (
{formik.errors.values}
)}
) } export default CreateBill