import { useSelector } from 'react-redux';
import { GlobalPritdummyData } from '../../../Features/ThemeChange/ThemeChange';
import { isMobile } from 'react-device-detect';
import { extractLastNumberOrderId } from '../../../Services/Others';
import moment from 'moment';
const PurPrintstyleInvoice = ({
index,
table2Data,
Date1,
totalQuantity,
OrderDetailGST,
OrderDetailIGST,
PaymentStatus,
printDatas,
BankDetails
}) => {
const GlobaldummyData = useSelector(GlobalPritdummyData);
let BillName = printDatas?.PrintHdrName
// Function to convert number to words
const numberToWords = (num) => {
const a = [
"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
"Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen",
"Eighteen", "Nineteen"
];
const b = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
if (num === 0) return "Zero";
if (num < 20) return a[num];
if (num < 100) return b[Math.floor(num / 10)] + (num % 10 ? " " + a[num % 10] : "");
if (num < 1000)
return a[Math.floor(num / 100)] + " Hundred" + (num % 100 ? " and " + numberToWords(num % 100) : "");
if (num < 100000)
return numberToWords(Math.floor(num / 1000)) + " Thousand" + (num % 1000 ? " " + numberToWords(num % 1000) : "");
if (num < 10000000)
return numberToWords(Math.floor(num / 100000)) + " Lakh" + (num % 100000 ? " " + numberToWords(num % 100000) : "");
if (num < 1000000000)
return numberToWords(Math.floor(num / 10000000)) + " Crore" + (num % 10000000 ? " " + numberToWords(num % 10000000) : "");
return "Number too large";
};
const invoiceData = {
// Company Details - mapped from A4Standard
companyName: table2Data?.CompName || table2Data?.BranchName || "",
companyspecname: table2Data?.AppSpecificName || "",
companyAddress: {
address1: table2Data?.AddressDetails?.[0]?.Address1 || "",
address2: table2Data?.AddressDetails?.[0]?.Address2 || "",
city: table2Data?.AddressDetails?.[0]?.City || "",
state: table2Data?.AddressDetails?.[0]?.State || "",
zip: table2Data?.AddressDetails?.[0]?.Zip || ""
},
companyGSTIN: table2Data?.CompGSTIN || table2Data?.GSTIN || "",
companyEmail: table2Data?.CompanyEmail || table2Data?.BrEmail || "",
companyMobile: table2Data?.BrMobile || "",
companyMobile2: table2Data?.BrMobile2 || "",
// Invoice Details - mapped from A4Standard
invoiceNo: table2Data?.QuotationNo ?
extractLastNumberOrderId(
table2Data?.QuotationNo,
) : "",
invoiceDate: moment(Date1).format('DD-MM-YYYY') || "",
// Customer Details - mapped from A4Standard CustomerDetails array
customerName: table2Data?.CustomerDetails?.[0]?.CustSuppName || table2Data?.CustName
|| "",
customerMobile: table2Data?.CustomerDetails?.[0]?.MobileNo || table2Data?.CustMobile || "",
customerGSTIN: table2Data?.CustomerDetails?.[0]?.CustGSTNo || table2Data?.CustGSTIN || "",
customerAddress: {
address1: table2Data?.CustomerDetails?.[0]?.Address1 || "",
address2: table2Data?.CustomerDetails?.[0]?.Address2 || "",
state: table2Data?.CustomerDetails?.[0]?.State || ""
},
// Product Details - mapped from A4Standard productDetails
productDetails: table2Data?.ProductDetails || [],
// Totals - mapped from A4Standard
totalAmount: Number(table2Data?.BillAmount || table2Data?.TotalAmt),
taxAmount: Number(OrderDetailGST),
grandTotal: Number(table2Data?.NetAmount || table2Data?.GrandTotal),
totalBillAmount: Number(table2Data?.BillAmount || table2Data?.NetAmount || 0),
// Bank Details - mapped from A4Standard
bankDetails: BankDetails?.[0] || null
};
console.log(table2Data, "Date1Date1", invoiceData, )
let PageSize = printDatas?.PageSize
const TakeawayData = table2Data?.ProductDetails
const DineInData = table2Data?.ProductDetails
const cgstTotal = OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.CGST || 0), 0))?.toFixed(2)
: 0;
const sgstTotal = OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.SGST || 0), 0))?.toFixed(2)
: 0;
const igstTotal = OrderDetailIGST && OrderDetailIGST.length > 0
? Number(OrderDetailIGST.reduce((sum, item) => sum + (item.IGST || 0), 0))?.toFixed(2)
: 0;
// Calculate round off value
const roundOffValue = Number(invoiceData.grandTotal) - (
Number(invoiceData.totalBillAmount) +
Number(cgstTotal) +
Number(sgstTotal) +
Number(igstTotal)
);
console.log(Number(invoiceData.totalBillAmount), cgstTotal, sgstTotal, igstTotal, "roundoff vaules")
function RoundOffFun(amount) {
const roundedAmount = Math.round(amount);
const roundOffValue = parseFloat((roundedAmount - amount).toFixed(2));
// const symbol = roundOffValue > 0 ? '+' : ''; // Add "+" symbol for positive values ${symbol}
console.log("Rounded Amount:", roundedAmount, "Round Off Value:", roundOffValue);
return `${roundOffValue.toFixed(2)}`;
}
// Allow up to 10 items per page
const chunkSize = isMobile ? 7 : PageSize == "A5" ? 9 : 8;
let dataSource = [];
// Simplified data source logic - always use all product details
dataSource = table2Data?.ProductDetails || [];
// Ensure dataSource is always an array
if (!Array.isArray(dataSource)) {
dataSource = [];
}
console.log("Final DataSource:", table2Data, );
const paginatedChunks = [];
// Always create at least one chunk, even if empty
if (dataSource.length === 0) {
paginatedChunks.push([]);
} else {
// Split data into chunks
for (let i = 0; i < dataSource.length; i += chunkSize) {
const chunk = dataSource.slice(i, i + chunkSize);
paginatedChunks.push(chunk);
}
}
const lastChunkRows = paginatedChunks.length > 0 ? paginatedChunks[paginatedChunks.length - 1].length : 0;
// If last page has more than 6 items, move footer to new page
const shouldFooterBeOnNewPage = lastChunkRows === chunkSize;
// If footer should be on new page, add an empty chunk for footer-only page
if (shouldFooterBeOnNewPage && paginatedChunks.length > 0) {
paginatedChunks.push([]); // Empty chunk for footer-only page
}
return (
{paginatedChunks.map((dataChunk, chunkIndex) => (
0 ? ' print-page-break' : ''}`}
style={{
display: "flex",
flexDirection: "column",
// justifyContent: ((chunkIndex === paginatedChunks.length - 1) && (!shouldFooterBeOnNewPage)) ? "space-between" : "",
height: isMobile ? "275mm" : PageSize == "A5" ? '130mm' : "245mm",
marginBottom: "0",
pageBreakAfter: chunkIndex < paginatedChunks.length - 1 ? 'always' : 'auto'
}}
>
{renderInvoiceContent(dataChunk, chunkIndex)}
))}
);
function renderInvoiceContent(dataChunk, chunkIndex) {
console.log(`Rendering page ${chunkIndex + 1}, chunk has ${dataChunk.length} items:`, dataChunk);
const isFirstPage = chunkIndex === 0;
const isLastPage = chunkIndex === paginatedChunks.length - 1;
const isFooterOnlyPage = isLastPage && dataChunk.length === 0 && shouldFooterBeOnNewPage;
console.log(`Page ${chunkIndex + 1}: isFirstPage=${isFirstPage}, isLastPage=${isLastPage}, isFooterOnlyPage=${isFooterOnlyPage}`);
return (
<>
{/* Header - Only on first page */}
{isFirstPage && (
<>
{table2Data?.OrderType === "E" ? "Estimate" : (BillName ? BillName : "Tax Invoice")}
>
)}
{/* Main Container - Always show */}
{/* Top Section - Company and Invoice Details - Only on first page */}
{isFirstPage && (
{/* Left - Company Details */}
{invoiceData.companyName}
{invoiceData.companyspecname}
{invoiceData.companyAddress.address1}
{invoiceData.companyAddress.address2}
{invoiceData.companyAddress.city} {invoiceData.companyAddress.zip ? ` - ${invoiceData.companyAddress.zip}` : ""}
{invoiceData.companyAddress.state}
GSTIN/UIN: {invoiceData.companyGSTIN}
{/*
State Name: Tamil Nadu, Code: 33
*/}
{invoiceData.companyEmail &&
E-Mail: {invoiceData.companyEmail}
}
{invoiceData.companyMobile &&
Mobile: +91 {invoiceData.companyMobile}{invoiceData.companyMobile2 ? `, ${invoiceData.companyMobile2}` : ""}
}
{/* Buyer Details */}
Buyer (Bill to)
{invoiceData.customerName}
{invoiceData.customerAddress.address1 &&
{invoiceData.customerAddress.address1}
}
{invoiceData.customerAddress.address2 &&
{invoiceData.customerAddress.address2}
}
{invoiceData.customerMobile &&
Mobile: {invoiceData.customerMobile}
}
{invoiceData.customerGSTIN &&
GSTIN/UIN: {invoiceData.customerGSTIN}
}
{invoiceData.customerAddress.state &&
State Name: {invoiceData.customerAddress.state}
}
{/* Right - Invoice Details */}
{/* Invoice No and Date */}
Invoice No.
{invoiceData.invoiceNo}
Dated
{invoiceData.invoiceDate}
{/* Delivery Note and Payment Terms */}
{/* Reference and Other References */}
{/* Buyer's Order */}
{/* Dispatch Details */}
{/* Dispatched through and Destination */}
{/* Terms of Delivery */}
)}
{/* Continuation header for non-first pages */}
{!isFirstPage && (
{isFooterOnlyPage ? 'Tax Invoice' : 'Tax Invoice '}
Invoice No: {invoiceData.invoiceNo}
)}
{/* Items Table - Show only if there are items or not a footer-only page */}
{(dataChunk.length > 0 || !isFooterOnlyPage) && (
{/* Table Header */}
SL.No
Description of Goods
HSN/SAC
Quantity
Rate
per
Amount
{/* Table Rows - Dynamic data from dataChunk */}
{(dataChunk && dataChunk.length > 0) ? (
<>
{dataChunk?.map((item, index) => (
{chunkIndex * chunkSize + index + 1}
{item.ProdName || 'Product Name'}
{item.BrandName &&
{item.BrandName}
}
{item.HSN || ''}
{item.Qty || 0} {item.UomName || 'NOS'}
{Number(item.Price || 0)?.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{item.UomName || 'NOS'}
{Number(item.WithoutTaxRate || 0)?.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
))}
{/* Tax summary */}
{isLastPage &&
(
<>
{/* Total without tax amount */}
₹ {Number(invoiceData?.totalBillAmount).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{/* CGST */}
{OrderDetailGST[0]?.TaxTypeName === "WithTax" &&
CGST
{
{ OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.CGST || 0), 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: "0.00"}
}
}
{/* SGST */}
{ OrderDetailGST[0]?.TaxTypeName === "WithTax" &&
SGST
{OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.SGST || 0), 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: "0.00"}
}
{/* IGST */}
{ OrderDetailGST[0]?.TaxTypeName === "WithTax" && (
IGST
{OrderDetailIGST && OrderDetailIGST.length > 0
? Number(OrderDetailIGST.reduce((sum, item) => sum + (item.IGST || 0), 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: "0.00"}
)}
{/* Rounding Off */}
ROUNDING OFF
{RoundOffFun(roundOffValue)}
{Array.from({ length: chunkSize - dataChunk.length })?.map((_, idx) => (
))}
{/* Total */}
Total
{totalQuantity ||
(invoiceData.productDetails?.reduce((sum, item) => sum + (item.SalesQty || 0), 0)) ||
0} NOS
₹ {Number(invoiceData.grandTotal).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
>
)}
>
) : (
// Show empty row when no data
-
No items to display
-
-
-
-
-
)}
)}
{/* Tax summary - Only on last page */}
{/* Footer content - Only on last page */}
{isLastPage && (
<>
{/* Amount in Words */}
Amount Chargeable (in words)
INR {numberToWords(Math.floor(invoiceData.grandTotal))} Only
E. & O.E
{/* Tax Breakdown Table */}
{OrderDetailGST[0]?.TaxTypeName === "WithTax" &&
{/* Tax Table Header - Main Headers */}
HSN/SAC
Taxable Value
CGST
SGST/UTGST
Tax Amount
{/* Tax Table Sub-Headers */}
{/* Tax Table Rows - Dynamic from OrderDetailGST */}
{OrderDetailGST && OrderDetailGST.length > 0 ? (
OrderDetailGST?.map((taxItem, index) => (
{taxItem.HSN || ''}
{Number(taxItem.WithoutTaxRate || 0).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taxItem.TaxPercentage ? (taxItem.TaxPercentage / 2) + '%' : '0%'}
{Number(taxItem.CGST || 0).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taxItem.TaxPercentage ? (taxItem.TaxPercentage / 2) + '%' : '0%'}
{Number(taxItem.SGST || 0).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{Number((taxItem.CGST || 0) + (taxItem.SGST || 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
))
) : (
// Show 0 values when no GST data
-
0.00
0%
0.00
0%
0.00
0.00
)}
{/* Tax Table Total */}
Total
{OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.WithoutTaxRate || 0), 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: "0.00"
}
{OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.CGST || 0), 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: "0.00"
}
{OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.SGST || 0), 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: "0.00"
}
{OrderDetailGST && OrderDetailGST.length > 0
? Number(OrderDetailGST.reduce((sum, item) => sum + (item.CGST || 0) + (item.SGST || 0) + (item.WithoutTaxRate || 0), 0)).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: "0.00"
}
}
{/* Tax Amount in Words */}
{OrderDetailGST[0]?.TaxTypeName === "WithTax" &&
Tax Amount (in words): INR {numberToWords(Math.floor(invoiceData.taxAmount || (OrderDetailGST?.reduce((sum, item) => sum + (item.CGST || 0) + (item.SGST || 0), 0) || 0)))} Only
}
{/* Bank Details and Signature */}
{/* Declaration */}
Declaration
We declare that this invoice shows the actual price of the goods described and that all particulars are true and correct.
{/* Signature Section */}
{/* Bank Details */}
Company's Bank Details
A/c Holder's Name: {invoiceData.companyName}
Bank Name: {invoiceData.bankDetails?.BankName || ""}
A/c No.: {invoiceData.bankDetails?.AccountNo || ""}
Branch & IFS Code: {invoiceData.bankDetails?.BankBranch || ""} & {invoiceData.bankDetails?.IFSCCode || ""}
{invoiceData.bankDetails?.SWIFTCode &&
SWIFT Code: {invoiceData.bankDetails?.SWIFTCode || ""}
}
for {invoiceData.companyName}
{/*
DD
TECHNOLOGIES
ELECTRONICS
*/}
Authorised Signatory
>
)}
{/* Footer - Only on last page */}
{isLastPage && (
This is a Computer Generated Invoice
)}
>
);
}
};
export default PurPrintstyleInvoice;