// InvoiceDetail.jsx import React, { useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import moment from 'moment'; import { dateFormatChange1, decryptToObject, encryptObject, extractLastNumber, extractLastNumberOrderId, getSession, sessionStore, } from '../../Services/Others'; import { ApplicationPreferences, getBranchDetail, getCommonAppPreference } from '../../Features/BrachLogin/BranchLogin'; import PrintStyle1 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle1'; import PrintStyle2 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle2'; import PrintStyle3 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle3'; import PrintStyle4 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle4'; import PrintStyle5 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle5'; import PrintStyle6 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle6'; import PrintStyle7 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle7'; import PrintStyle8 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle8'; import PrintStyle9 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle9'; import PrintStyle10 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle10'; import PrintStyle11 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle11'; import PrintStyle12 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle12'; import { getPrintSelectionComponentData, GloabalFieldDetails, GlobalPricingAppPricingName, GlobalprintDatas, PricingAppPricingNameData, SelectedPrintTemplate, } from '../../Features/ThemeChange/ThemeChange'; import { getPreferenceData, PaymentGatewayGetdetail, } from '../../Features/BookingScreen/BookingData/BookingData'; import axios from 'axios'; import { FiDownload, FiChevronLeft, FiChevronRight } from 'react-icons/fi'; import './PaymentPdfBooking.scss'; import TaxInvoice from '../BookingScreen/PrintTemplates/A4/TaxInvoice'; import A4Standard from '../PurchaseReturn/PrintReturn/A4purchaseReturn/A4Standard'; import { PublicQrCodeget, PublicQrCodepost } from '../../Features/ConfigMasterPage/ConfigMasterPage'; import PrintStyle13 from '../BookingScreen/PrintTemplates/ThermalPrinter/PrintStyle13'; import PrintA5Style11 from '../BookingScreen/PrintTemplates/A4/PrintStyleA5'; import InvoiceTemplate from '../BookingScreen/PrintTemplates/A4/A4Standard'; import PrintA4Style11 from '../BookingScreen/PrintTemplates/A4/PrintA4Style11'; import html2canvas from "html2canvas"; import jsPDF from "jspdf"; const apiUrlToken = import.meta.env.ENV_API_URL_TOKEN; const LinkUrlCreate = () => { const dispatch = useDispatch(); const CreatedDate = '2023-10-01T12:00:00Z'; const printRef = useRef(); const containerRef = useRef(); const [currentPage, setCurrentPage] = useState(0); const url_string = window.location.href; const url = new URL(url_string); const [PrintOrderDetails, setPrintOrderDetails] = useState([]); const [printerTemplateStyle, setPrintSettingData] = useState(''); const [Preference, setPreferenceData] = useState([]); const [base64Image, setBase64Image] = useState(null); const [conversionError, setConversionError] = useState(null); const [allData, setAllData] = useState(null); const [table2Data, setTable2Data] = useState({}); const [branchDetails, setBranchDetails] = useState({}); const [ProdId, setProdId] = useState([]); const [isDataLoading, setIsDataLoading] = useState(true); const [allDataLoaded, setAllDataLoaded] = useState(false); const codesParam = url.searchParams.get('code'); // Global selectors const FieldDetails = useSelector(GloabalFieldDetails); const pricingAppName = useSelector(GlobalPricingAppPricingName); const printTemplate = useSelector(SelectedPrintTemplate); // This should get the PrintTemplate from global state const globalPrintDatas = useSelector(GlobalprintDatas); // This should get printDatas from global state const appPreferences = useSelector(ApplicationPreferences); const commonModulePreference = appPreferences?.find( (preference) => preference?.PreferredCatName === "Common Module" )?.PreferenceCatDetails; const sportsAppPreference = commonModulePreference?.find( (preference) => preference?.PreferredSubCatName === "SportsApp" && preference?.PreferredStatus === "Y" ); useEffect(() => { initializeData(); }, []); const initializeData = async () => { try { setIsDataLoading(true); setAllDataLoaded(false); await addSession(); await getQrCode(); } catch (error) { console.error('Error initializing data:', error); setIsDataLoading(false); } }; const getQrCode = async () => { try { const getQrCodedata = await dispatch(PublicQrCodeget(codesParam)).unwrap(); const oldUrl = getQrCodedata.data.data?.[0]?.OldUrl; const decrypted = decryptToObject(oldUrl); // Normalize decrypted value into an array of OrderIds let orderIds = []; if (Array.isArray(decrypted)) { orderIds = decrypted.map((v) => String(v).trim()).filter(Boolean); } else if (typeof decrypted === 'string') { orderIds = decrypted.split(',').map((v) => v.trim()).filter(Boolean); } else if (decrypted && typeof decrypted === 'object') { const possible = decrypted.OrderId || decrypted.orderId || decrypted.code || decrypted.id; if (possible) orderIds = [String(possible).trim()]; } setProdId(orderIds); } catch (error) { console.error('Error getting QR code:', error); setIsDataLoading(false); } }; const addSession = async () => { if (!getSession('auth')) { try { let data = { username: '1000000001', password: '1234', }; const response = await axios.post( `${apiUrlToken}/jwtTokenGenerator`, data, { headers: { 'Content-Type': 'application/json', Accept: 'application/json', }, } ); const { token } = response?.data; sessionStore('auth', token); sessionStore('LoginType', 'Kiosk'); } catch (error) { console.error('Error adding session:', error); } } }; // Fetch API data when ProdId is available useEffect(() => { if (Array.isArray(ProdId) && ProdId.length > 0) { fetchApiData(ProdId); } }, [ProdId]); const fetchApiData = async (orderIds = []) => { try { const promises = orderIds.map((orderId) => dispatch(PaymentGatewayGetdetail(orderId)) .unwrap() .then((response) => response?.data?.data?.[0] || null) ); const results = await Promise.all(promises); const validResults = results.filter(Boolean); setPrintOrderDetails(validResults); if (validResults.length > 0) { await loadAllRequiredData(validResults[0]); } } catch (error) { console.error("Error fetching bill details:", error); setIsDataLoading(false); } }; const loadAllRequiredData = async (firstInvoice) => { try { const { AppId, CompId, BranchId,UserId } = firstInvoice; const pricingData = { appId: AppId, compId: CompId, branchId: BranchId, UserId : UserId }; const printData = { AppId, CompId, BranchId, UserId }; // Step 1: Call PricingAppPricingName to update global state console.log("Step 1: Calling PricingAppPricingNameData..."); const pricingRes = await dispatch(PricingAppPricingNameData(pricingData)).unwrap(); console.log(pricingRes, "PricingAppPricingName response"); const commonapppreference = await dispatch(getCommonAppPreference({ appId: AppId})).unwrap(); // Step 2: Call getPrintSelectionComponentData to update global state with print template console.log("Step 2: Calling getPrintSelectionComponentData..."); const printSettings = await dispatch(getPrintSelectionComponentData(printData)).unwrap(); console.log(printSettings,commonapppreference, "getPrintSelectionComponentData response"); // Step 3: Call getPreferenceData console.log("Step 3: Calling getPreferenceData..."); const preferences = await dispatch(getPreferenceData(printData)).unwrap(); setPreferenceData(preferences?.data); // Step 4: Fetch branch details console.log("Step 4: Fetching branch details..."); const branchIds = [...new Set([BranchId])]; // Start with current branch await Promise.all(branchIds.map(branchId => fetchBranchData(branchId))); // All data loaded successfully console.log("All data loaded successfully"); setAllDataLoaded(true); } catch (error) { console.error('Error loading required data:', error); } finally { setIsDataLoading(false); } }; // Handle additional branch details after PrintOrderDetails is set useEffect(() => { if (PrintOrderDetails?.length > 0 && allDataLoaded) { // Get any additional unique branch IDs from all invoices const allBranchIds = [...new Set(PrintOrderDetails.map(invoice => invoice.BranchId))]; const currentBranchIds = Object.keys(branchDetails); const newBranchIds = allBranchIds.filter(id => !currentBranchIds.includes(String(id))); // Fetch details for any new branches newBranchIds.forEach(branchId => { if (branchId) { fetchBranchData(branchId); } }); } }, [PrintOrderDetails, allDataLoaded]); const fetchBranchData = async (BranchId) => { try { const response = await dispatch( getBranchDetail({ BrId: BranchId }) ).unwrap(); if (response?.data?.statusCode === 1) { setBranchDetails(prev => ({ ...prev, [BranchId]: { address: response?.data?.data?.[0]?.Address1, city: response?.data?.data?.[0]?.City, zip: response?.data?.data?.[0]?.Zip, logo: response?.data?.data?.[0]?.CompLogo } })); } } catch (error) { console.error('Error fetching branch data:', error); } }; const imageUrlToBase64 = async (url) => { try { const response = await fetch(url); const blob = await response.blob(); return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(blob); }); } catch (error) { console.error('Error fetching or converting image:', error); throw error; } }; // Convert logos to base64 useEffect(() => { async function convertLogos() { const newBase64Images = {}; for (const [branchId, details] of Object.entries(branchDetails)) { if (details.logo) { try { const base64 = await imageUrlToBase64(details.logo); newBase64Images[branchId] = base64; } catch (error) { console.error(`Error converting image for branch ${branchId}:`, error); newBase64Images[branchId] = null; } } } setBase64Image(newBase64Images); } if (Object.keys(branchDetails).length > 0) { convertLogos(); } }, [branchDetails]); const CashierName = PrintOrderDetails?.[0]?.CashierName || null; // const handleDownloadPDF = () => { // html2pdf().from(printRef.current).save(); // }; // const handleDownloadPDF = () => { // const element = printRef.current; // const options = { // // margin: 0.5, // margin: 0, // filename: "document.pdf", // image: { type: "jpeg", quality: 0.98 }, // html2canvas: { scale: 2, useCORS: true }, // makes CSS + images sharper // // jsPDF: { unit: "in", format: "a4", orientation: "portrait" }, // jsPDF: { unit: "px", format: [element.offsetWidth, element.offsetHeight] }, // }; // html2pdf().set(options).from(element).save(); // }; const handleDownloadPDF = async () => { const element = printRef.current; const canvas = await html2canvas(element, { scale: 2, useCORS: true }); const imgData = canvas.toDataURL("image/jpeg", 0.98); const pdf = new jsPDF({ unit: "px", format: [canvas.width, canvas.height], }); pdf.addImage(imgData, "JPEG", 0, 0, canvas.width, canvas.height); pdf.save("document.pdf"); }; const scrollToPage = (pageIndex) => { const pages = containerRef.current?.children; if (pages && pages[pageIndex]) { pages[pageIndex].scrollIntoView({ behavior: 'smooth', block: 'start' }); setCurrentPage(pageIndex); } }; const handleNextPage = () => { if (currentPage < PrintOrderDetails.length - 1) { scrollToPage(currentPage + 1); } }; const handlePrevPage = () => { if (currentPage > 0) { scrollToPage(currentPage - 1); } }; // Get preference data let SalesModePref = Preference?.[0]?.SettingDtlDetails?.filter( (i) => i.SettingIdName === 'Sales Mode' )?.[0]; let PrintLogo = Preference?.[0]?.SettingDtlDetails?.filter( (i) => i.SettingIdName === 'PrintLogo' )?.[0]; let PrintGreeting = Preference?.[0]?.SettingDtlDetails?.filter( (i) => i.SettingIdName === 'PrintGreetings' )?.[0]; const Date1 = dateFormatChange1(CreatedDate); // Show loading state while data is being fetched if (isDataLoading || !allDataLoaded) { return (
Loading invoice Bill...
); } // Show message if no data if (!PrintOrderDetails || PrintOrderDetails.length === 0) { return (
No invoice data found.
); } // Show message if print template is not loaded if (!printTemplate) { return (
Print template not available. Please check your configuration.
); } return ( <>
{PrintOrderDetails.length > 1 && (
{currentPage + 1} / {PrintOrderDetails.length}
)}
{PrintOrderDetails?.map((table2Data, index) => { if (!table2Data) return null; const { BranchId, SalesDate, CashierName, productDetails, TaxDetails, ExtraChargeDetails, OrderOfferDetails, PaymentOrderDtl, OrderId, FYStatus } = table2Data; const branchDetail = branchDetails[BranchId] || {}; const currentBase64Image = base64Image?.[BranchId] || null; const Date1 = dateFormatChange1(SalesDate); const PaymentStatusSuccess = PaymentOrderDtl?.filter(ps => ps.PaymentStatus === 'S'); const ExtraChargeTotal = ExtraChargeDetails?.reduce( (accumulator, currentObject) => accumulator + currentObject.TotalAmt, 0 ) || 0; const productsData = productDetails || []; const offers = OrderOfferDetails || []; let TotalOfferAmount = 0; // Calculate SalesWiseOffers total amount offers.forEach((offer) => { if (offer.TableName === 'SalesWiseOffers') { TotalOfferAmount += offer.OfferAmount; } }); const hasMappedOffer = offers.some((offer) => ['ItemWiseOffers', 'BundleOffers', 'QuantityWiseOffers'].includes(offer.TableName) ); if (hasMappedOffer) { const productTotal = productsData?.reduce( (acc, item) => acc + (item?.Type != 'C' ? item.OfferAmt : item.OfferValue || 0), 0 ); TotalOfferAmount += productTotal; } else { const Combothere = productsData?.filter((item) => item?.Type == 'C'); const CombothereTotal = Combothere?.reduce( (acc, item) => acc + (item.OfferValue || 0), 0 ); TotalOfferAmount += CombothereTotal; } let totalQuantityFilter = productsData?.map( (item) => item?.SalesQty || item?.OrderQty ); const totalQuantity = totalQuantityFilter?.reduce( (accumulator, currentValue) => accumulator + currentValue, 0 ) || 0; const OrderDetailGST = TaxDetails?.filter( (item) => item.TaxIdName?.toLowerCase() === 'cgst,sgst' ); const OrderDetailIGST = TaxDetails?.filter( (item) => item.TaxIdName?.toLowerCase() === 'igst' ); const OrderDetailVAT = TaxDetails?.filter( (item) => item.TaxIdName?.toLowerCase() === 'vat' ); const tokenGroups = (productsData || []).reduce( (acc, item, idx) => { if (item.TokenAvailable === 'Y') { if (!item.CounterName) { acc[`individual-${idx}`] = [item]; } else { if (!acc[item.CounterName]) acc[item.CounterName] = []; acc[item.CounterName].push(item); } } return acc; }, {} ); // Render print template based on global state const renderPrintTemplate = () => { const commonProps = { index, ExtraChargeTotal, Date1, base64Image: currentBase64Image, BranchAddress: branchDetail.address, BranchCity: branchDetail.city, BranchZip: branchDetail.zip, SalesModePref, CashierName, totalQuantity, OrderDetailGST, OrderDetailIGST, OrderDetailVAT, table2Data, totalQuantityFilter, PaymentStatus: PaymentOrderDtl, PrintLogo, PrintGreeting, printDatas: globalPrintDatas, sportsAppPreference:sportsAppPreference }; console.log(printTemplate,"printTemplate") switch (printTemplate) { case 'Style 1': return ; case 'Style 2': return ; case 'Style 3': return ; case 'Style 4': return ; case 'Style 5': return ; case 'Style 6': return ; case 'Style 7': return ; case 'Style 8': return ; case 'Style 9': return ; case 'Style 10': return ; case 'Style 11': return ; case 'Style 12': // return ; // case 'Style 13': return ; case 'A4': return ; case 'A5': return ; case 'A4Standard': return ; case 'TaxInvoice': return ; default: return ; } }; return (
{renderPrintTemplate()} {/* Token Print */} {/* {Object.entries(tokenGroups).map( ([counterName, items], tokenIdx) => (

{items[0]?.BrName}

Token

BillNo:  {OrderId && extractLastNumberOrderId(OrderId, FYStatus)}

{Date1}

{items?.map((item, idx) => ( ))}
S.No Item Qty Rate Price
{idx + 1} {item.ProdName} {item.SalesQty} {item.Rate} {item.TotalAmt}
) )} */}
); })}
); }; export default LinkUrlCreate;