import {LeadsMandate} from "./entities/leadsMandate.entity"; import {LeadsPi} from "./entities/leadsPi.entity"; import {LeadsTax} from "./entities/leadsTax.entity"; import { LeadsManagementHelper } from "./leads-management.helpers.service"; async getDocumentsData(document_company_id?: string) { try { const queryOptions: any = document_company_id ? { where: { document_company_id } } : {}; return await DocumentsData.findAll(queryOptions); } catch (error) { console.error("Error fetching documents:", error); throw new Error(`Failed to fetch documents: ${error.message}`); } } async fetchAsset(accessToken: string, folder: string, filePath: string): Promise { const itemId = await this.dmsService.getItemId(folder, filePath); return this.dmsService.getFileDownLink(accessToken, itemId); } getDocumentTemplatePath(document_type: string): { pugTemplatePath: string; fileType: string } { const templates: Record = { mandateDocument: { path: "./pug/mandateDocument.pug", type: "Mandate" }, piDocument: { path: "./pug/piDocument.pug", type: "PI" }, taxInvoice: { path: "./pug/taxDocument.pug", type: "TI" }, }; if (!templates[document_type]) { throw new Error(`Unsupported document type: ${document_type}`); } return { pugTemplatePath: path.join(__dirname, templates[document_type].path), fileType: templates[document_type].type, }; } async generatePDF(html: string): Promise { const browser = await puppeteer.launch({ args: ["--no-sandbox", "--disable-setuid-sandbox"] }); const page = await browser.newPage(); await page.setContent(html); const pdfBuffer = await page.pdf({ format: "A4", printBackground: true, timeout: 60000 }); await browser.close(); return pdfBuffer; } generateFilename(companyName: string, fileType: string): string { const date = new Date(); const formattedDate = new Intl.DateTimeFormat("en-GB", { day: "2-digit", month: "2-digit", year: "2-digit" }) .format(date) .replace(/\//g, "-"); const time = '05-02-2025' return `${companyName} ${time} ${fileType}`; } getParentFolderId(fileType: string): string { const parentFolders: Record = { Mandate: PARENT_ID_MANDATE, PI: PARENT_ID_PI, TI: PARENT_ID_TAX, }; return parentFolders[fileType] || ""; } async generateDocumentPDF(document_company_id: number, document_type: string): Promise { try { if (!document_company_id || isNaN(document_company_id)) { throw new Error(`Invalid document_company_id: ${document_company_id}`); } const leadData = await LeadDetails.findOne({ where: { id: document_company_id }, attributes: [ "company_name", "company_address", "company_state", "company_city", "company_pin_code", "primary_contact_person_name", "primary_contact_person_email_id", "primary_contact_person_mobile", "primary_contact_person_designation", "company_pan_no", "company_gst_in_no", "company_tan_no", "net_fees_receivable", "tds_percent", "gross_fees", "gst_of_base_fees", "lead_created_date", "fees_quotes", ], }); const companyGstInNo = leadData.company_gst_in_no; const grossFees = leadData.gross_fees; const tds = leadData.tds_percent; const netFeesReceivable = leadData.net_fees_receivable; if (!leadData) { throw new Error(`No data found for document_company_id: ${document_company_id}`); } const feesQuotes = leadData.fees_quotes || 0; const feesQuotesGst = (18 / 100) * feesQuotes; const totalFeesInWords = await this.helperFnRepo.CONVERT_NUMBER_TO_WORDS(Math.floor(feesQuotes + feesQuotesGst)); const feesQuotesTds = (10 / 100) * feesQuotes; const accessToken = await this.dmsService.getAccessToken(); const assetsFolderName = "infomerics-documents"; const [headingResponse, signatureResponse] = await Promise.all([ this.fetchAsset(accessToken.access_token, assetsFolderName, "Assets/Leads_management/company_logo.png"), this.fetchAsset(accessToken.access_token, assetsFolderName, "Assets/Leads_management/signature.png"), ]); const [areaCode, gstCode, financialYear] = await Promise.all([ this.helperFnRepo.GET_AREA_CODE_BY_STATE(leadData.company_state), this.helperFnRepo.GET_GST_CODE_BY_STATE(leadData.company_state), this.helperFnRepo.GET_FINANCIAL_YEAR(new Date(leadData.createdAt)), ]); const leadCreatedYear = new Date(leadData.createdAt).getFullYear(); const referenceNumber = `236-LET-2475-${leadCreatedYear}`; const mandateNumber = `IVR/MN/${financialYear}/${areaCode}-0001/GC`; const performaInvoiceNumber = `${areaCode}/${gstCode}/0001/${financialYear}`; const seriesNumber = `IVR/TINV/RF/${financialYear}/${INVOICE_NUMBER}`; const creationDate = new Date().toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }) const { pugTemplatePath, fileType } = this.getDocumentTemplatePath(document_type); const pugTemplate = fs.readFileSync(pugTemplatePath, "utf-8"); const html = pug.render(pugTemplate, { ...leadData.dataValues, reference_number: referenceNumber, mandate_number: mandateNumber, performa_invoice_number: performaInvoiceNumber, headingImage: headingResponse, signatureImage: signatureResponse, fees_quotes: feesQuotes, fees_quotes_gst: feesQuotesGst, total_fees_in_words: totalFeesInWords, invoice_number: INVOICE_NUMBER, series_number: seriesNumber, fees_quotes_tds: feesQuotesTds, creation_date: creationDate, }); const pdfBuffer = await this.generatePDF(html); const filename = this.generateFilename(leadData.company_name, fileType); const parentId = this.getParentFolderId(fileType); const uploadResponse = await this.dmsService.fileUpload(parentId, pdfBuffer, `${filename}.pdf`); const eTag = uploadResponse['eTag'] const formattedETag = eTag.split(',')[0].replace(/[{}]/g, '').replace(/^"|"$/g, '').trim(); return {pdfBuffer, formattedETag, referenceNumber, creationDate, mandateNumber, companyGstInNo, grossFees, tds, netFeesReceivable, performaInvoiceNumber}; } catch (error) { console.error("Error generating PDF:", error); throw new Error(`Failed to generate PDF: ${error.message}`); } } --------------------------------------------------------------------------------------------------------------------------------------------------