get factor invoice

This commit is contained in:
hamid zarghami
2025-05-04 10:53:47 +03:30
parent 80b6500ee7
commit b945ffb0a3
4 changed files with 365 additions and 64 deletions
+67
View File
@@ -0,0 +1,67 @@
import { jsPDF } from 'jspdf';
import html2canvas from 'html2canvas';
import { FC } from 'react';
import Button from './Button';
import { useTranslation } from 'react-i18next';
interface PDFGeneratorProps {
elementId: string;
fileName: string;
}
const PDFGenerator: FC<PDFGeneratorProps> = ({ elementId, fileName }) => {
const { t } = useTranslation('global');
const generatePDF = async () => {
const element = document.getElementById(elementId);
if (!element) return;
// تنظیم استایل‌های موقت برای PDF
const originalStyles = element.getAttribute('style') || '';
element.setAttribute('style', `
${originalStyles}
width: 800px !important;
margin: 0 auto !important;
padding: 20px !important;
`);
const canvas = await html2canvas(element, {
scale: 1.5, // کاهش کیفیت برای سایز کمتر
useCORS: true,
logging: false,
backgroundColor: '#ffffff',
windowWidth: 800,
width: 800
});
// برگرداندن استایل‌های اصلی
element.setAttribute('style', originalStyles);
const imgData = canvas.toDataURL('image/jpeg', 0.8); // استفاده از JPEG با کیفیت 80%
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4'
});
const imgWidth = 180; // کاهش عرض برای حاشیه بیشتر
const imgHeight = (canvas.height * imgWidth) / canvas.width;
// محاسبه موقعیت برای قرار دادن در وسط صفحه
const x = (210 - imgWidth) / 2; // 210 عرض A4 در میلی‌متر
const y = (297 - imgHeight) / 2; // 297 ارتفاع A4 در میلی‌متر
pdf.addImage(imgData, 'JPEG', x, y, imgWidth, imgHeight);
pdf.save(`${fileName}.pdf`);
};
return (
<Button
label={t('receip.get_factor')}
className='bg-[#E8E8E8] text-description text-xs'
onClick={generatePDF}
/>
);
};
export default PDFGenerator;
+92 -53
View File
@@ -18,6 +18,7 @@ import { Helmet } from 'react-helmet-async'
import { useGetProfile } from '../profile/hooks/useProfileData'
import { toast } from 'react-toastify'
import { ErrorType } from '../../helpers/types'
import PDFGenerator from '../../components/PDFGenerator'
const ReceiptsDetail: FC = () => {
@@ -108,14 +109,13 @@ const ReceiptsDetail: FC = () => {
:
<div className='flex xl:flex-row flex-col mt-8 gap-6'>
<div className='flex-1'>
<div className='w-full bg-white rounded-3xl p-8'>
<div className='flex justify-between items-center'>
<div>
<div id="receipt-details" className='w-full bg-white rounded-3xl p-8'>
<div className='flex justify-between items-center mb-6'>
<div className='text-lg font-medium'>
{t('receip.personal_information')}
</div>
</div>
{
getProfile.data?.data?.user?.financialType === 'LEGAL' ?
<LegalInfo />
@@ -125,63 +125,102 @@ const ReceiptsDetail: FC = () => {
: <RegisterInfo data={getProfile.data?.data} />
}
<div className='mt-8'>
<div className='flex justify-between items-center mb-6'>
<div className='text-lg font-medium'>
{t('receip.detail_receip')}
</div>
</div>
<div className='mt-7 text-sm'>
<div className='flex justify-between items-center text-description h-14 font-medium'>
<div>
{t('receip.description')}
</div>
<div>
{t('receip.price')}
</div>
</div>
{
getInvoce.data?.data?.invoice?.items?.map((item: ReceiptDetailItemType) => {
return (
<div key={item.id} className='flex justify-between items-center text-xs border-t border-[#EAEDF5] h-14'>
<div className='flex gap-0.5'>
<span>{item.name}</span>
<span>{item.count}</span>
<span>عدد</span>
</div>
<div>
<span>{NumberFormat(item.totalPrice)}</span> تومان
</div>
</div>
)
})
}
</div>
<div className='w-full bg-white rounded-3xl mt-8 p-8'>
<div className='flex justify-between items-center'>
<div>
{t('receip.detail_receip')}
<div className='flex justify-between items-center text-xs border-t border-[#EAEDF5] h-14'>
<div>
۱۰٪ ارزش افزوده
</div>
<div>
<span>{NumberFormat(getInvoce.data?.data?.invoice?.tax)}</span> تومان
</div>
</div>
<div className='flex justify-between gap-1 items-center text-xs border-t border-[#EAEDF5] h-14'>
<div>
جمع کل
</div>
<div className='flex gap-1'>
{
getInvoce.data?.data?.invoice?.originalPrice !== getInvoce.data?.data?.invoice?.totalPrice && (
<><span className='line-through'>{NumberFormat(getInvoce.data?.data?.invoice?.originalPrice)}</span></>
)
}
<span>{NumberFormat(getInvoce.data?.data?.invoice?.totalPrice)}</span> تومان
</div>
</div>
</div>
</div>
<div className='mt-7 text-sm'>
<div className='flex justify-between items-center text-description h-14'>
<div>
{t('receip.description')}
</div>
<div>
{t('receip.price')}
<div className='mt-8'>
<div className='flex justify-between items-center mb-6'>
<div className='text-lg font-medium'>
{t('receip.receip_information')}
</div>
</div>
{
getInvoce.data?.data?.invoice?.items?.map((item: ReceiptDetailItemType) => {
return (
<div key={item.id} className='flex justify-between items-center text-xs border-t border-[#EAEDF5] h-14'>
<div className='flex gap-0.5'>
<span>{item.name}</span>
<span>{item.count}</span>
<span>عدد</span>
</div>
<div>
<span>{NumberFormat(item.totalPrice)}</span> تومان
</div>
</div>
)
})
}
<div className='flex justify-between items-center text-xs border-t border-[#EAEDF5] h-14'>
<div>
۱۰٪ ارزش افزوده
<div className='mt-6 text-xs font-extralight'>
<div className='flex justify-between h-12 border-b items-center'>
<div className='text-description'>
{t('receip.date_factor')}
</div>
<div>
{moment(getInvoce.data?.data?.invoice?.createdAt).format('jYYYY-jMM-jDD')}
</div>
</div>
<div>
<span>{NumberFormat(getInvoce.data?.data?.invoice?.tax)}</span> تومان
<div className='flex justify-between h-12 border-b items-center'>
<div className='text-description'>
{t('receip.due_date')}
</div>
<div>
{moment(getInvoce.data?.data?.invoice?.dueDate).format('jYYYY-jMM-jDD')}
</div>
</div>
</div>
<div className='flex justify-between gap-1 items-center text-xs border-t border-[#EAEDF5] h-14'>
<div>
جمع کل
<div className='flex justify-between h-12 border-b items-center'>
<div className='text-description'>
{t('receip.factor_number')}
</div>
<div>
{moment(getInvoce.data?.data?.invoice.createdAt).format('jYYYY') + getInvoce.data?.data?.invoice.numericId}
</div>
</div>
<div className='flex gap-1'>
{
getInvoce.data?.data?.invoice?.originalPrice !== getInvoce.data?.data?.invoice?.totalPrice && (
<><span className='line-through'>{NumberFormat(getInvoce.data?.data?.invoice?.originalPrice)}</span></>
)
}
<span>{NumberFormat(getInvoce.data?.data?.invoice?.totalPrice)}</span> تومان
<div className='flex justify-between h-12 border-b items-center'>
<div className='text-description'>
{t('receip.status_factor')}
</div>
<div>
{t(`receip.${getInvoce.data?.data?.invoice?.status}`)}
</div>
</div>
</div>
</div>
@@ -245,9 +284,9 @@ const ReceiptsDetail: FC = () => {
{
getInvoce.data?.data?.invoice?.status === 'WAIT_PAYMENT' &&
<div className='flex gap-4 items-center mt-8'>
<Button
label={t('receip.get_factor')}
className='bg-[#E8E8E8] text-description text-xs'
<PDFGenerator
elementId="receipt-details"
fileName={`receipt-${getInvoce.data?.data?.invoice.numericId}`}
/>
<PayInvoice
id={id ? id : ''}