Android_Retail/src/Pages/BookingScreen/Components/BookingFunctionality/MobileMultiPdfPrint.jsx

964 lines
29 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useRef } from 'react';
import { Emailsend } from '../../../../Features/PurchaseOrder/PurchaseOrder';
import {
blobToBase64,
encryptObject,
pdfDiv,
} from '../../../../Services/Others';
import { PrintStyleFunction } from '../../../paymentpdfPage/PrintStyleFunction';
import { PDFDocument } from 'pdf-lib';
import { PublicQrCodepost } from '../../../../Features/ConfigMasterPage/ConfigMasterPage';
import { renderToStaticMarkup } from 'react-dom/server';
import { downloadFile } from '../../../../utils/downloadFile';
const MainHomeUrl = import.meta.env.ENV_MAIN_BASE_URL;
const uploadApiUrl = import.meta.env.ENV_IMAGE_UPLOAD_API_URL;
// Create a secure blob URL creator that works in all environments
const createSecureBlobUrl = (blob) => {
try {
return URL.createObjectURL(blob);
} catch (error) {
console.warn(
'Standard blob URL creation failed, using alternative approach'
);
return window.URL.createObjectURL(blob);
}
};
// Revoke blob URL safely
const revokeSecureBlobUrl = (url) => {
if (url && url.startsWith('blob:')) {
try {
URL.revokeObjectURL(url);
} catch (error) {
console.warn('Failed to revoke blob URL:', error);
}
}
};
// Merge multiple pdf blobs into one
const mergePdfBlobs = async (blobs) => {
const mergedPdf = await PDFDocument.create();
for (const blob of blobs) {
const pdfBytes = await blob.arrayBuffer();
const pdf = await PDFDocument.load(pdfBytes);
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
copiedPages.forEach((page) => mergedPdf.addPage(page));
}
const mergedBytes = await mergedPdf.save();
return new Blob([mergedBytes], { type: 'application/pdf' });
};
export const MobileMultiPdfPrint = async ({
printerTemplateStyle = 'Style 13',
printDatas = {},
PrintOrderDetails = [],
setPrintOrderDetails = () => { },
PrintComing = '',
emailId = '',
dispatch,
UserId = '',
onProgress = () => { },
returnBlob = false,
}) => {
try {
const style = await PrintStyleFunction(printerTemplateStyle, 'Sales');
const stylesMap = {
'Style 1': 'PrintStyle1',
'Style 2': 'PrintStyle2',
'Style 3': 'PrintStyle3',
'Style 4': 'PrintStyle4',
'Style 5': 'PrintStyle5',
'Style 6': 'PrintStyle6',
'Style 7': 'PrintStyle7',
'Style 8': 'PrintStyle8',
'Style 9': 'PrintStyle9',
'Style 10': 'PrintStyle10',
'Style 11': 'PrintStyle11',
'Style 12': 'PrintStyle12',
'Style 13': 'RePrint',
A4: 'PrintStyleA4',
A5: 'PrintStyleA5',
A4Standard: 'A4Standard',
TaxInvoice: 'TaxInvoice',
};
const selectedStyle = stylesMap[printerTemplateStyle] || 'RePrint';
const Printsize = printDatas?.PageSize || 'A4';
const totalOrders = PrintOrderDetails.length;
let allBlobs = [];
// 🔥 LOOP EACH INVOICE (MAIN FIX)
for (let i = 0; i < totalOrders; i++) {
const element = document.getElementById(
`${selectedStyle}-${i}`
);
if (!element) {
console.warn('⚠️ Element not found:', `${selectedStyle}-${i}`);
continue;
}
// 🔥 TEMP WRAPPER (IMPORTANT)
const wrapper = document.createElement('div');
wrapper.id = `temp-${i}`;
wrapper.style.width = '794px';
wrapper.style.background = '#fff';
wrapper.innerHTML = `
${style}
${element.innerHTML}
`;
document.body.appendChild(wrapper);
try {
// 👉 ONE invoice → ONE PDF
const blob = await pdfDiv(wrapper.id);
allBlobs.push(blob);
} catch (err) {
console.error('PDF error:', err);
}
document.body.removeChild(wrapper);
// 🔥 Progress update
const progress = Math.round(((i + 1) / totalOrders) * 100);
onProgress(progress);
// 🔥 small delay for stability (important for large data)
await new Promise((r) => setTimeout(r, 5));
}
// // 🔥 MERGE ALL PDFs
// const combinedPdfBlob = await mergePdfBlobs(allBlobs);
// const base64Pdf = await blobToBase64(combinedPdfBlob);
// // 🔥 DOWNLOAD
// if (PrintComing === 'download') {
// const blobUrl = createSecureBlobUrl(combinedPdfBlob);
// const link = document.createElement('a');
// link.href = blobUrl;
// link.download = 'Receipts.pdf';
// document.body.appendChild(link);
// link.click();
// setTimeout(() => {
// document.body.removeChild(link);
// revokeSecureBlobUrl(blobUrl);
// }, 100);
// }
const combinedPdfBlob = await mergePdfBlobs(allBlobs);
const base64Pdf = await blobToBase64(combinedPdfBlob);
// 🔥 DOWNLOAD
if (PrintComing === 'download') {
// ✅ Convert Blob → ArrayBuffer for downloadFile
const buffer = await combinedPdfBlob.arrayBuffer();
downloadFile(
buffer,
"Receipts.pdf",
"application/pdf",
(success) => {
if (!success) {
console.error('Failed to download the file. Please try again.');
}
}
);
}
// 🔥 RETURN BLOB
if (returnBlob && PrintComing === 'download') {
setPrintOrderDetails([]);
return { success: true, pdfBlob: combinedPdfBlob };
}
// 🔥 WHATSAPP
if (PrintComing === 'whatsapp') {
const orderIdsArray = PrintOrderDetails.map((row) => row?.OrderId).filter(Boolean);
if (orderIdsArray.length === 0) return;
const encrypted = encryptObject(orderIdsArray);
const postData = {
Url: encrypted,
CreatedBy: UserId,
};
try {
const res = await dispatch(PublicQrCodepost(postData)).unwrap();
const urlData = res?.data?.ReferenceNo || res?.ReferenceNo;
if (!urlData) return;
const documentUrl = `${MainHomeUrl}viewbill?code=${urlData}`;
const waUrl =
'https://web.whatsapp.com/send?text=' +
encodeURIComponent('Here are your receipts 👉 ' + documentUrl);
window.open(waUrl, '_blank');
} catch (err) {
console.error('❌ WhatsApp error:', err);
}
}
// 🔥 EMAIL
if (PrintComing === 'email') {
try {
const payload = {
fileBlob: combinedPdfBlob,
toEmail: emailId,
type: 'Sales',
messageTemplatesList: [],
};
const res = await dispatch(Emailsend(payload))?.unwrap();
return res;
} catch (err) {
console.error('❌ Email error:', err);
}
}
// 🔥 PRINT VIEW
if (!['download', 'whatsapp', 'email'].includes(PrintComing)) {
const blobUrl = createSecureBlobUrl(combinedPdfBlob);
const newWindow = window.open('', '_blank');
if (newWindow) {
newWindow.document.write(`
<html>
<body style="margin:0">
<button onclick="window.print()"
style="position:fixed;top:10px;right:10px;">Print</button>
<iframe src="${blobUrl}" style="width:100%;height:100%;border:none"></iframe>
</body>
</html>
`);
newWindow.document.close();
} else {
window.location.href = blobUrl;
}
const intentUrl =
'intent://open?' +
'filename=' + encodeURIComponent('Receipts.pdf') +
'&size=' + combinedPdfBlob.size +
'&type=application/pdf' +
'&data=' + encodeURIComponent(base64Pdf) +
'&PrintTypeS=' + encodeURIComponent(Printsize) +
'#Intent;scheme=pozoprinter;package=com.example.pozoprinter;end';
setTimeout(() => {
try {
window.location.href = intentUrl;
} catch { console.log("some errors") }
}, 500);
}
// 🔥 CLEANUP
setPrintOrderDetails([]);
return { success: true, message: 'PDF processed successfully' };
} catch (error) {
console.error('MobileMultiPdfPrint error:', error);
return { success: false, message: error.message };
}
};
// export const MobileMultiPdfPrint = async ({
// printerTemplateStyle = 'Style 13',
// printDatas = {},
// PrintOrderDetails = [],
// setPrintOrderDetails = () => {},
// PrintComing = '',
// emailId = '',
// dispatch,
// UserId = '',
// onProgress = () => {},
// returnBlob = false,
// }) => {
// try {
// const style = await PrintStyleFunction(printerTemplateStyle, 'Sales');
// const stylesMap = {
// 'Style 1': 'PrintStyle1',
// 'Style 2': 'PrintStyle2',
// 'Style 3': 'PrintStyle3',
// 'Style 4': 'PrintStyle4',
// 'Style 5': 'PrintStyle5',
// 'Style 6': 'PrintStyle6',
// 'Style 7': 'PrintStyle7',
// 'Style 8': 'PrintStyle8',
// 'Style 9': 'PrintStyle9',
// 'Style 10': 'PrintStyle10',
// 'Style 11': 'PrintStyle11',
// 'Style 12': 'PrintStyle12',
// 'Style 13': 'RePrint',
// A4: 'PrintStyleA4',
// A5: 'PrintStyleA5',
// A4Standard: 'A4Standard',
// TaxInvoice: 'TaxInvoice',
// };
// const selectedStyle = stylesMap[printerTemplateStyle] || 'RePrint';
// const Printsize = printDatas?.PageSize || 'A4';
// // Create or clear the container
// let container = document.getElementById('print-merged');
// if (!container) {
// container = document.createElement('div');
// container.id = 'print-merged';
// container.style.display = 'none';
// document.body.appendChild(container);
// } else {
// container.innerHTML = '';
// }
// // Process in batches for large files
// const BATCH_SIZE = 5;
// const totalOrders = PrintOrderDetails.length;
// let processedOrders = 0;
// let allBlobs = [];
// for (let i = 0; i < totalOrders; i += BATCH_SIZE) {
// const batch = PrintOrderDetails.slice(i, i + BATCH_SIZE);
// // Clear container for each batch
// container.innerHTML = '';
// // Process each order in the current batch
// batch.forEach((_, index) => {
// const globalIndex = i + index;
// const element = document.getElementById(
// `${selectedStyle}-${globalIndex}`
// );
// if (element) {
// const cloned = element.cloneNode(true);
// // Add page break between orders (except the last one)
// if (globalIndex < totalOrders - 1) {
// const pageBreak = document.createElement('div');
// pageBreak.style.pageBreakAfter = 'always';
// container.appendChild(cloned);
// container.appendChild(pageBreak);
// } else {
// container.appendChild(cloned);
// }
// } else {
// console.warn(
// '⚠️ Element not found:',
// `${selectedStyle}-${globalIndex}`
// );
// }
// });
// // Generate PDF for this batch
// try {
// const pdfBlob = await pdfDiv('print-merged', style);
// allBlobs.push(pdfBlob);
// processedOrders += batch.length;
// const progress = Math.round((processedOrders / totalOrders) * 100);
// onProgress(progress);
// } catch (error) {
// console.error('Error generating PDF batch:', error);
// throw new Error(
// `Failed to generate PDF for batch starting at index ${i}`
// );
// }
// }
// // ✅ Merge all PDF blobs into one
// const combinedPdfBlob = await mergePdfBlobs(allBlobs);
// const base64Pdf = await blobToBase64(combinedPdfBlob);
// // Handle different print actions
// if (PrintComing === 'download') {
// const blobUrl = createSecureBlobUrl(combinedPdfBlob);
// const link = document.createElement('a');
// link.href = blobUrl;
// link.download = 'Receipts.pdf';
// document.body.appendChild(link);
// link.click();
// setTimeout(() => {
// document.body.removeChild(link);
// revokeSecureBlobUrl(blobUrl);
// }, 100);
// }
// // Return blob if requested (after download completes)
// if (returnBlob && PrintComing === 'download') {
// setPrintOrderDetails([]);
// if (container) {
// document.body.removeChild(container);
// }
// return { success: true, pdfBlob: combinedPdfBlob };
// }
// // if (PrintComing === "whatsapp") {
// // const orderIds = PrintOrderDetails.map((row) => row?.OrderId).filter(Boolean);
// // const documentUrl = `${MainHomeUrl}viewbill?code=${orderIds}`;
// // const waUrl =
// // "https://web.whatsapp.com/send?text=" +
// // encodeURIComponent("Here are your receipts 👉 " + documentUrl);
// // window.open(waUrl, "_blank");
// // }
// if (PrintComing === 'whatsapp') {
// const orderIdsArray = PrintOrderDetails.map((row) => row?.OrderId).filter(
// Boolean
// );
// if (orderIdsArray.length === 0) {
// console.warn('⚠️ No order IDs found for WhatsApp sharing.');
// return;
// }
// // 2⃣ Encrypt order IDs
// const encrypted = encryptObject(orderIdsArray);
// // 3⃣ Prepare payload for backend
// const postData = {
// Url: encrypted,
// CreatedBy: UserId, // Make sure UserId is passed correctly to your function
// };
// try {
// // 4⃣ Call backend to get a ReferenceNo
// const res = await dispatch(PublicQrCodepost(postData)).unwrap();
// console.log('Backend response:', res);
// // 5⃣ Extract ReferenceNo (adjust based on your backend response structure)
// // Example: it might be res.data.ReferenceNo or res.ReferenceNo
// const urlData = res?.data?.ReferenceNo || res?.ReferenceNo;
// if (!urlData) {
// console.error('❌ No ReferenceNo returned from backend');
// return;
// }
// // 6⃣ Build the shareable URL
// const documentUrl = `${MainHomeUrl}viewbill?code=${urlData}`;
// // 7⃣ Open WhatsApp Web with URL
// const waUrl =
// 'https://web.whatsapp.com/send?text=' +
// encodeURIComponent('Here are your receipts 👉 ' + documentUrl);
// window.open(waUrl, '_blank');
// } catch (err) {
// console.error('❌ WhatsApp sharing failed:', err);
// }
// }
// if (PrintComing === 'email') {
// try {
// const payload = {
// fileBlob: combinedPdfBlob,
// toEmail: emailId,
// type: 'Sales',
// messageTemplatesList: [],
// };
// const res = await dispatch(Emailsend(payload))?.unwrap();
// console.log('✅ Email sent response:', res?.data || res);
// return res;
// } catch (err) {
// console.error('❌ Email error:', err);
// }
// }
// if (!['download', 'whatsapp', 'email'].includes(PrintComing)) {
// const blobUrl = createSecureBlobUrl(combinedPdfBlob);
// const newWindow = window.open('', '_blank');
// if (newWindow) {
// newWindow.document.write(`
// <html>
// <head>
// <title>Receipts</title>
// <style>
// body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f0f0f0; }
// iframe { width: 100%; height: 100%; border: none; }
// .print-button { position: fixed; top: 20px; right: 20px; z-index: 1000; padding: 10px 15px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
// </style>
// </head>
// <body>
// <button class="print-button" onclick="window.print()">Print</button>
// <iframe src="${blobUrl}" type="application/pdf"></iframe>
// </body>
// </html>
// `);
// newWindow.document.close();
// } else {
// window.location.href = blobUrl;
// }
// // For mobile intent URL
// const intentUrl =
// 'intent://open?' +
// 'filename=' +
// encodeURIComponent('Receipts.pdf') +
// '&size=' +
// combinedPdfBlob.size +
// '&type=application/pdf' +
// '&data=' +
// encodeURIComponent(base64Pdf) +
// '&PrintTypeS=' +
// encodeURIComponent(Printsize) +
// '&PrintTypeE' +
// '#Intent;scheme=pozoprinter;package=com.example.pozoprinter;end';
// setTimeout(() => {
// try {
// window.location.href = intentUrl;
// } catch (e) {
// console.warn('Could not open intent URL:', e);
// }
// }, 500);
// }
// // Clean up
// setPrintOrderDetails([]);
// if (container) {
// document.body.removeChild(container);
// }
// return { success: true, message: 'PDF processed successfully' };
// } catch (error) {
// console.error('MobileMultiPdfPrint error:', error);
// return { success: false, message: error.message };
// }
// };
// Progress component to show processing status
export const PdfProcessingProgress = ({ progress, isProcessing }) => {
if (!isProcessing) return null;
return (
<div
style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0,0,0,0.7)',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
zIndex: 10999,
}}
>
<div
style={{
backgroundColor: 'white',
padding: '20px',
borderRadius: '8px',
textAlign: 'center',
minWidth: '300px',
}}
>
<h3>Processing PDFs</h3>
<div
style={{
width: '100%',
backgroundColor: '#f0f0f0',
borderRadius: '4px',
margin: '15px 0',
}}
>
<div
style={{
width: `${progress}%`,
height: '20px',
backgroundColor: '#4caf50',
borderRadius: '4px',
transition: 'width 0.3s',
}}
></div>
</div>
<p>{progress}% Complete</p>
</div>
</div>
);
};
export const MobileMultiCreditPdfPrint = async ({
PrintOrderDetails = [],
BSCreditCustomerPrint,
style,
PrintComing = '',
emailId = '',
dispatch,
UserId = '',
onProgress = () => { },
BATCH_SIZE = 5,
}) => {
if (!BSCreditCustomerPrint) {
throw new Error('BSCreditCustomerPrint component is required');
}
// Helper: wait for images & fonts in a container
const waitForImagesAndFonts = (container, timeout = 7000) =>
new Promise((resolve) => {
// images
const imgs = Array.from(container.querySelectorAll('img'));
let remaining = imgs.length;
if (remaining === 0) {
// still ensure fonts ready
if (document.fonts && document.fonts.ready) {
document.fonts.ready.then(() => resolve()).catch(() => resolve());
} else resolve();
return;
}
const timer = setTimeout(() => {
clearTimeout(timer);
resolve();
}, timeout);
imgs.forEach((img) => {
if (img.complete) {
remaining--;
if (remaining === 0) {
clearTimeout(timer);
// fonts:
if (document.fonts && document.fonts.ready) {
document.fonts.ready.then(() => resolve()).catch(() => resolve());
} else resolve();
}
} else {
img.addEventListener(
'load',
() => {
remaining--;
if (remaining === 0) {
clearTimeout(timer);
if (document.fonts && document.fonts.ready) {
document.fonts.ready
.then(() => resolve())
.catch(() => resolve());
} else resolve();
}
},
{ once: true }
);
img.addEventListener(
'error',
() => {
remaining--;
if (remaining === 0) {
clearTimeout(timer);
if (document.fonts && document.fonts.ready) {
document.fonts.ready
.then(() => resolve())
.catch(() => resolve());
} else resolve();
}
},
{ once: true }
);
}
});
});
// Fallback mergePdfBlobs using pdf-lib (client-side)
const mergePdfBlobsFallback = async (blobs) => {
if (!blobs || blobs.length === 0) {
return new Blob([], { type: 'application/pdf' });
}
if (blobs.length === 1) return blobs[0];
const mergedPdf = await PDFDocument.create();
for (const blob of blobs) {
const arrayBuffer = await blob.arrayBuffer();
const donorPdf = await PDFDocument.load(arrayBuffer);
const copiedPages = await mergedPdf.copyPages(
donorPdf,
donorPdf.getPageIndices()
);
copiedPages.forEach((p) => mergedPdf.addPage(p));
}
const mergedBytes = await mergedPdf.save();
return new Blob([mergedBytes], { type: 'application/pdf' });
};
const blobToBase64 = (blob) =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result.split(',')[1]); // base64 without prefix
reader.onerror = reject;
reader.readAsDataURL(blob);
});
// create container or ensure empty
let printRootContainer = document.getElementById('print-merged-react');
if (printRootContainer) {
printRootContainer.innerHTML = '';
} else {
printRootContainer = document.createElement('div');
printRootContainer.id = 'print-merged-react';
printRootContainer.style.display = 'none';
document.body.appendChild(printRootContainer);
}
const total = PrintOrderDetails.length;
let allBlobs = [];
let processedVisible = 0;
try {
for (let i = 0; i < total; i += BATCH_SIZE) {
const batch = PrintOrderDetails.slice(i, i + BATCH_SIZE);
// clear container for each batch
printRootContainer.innerHTML = '';
// Render each BSCreditCustomerPrint into its own div
const roots = [];
for (let idx = 0; idx < batch.length; idx++) {
const globalIndex = i + idx;
const wrapper = document.createElement('div');
wrapper.id = `Credit-customer-${globalIndex}`;
const html = renderToStaticMarkup(
<BSCreditCustomerPrint PrintDatas={batch[idx]} />
);
wrapper.innerHTML = html;
printRootContainer.appendChild(wrapper);
// add page break if needed
if (globalIndex < total - 1) {
const pb = document.createElement('div');
pb.style.pageBreakAfter = 'always';
printRootContainer.appendChild(pb);
}
roots.push(printRootContainer);
}
await new Promise((res) => setTimeout(res, 120)); // small tick
await waitForImagesAndFonts(printRootContainer, 8000);
const batchContainerId = `print-merged-batch-${i}`;
let batchContainer = document.getElementById(batchContainerId);
if (!batchContainer) {
batchContainer = document.createElement('div');
batchContainer.id = batchContainerId;
batchContainer.style.display = 'none';
document.body.appendChild(batchContainer);
}
batchContainer.innerHTML = `${style}${printRootContainer.innerHTML}`;
const pdfBlob = await pdfDiv(batchContainerId, style);
allBlobs.push(pdfBlob);
roots.forEach((r) => {
try {
r.unmount();
} catch (e) {
// ignore
}
});
// cleanup batch container
try {
if (batchContainer && batchContainer.parentElement) {
batchContainer.parentElement.removeChild(batchContainer);
}
} catch (e) {
/* ignore */
}
// progress
processedVisible += batch.length;
onProgress(Math.round((processedVisible / total) * 100));
}
// // merge blobs - use existing merge function if available, otherwise fallback
// const combinedPdfBlob =
// typeof mergePdfBlobs === 'function'
// ? await mergePdfBlobs(allBlobs)
// : await mergePdfBlobsFallback(allBlobs);
// const base64Pdf = await blobToBase64(combinedPdfBlob);
// // Action handlers
// if (PrintComing === 'download') {
// const blobUrl =
// typeof createSecureBlobUrl === 'function'
// ? createSecureBlobUrl(combinedPdfBlob)
// : URL.createObjectURL(combinedPdfBlob);
// const link = document.createElement('a');
// link.href = blobUrl;
// link.download = 'Receipts.pdf';
// document.body.appendChild(link);
// link.click();
// setTimeout(() => {
// document.body.removeChild(link);
// if (typeof revokeSecureBlobUrl === 'function')
// revokeSecureBlobUrl(blobUrl);
// else URL.revokeObjectURL(blobUrl);
// }, 300);
// return { success: true };
// }
const combinedPdfBlob =
typeof mergePdfBlobs === 'function'
? await mergePdfBlobs(allBlobs)
: await mergePdfBlobsFallback(allBlobs);
const base64Pdf = await blobToBase64(combinedPdfBlob);
// Action handlers
if (PrintComing === 'download') {
// ✅ Convert Blob → ArrayBuffer for downloadFile
const buffer = await combinedPdfBlob.arrayBuffer();
downloadFile(
buffer,
"Receipts.pdf",
"application/pdf",
(success) => {
if (!success) {
console.error('Failed to download the file. Please try again.');
}
}
);
return { success: true };
}
if (PrintComing === 'whatsapp') {
const orderIdsArray = PrintOrderDetails.map((r) => r?.receiptNo).filter(
Boolean
);
if (orderIdsArray.length === 0) {
console.warn('No order ids for whatsapp');
return { success: false, message: 'No orders' };
}
const encrypted = encryptObject(orderIdsArray);
const postData = { Url: encrypted, CreatedBy: UserId };
try {
const res = await dispatch(PublicQrCodepost(postData)).unwrap();
const urlData = res?.data?.ReferenceNo || res?.ReferenceNo;
if (!urlData) throw new Error('No ReferenceNo from backend');
const documentUrl = `${MainHomeUrl}viewbill?code=${urlData}`;
const waUrl =
'https://web.whatsapp.com/send?text=' +
encodeURIComponent('Here are your receipts 👉 ' + documentUrl);
window.open(waUrl, '_blank');
return { success: true };
} catch (err) {
console.error('WhatsApp sharing failed', err);
return { success: false, message: err?.message || String(err) };
}
}
if (PrintComing === 'email') {
try {
const payload = {
fileBlob: combinedPdfBlob,
toEmail: emailId,
type: 'CreditReceipt',
messageTemplatesList: [],
};
const res = await dispatch(Emailsend(payload)).unwrap();
return { success: true, data: res };
} catch (err) {
console.error('Email send failed', err);
return { success: false, message: err?.message || String(err) };
}
}
// default: open viewer tab and attempt mobile intent
const blobUrl =
typeof createSecureBlobUrl === 'function'
? createSecureBlobUrl(combinedPdfBlob)
: URL.createObjectURL(combinedPdfBlob);
const newWindow = window.open('', '_blank');
if (newWindow) {
newWindow.document.write(`
<html>
<head><title>Receipts</title>
<style>
body{margin:0;background:#f0f0f0;height:100vh;display:flex;align-items:center;justify-content:center}
iframe{width:100%;height:100%;border:none}
.print-button{position:fixed;top:16px;right:16px;padding:10px 14px;background:#4CAF50;color:white;border:none;border-radius:6px;cursor:pointer;z-index:9999}
</style>
</head>
<body>
<button class="print-button" onclick="window.print()">Print</button>
<iframe src="${blobUrl}" type="application/pdf"></iframe>
</body>
</html>
`);
newWindow.document.close();
} else {
window.location.href = blobUrl;
}
// mobile intent (optional)
const intentUrl =
'intent://open?' +
'filename=' +
encodeURIComponent('Receipts.pdf') +
'&size=' +
combinedPdfBlob.size +
'&type=application/pdf' +
'&data=' +
encodeURIComponent(base64Pdf) +
'#Intent;scheme=pozoprinter;package=com.example.pozoprinter;end';
try {
setTimeout(() => {
try {
window.location.href = intentUrl;
} catch (e) {
/* ignore */
}
}, 500);
} catch (e) {
/* ignore */
}
return { success: true };
} catch (err) {
console.error('MobileMultiCreditPdfPrint error:', err);
return { success: false, message: err?.message || String(err) };
} finally {
// final cleanup
try {
// remove printRootContainer and any leftover child batch containers
const root = document.getElementById('print-merged-react');
if (root && root.parentElement) root.parentElement.removeChild(root);
// remove any batch containers (ids starting with print-merged-batch-)
Array.from(
document.querySelectorAll("[id^='print-merged-batch-']")
).forEach((el) => {
try {
el.parentElement.removeChild(el);
} catch (e) { }
});
} catch (e) {
console.warn('Cleanup error', e);
}
}
};