// 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 (
{items[0]?.BrName}
Token
BillNo: {OrderId && extractLastNumberOrderId(OrderId, FYStatus)}
{Date1}
| S.No | Item | Qty | Rate | Price |
|---|---|---|---|---|
| {idx + 1} | {item.ProdName} | {item.SalesQty} | {item.Rate} | {item.TotalAmt} |