From ede0fce22379acb5229885968e6aa0b929f7800c Mon Sep 17 00:00:00 2001 From: Srinath Date: Mon, 16 Feb 2026 14:30:47 +0530 Subject: [PATCH 1/5] Added ReprintPDFDataShare componnt --- .../OtherConponents/Reprint/BSReprint.jsx | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/Pages/BookingScreen/Components/OtherConponents/Reprint/BSReprint.jsx b/src/Pages/BookingScreen/Components/OtherConponents/Reprint/BSReprint.jsx index 9526717..65d399f 100644 --- a/src/Pages/BookingScreen/Components/OtherConponents/Reprint/BSReprint.jsx +++ b/src/Pages/BookingScreen/Components/OtherConponents/Reprint/BSReprint.jsx @@ -88,6 +88,8 @@ import { changeOrderOfferDetail } from '../../../../../Features/Offer/Offer.js'; import { ChangeFullFreeProductList, changeFullOfferAppliedProducts, changeLoyaltyConsumedQuantities } from '../../../../../Features/Offer/Offernew/BookingOffernew.js'; import { ChangeTotalAmount } from '../../../../../Features/ExteraCharges/ExtraCharges.js'; import { Radio } from 'antd'; +import ReprintPDFDataShare from './ReprintPDFDataShare.jsx'; +import { ImShare } from 'react-icons/im'; const RetailApiurl = import.meta.env.ENV_API_URL; @@ -116,7 +118,6 @@ function BSReprint({ setOpenModel = () => { } }) { const [bulkMode, setBulkMode] = useState(false); const [loading, setLoading] = useState(false); const [reprintData, setReprintData] = useState([]); - console.log(reprintData, 'reprintData'); const [reprintReasonList, setReprintReasonList] = useState([]); const [isDuplicate, setIsDuplicate] = useState('Original'); const [BillSearch, setBillSearch] = useState(''); @@ -138,7 +139,7 @@ function BSReprint({ setOpenModel = () => { } }) { SettingDataSelector?.[0]?.['SettingDtlDetails']?.find( (item) => item.SettingIdName === 'Estimation' )?.SettingValue === 'Y'; - console.log(preferenceEstimate, 'preferenceEstimate'); + console.log(preferenceEstimate, 'preferenceEstimate'); const editBill = SettingDataSelector?.[0]?.SettingDtlDetails?.find( (setting) => setting?.SettingIdName?.toLowerCase() === 'editbill' && @@ -167,9 +168,10 @@ function BSReprint({ setOpenModel = () => { } }) { const SessionMobileNo = getSession('MobileNo'); const [dateStrings, setDateStrings] = useState([]); const [type, setType] = useState("Sales"); + const [showShareModal, setShowShareModal] = useState(false); // ---- 1. Fetch Function ---- const fetchData = async ({ queryKey }) => { - const [_, dates, page,type] = queryKey; + const [_, dates, page, type] = queryKey; const Response = await dispatch( ReprintDetails({ CompId, @@ -178,7 +180,7 @@ function BSReprint({ setOpenModel = () => { } }) { OrderFromDate: dates?.[0] ?? '', OrderToDate: dates?.[1] ?? '', PageNumber: page, - Type:type + Type: type }) ).unwrap(); if (Response?.data?.statusCode === 1) { @@ -189,7 +191,7 @@ function BSReprint({ setOpenModel = () => { } }) { }; const { data, isLoading, error } = useQuery({ - queryKey: ['reprint', dateStrings, page,type], + queryKey: ['reprint', dateStrings, page, type], queryFn: fetchData, enabled: true, staleTime: 1000 * 60 * 5, @@ -250,7 +252,7 @@ function BSReprint({ setOpenModel = () => { } }) { }; commonMasterApiCall(); }, []); - useEffect(() => { + useEffect(() => { DefaultReprintReason(); }, []); useEffect(() => { @@ -263,7 +265,7 @@ function BSReprint({ setOpenModel = () => { } }) { dispatch(getPrinterMappingDetails(data)).unwrap(); const Data1 = { AppId, CompId, BranchId }; dispatch(getPrintSelectionComponentData(Data1)).unwrap(); - + }, []); const handleDateChange = (dates, dateStrings) => { @@ -1193,7 +1195,6 @@ function BSReprint({ setOpenModel = () => { } }) { const mutiplePrint = async (printType) => { setIsProcessing(true); setProcessingProgress(0); - const result = await MobileMultiPdfPrint({ printerTemplateStyle, printDatas, @@ -1280,7 +1281,7 @@ function BSReprint({ setOpenModel = () => { } }) { OverallDisc, OrderPaymentDtl, } = orderDtls; - + const updated = productDetails?.map((item) => ({ ...item, Offer: item?.OfferAmt, @@ -1406,7 +1407,7 @@ function BSReprint({ setOpenModel = () => { } }) { } } - const typeOptions = [ + const typeOptions = [ { label: "Sales", value: "Sales" }, { label: "Estimate", value: "Est" }, ]; @@ -1490,7 +1491,9 @@ function BSReprint({ setOpenModel = () => { } }) { Reprintformdata(); }} /> - +
+ setShowShareModal(true)} style={{ cursor: 'pointer' }} /> +
{selectedRows.length > 0 && (
@@ -1503,6 +1506,9 @@ function BSReprint({ setOpenModel = () => { } }) { onClick={() => mutiplePrint('whatsapp')} className="icon-whatsapp" /> + {/* */}
)}
@@ -1848,6 +1854,14 @@ function BSReprint({ setOpenModel = () => { } }) { /> ))} + + { showShareModal && setShowShareModal(false)} + />} ); } From 578f27337a4a0565d120d1600a89b5a104b0beef Mon Sep 17 00:00:00 2001 From: Srinath Date: Mon, 16 Feb 2026 14:32:51 +0530 Subject: [PATCH 2/5] create new componnt ReprintPDFDataShare --- .../Reprint/ReprintPDFDataShare.jsx | 281 ++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx diff --git a/src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx b/src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx new file mode 100644 index 0000000..d36f282 --- /dev/null +++ b/src/Pages/BookingScreen/Components/OtherConponents/Reprint/ReprintPDFDataShare.jsx @@ -0,0 +1,281 @@ +import { FaDownload, FaWhatsapp } from "react-icons/fa"; +import { extractLastNumberOrderId, getSession } from "../../../../../Services/Others"; +import { useDispatch } from "react-redux"; +import { useCallback, useState } from "react"; +import { DatePicker, Modal } from "antd"; +import { ReprintDetails } from "../../../../../Features/BookingScreen/Customer/addCustomer"; +import Buttons from "../../../../../Components/Forms/Buttons"; +import { MobileMultiPdfPrint, PdfProcessingProgress } from "../../BookingFunctionality/MobileMultiPdfPrint"; +import PaymentPdfBooking from "../../../../paymentpdfPage/PaymentPdfBooking"; +import { MdEmail } from "react-icons/md"; +import { uploadImage } from "../../../../../Features/upload/upload"; +import { SelfBookingEmailSendLink } from "../../../../../Features/ConfigMasterPage/ConfigMasterPage"; +import { Messages } from "../../../../../Components/Notifications/Messages"; +const { RangePicker } = DatePicker; +const uploadApiUrl = import.meta.env.ENV_IMAGE_UPLOAD_API_URL; + +const ReprintPDFDataShare = ({ printDatas, printerTemplateStyle, SettingDataSelector, open = false, onClose = () => { } }) => { + const dispatch = useDispatch(); + const CompId = getSession('CompId'); + const BranchId = getSession('BranchId'); + const AppId = getSession('AppId'); + const UserId = getSession('UserId'); + + const [dateStrings, setDateStrings] = useState([]); + const [type, setType] = useState("Sales"); + const [reprintData, setReprintData] = useState(); + const [isProcessing, setIsProcessing] = useState(false); + const [processingProgress, setProcessingProgress] = useState(0); + const [isDuplicate, setIsDuplicate] = useState('Original'); + const [emailId, setEmailId] = useState(''); + const [isEmail, setIsEmail] = useState(false); + const [pdfUrl, setPdfUrl] = useState(false); + const [messageType, setMessageType] = useState(null); + const [messageData, setMessageData] = useState(null); + const [isFetching, setIsFetching] = useState(false); + + const handleDateChange = (dateStrings) => { + if (dateStrings[0] && dateStrings[1]) { + setDateStrings(dateStrings); + fetchData(dateStrings); + } + }; + + const fetchData = async (dates = dateStrings) => { + setIsFetching(true); + try { + const Response = await dispatch(ReprintDetails({ + CompId, + BranchId, + AppId, + OrderFromDate: dates?.[0] ?? '', + OrderToDate: dates?.[1] ?? '', + Type: type + })).unwrap(); + if (Response?.data?.statusCode === 1) { + setReprintData(Response?.data?.data); + } else { + setReprintData(null); + } + } finally { + setIsFetching(false); + } + }; + + const pdfPast = async () => { + if (printerTemplateStyle !== "TaxInvoice") { + setMessageType("error"); + setMessageData("Please select invoice print style"); + return; + } + + if (!reprintData || reprintData.length === 0) { + return; + } + try { + setIsProcessing(true); + setProcessingProgress(0); + const result = await MobileMultiPdfPrint({ + printerTemplateStyle, + printDatas, + PrintOrderDetails: reprintData, + setPrintOrderDetails: setReprintData, + PrintComing: 'download', + UserId: UserId, + dispatch, + onProgress: (progress) => setProcessingProgress(progress), + returnBlob: true + }); + + if (result?.pdfBlob) { + const file = new File([result.pdfBlob], 'invoices.pdf', { type: 'application/pdf' }); + const uploadImgData = await dispatch(uploadImage(file)).unwrap(); + if (uploadImgData?.data?.status) { + const imageUrl = uploadImgData?.data?.image; + const urlObj = new URL(imageUrl); + const fileName = urlObj.searchParams.get("fileId"); + const downloadUrl = `${uploadApiUrl}/upload/DownloadFile?fileId=${fileName}`; + setPdfUrl(downloadUrl); + } else { + setMessageType("error"); + setMessageData("Failed to upload PDF"); + } + } + } catch (error) { + setMessageType("error"); + setMessageData("Error processing PDF"); + } finally { + setIsProcessing(false); + } + }; + const handleDownload = () => { + if (pdfUrl) { + window.open(pdfUrl, '_blank'); + } + }; + const SendToEmailLink = async () => { + if (!emailId) { + setMessageType("error"); + setMessageData("Please enter a recipient email."); + return; + } + const data = { + toEmail: emailId, + type: 'M', + HeaderType:'invoice attached', + fileUrl: pdfUrl, + }; + + try { + const res = await dispatch(SelfBookingEmailSendLink(data)).unwrap(); + setMessageType("success"); + setMessageData(res.data?.response); + clearAndClose(); + } catch (err) { + console.error("Error sending Email:", err); + setMessageType("error"); + setMessageData("Failed to send email. Please try again."); + } + }; + + const handleWhatsAppClick = () => { + window.open(whatsappShareUrl, '_blank'); + clearAndClose(); + }; + + const clearAndClose = () => { + setDateStrings([]); + setReprintData(null); + setPdfUrl(false); + setEmailId(''); + setIsEmail(false); + onClose(); + setDateStrings([]); + }; + const message = ` +Please find your complete bill invoice attached in the link below: +${pdfUrl} + +Kindly review the details and keep this invoice for your records. + +Thank you for choosing us!`; + + const whatsappShareUrl = `https://wa.me/?text=${encodeURIComponent(message)}`; + + const onComplete = useCallback(() => { + setMessageData(null); + setMessageType(null); + }, []); + return ( +
+ + + <> +
+
+ +
+
+ +
+
+ + + {isEmail &&
+ setEmailId(e.target.value)} + style={{ flex: 1, padding: '8px', borderRadius: '4px', border: '1px solid #d9d9d9' }} + /> + SendToEmailLink()} + /> + +
} + {pdfUrl && ( +
+
+ + setIsEmail(prev => !prev)} className="icon-email" style={{ cursor: 'pointer' }} /> + +
+
+ )} + + + + + +
+ +
+ {reprintData?.map((orderDetail, index) => ( +
+ +
+ ))} +
+
+ + + ) +} + +export default ReprintPDFDataShare; \ No newline at end of file From aade736b5c25089093f9302f8548532a38b21082 Mon Sep 17 00:00:00 2001 From: Srinath Date: Mon, 16 Feb 2026 14:33:40 +0530 Subject: [PATCH 3/5] Added HeaderType:HeaderType --- src/Features/ConfigMasterPage/ConfigMasterPage.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Features/ConfigMasterPage/ConfigMasterPage.js b/src/Features/ConfigMasterPage/ConfigMasterPage.js index f2797b2..cf6e03b 100644 --- a/src/Features/ConfigMasterPage/ConfigMasterPage.js +++ b/src/Features/ConfigMasterPage/ConfigMasterPage.js @@ -105,11 +105,12 @@ export const postBulkConfiguration = createAsyncThunk( export const SelfBookingEmailSendLink = createAsyncThunk( 'email/sendEmailLink', async (EmailData) => { - const { toEmail, type, fileUrl} = EmailData; + const { toEmail, type, fileUrl,HeaderType} = EmailData; const data = { toEmail:toEmail, Type: type, fileUrl:fileUrl, + HeaderType:HeaderType }; return await axiosEmail_SMSData.post('/SendUrlEmail', data); } From 19af70631781bcbd9aed9556afe0cb82e79b8ba0 Mon Sep 17 00:00:00 2001 From: Srinath Date: Mon, 16 Feb 2026 14:34:29 +0530 Subject: [PATCH 4/5] Added Dowload feture --- .../BookingFunctionality/MobileMultiPdfPrint.jsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Pages/BookingScreen/Components/BookingFunctionality/MobileMultiPdfPrint.jsx b/src/Pages/BookingScreen/Components/BookingFunctionality/MobileMultiPdfPrint.jsx index 61dc7ad..465b2a9 100644 --- a/src/Pages/BookingScreen/Components/BookingFunctionality/MobileMultiPdfPrint.jsx +++ b/src/Pages/BookingScreen/Components/BookingFunctionality/MobileMultiPdfPrint.jsx @@ -11,6 +11,7 @@ import { PublicQrCodepost } from '../../../../Features/ConfigMasterPage/ConfigMa import { renderToStaticMarkup } from 'react-dom/server'; 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) => { @@ -60,10 +61,10 @@ export const MobileMultiPdfPrint = async ({ dispatch, UserId = '', onProgress = () => {}, + returnBlob = false, }) => { try { const style = await PrintStyleFunction(printerTemplateStyle, 'Sales'); - const stylesMap = { 'Style 1': 'PrintStyle1', 'Style 2': 'PrintStyle2', @@ -170,6 +171,15 @@ export const MobileMultiPdfPrint = async ({ 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); From fe78134fb6bde66aafce65f6176de737498c4328 Mon Sep 17 00:00:00 2001 From: Srinath Date: Mon, 16 Feb 2026 14:35:15 +0530 Subject: [PATCH 5/5] Added Endpoint --- src/Features/BookingScreen/Customer/addCustomer.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Features/BookingScreen/Customer/addCustomer.js b/src/Features/BookingScreen/Customer/addCustomer.js index ff16a92..de7c3fd 100644 --- a/src/Features/BookingScreen/Customer/addCustomer.js +++ b/src/Features/BookingScreen/Customer/addCustomer.js @@ -79,17 +79,23 @@ export const getRePrintReason = createAsyncThunk( export const ReprintDetails = createAsyncThunk( "addCustomer/ReprintDetails", async (data) => { - const { AppId, CompId, BranchId, OrderFromDate, OrderToDate, OrderId } = data || {}; + const { AppId, CompId, BranchId, OrderFromDate, OrderToDate, OrderId,PageNumber } = data || {}; if (OrderId && !OrderFromDate && !OrderToDate) { return await axiosRetailInstanceData.get( `/reprint?CompId=${CompId}&BranchId=${BranchId}&AppId=${AppId}&OrderId=${OrderId}&pageNumber=${data.PageNumber}&Type=${data.Type}` ); } - if (OrderFromDate && OrderToDate) { + if (OrderFromDate && OrderToDate && PageNumber) { return await axiosRetailInstanceData.get( `/reprint?CompId=${CompId}&BranchId=${BranchId}&AppId=${AppId}&orderFromDate=${OrderFromDate}&orderToDate=${OrderToDate} &pageNumber=${data.PageNumber}&Type=${data.Type}` ); - } else { + } + else if(OrderFromDate && OrderToDate ) { + return await axiosRetailInstanceData.get( + `/reprint?CompId=${CompId}&BranchId=${BranchId}&AppId=${AppId}&orderFromDate=${OrderFromDate}&orderToDate=${OrderToDate}&Type=${data.Type}` + ); + } + else { return await axiosRetailInstanceData.get( `/reprint?CompId=${CompId}&BranchId=${BranchId}&AppId=${AppId}&pageNumber=${data.PageNumber}&Type=${data.Type}` );