const express = require("express"); const router = express.Router(); const fs = require("fs"); const PizZip = require("pizzip"); const Docxtemplater = require("docxtemplater"); const logger = require("../utils/logger"); const path = require("path"); const moment = require("moment"); const parcoursService = require("../services/parcoursService"); const contratService = require("../services/contratService"); const userService = require("../services/userService"); const globalService = require("../services/globalService"); const moduloTPPC = require("../constantes/json-modulateur-tppc"); require("moment/locale/fr"); moment.locale("fr"); function getSelectedFranchise(franchiseId, tarif) { switch (franchiseId) { case "150": return tarif.franchise150 case "300": return tarif.franchise300 case "mini150": return tarif.franchiseMini150 case "mini300": return tarif.franchiseMini300 } } function getSelectedFranchiseTitre(franchiseId) { switch (franchiseId) { case "150": return "150 €" case "300": return "300 €" case "mini150": return "5 % avec 150 € minimum et 1 000 € maximum" case "mini300": return "10 % avec 300 € minimum et 2 000 € maximum" } } //generate Projet TPPC router.post("/tppc/projet/:numParcours", async (req, res) => { // TODO Attention conditionner en fonction du type de CP const content = fs.readFileSync( path.resolve("src/templates/template-projet-tppc.docx"), "binary" ); const zip = new PizZip(content); const doc = new Docxtemplater(zip, {paragraphLoop: true, linebreaks: true}); const numParcours = req.params.numParcours.toUpperCase(); const parcours = await parcoursService.getParcoursByNumParcours(numParcours); const contrat = await contratService.getContratById(parcours.contrat); const client = contrat?.["@expand"]?.client || {}; const intermediaire = contrat?.["@expand"]?.intermediaire || {}; const tppc = contrat?.["@expand"]?.enCours || {}; const projet = tppc?.["@expand"]?.projet || {}; const tarif = tppc?.["@expand"]?.tarif || null; const listAssAdd = []; try { projet.assureAdditionnel.forEach((objet) => { listAssAdd.push( objet.nom + " - Adresse : " + objet.adresse + " - Siret : " + objet.siret ); }); } catch (error) {} // Cas date du jour d'édition let dateNow; dateNow = moment().format("DD MMMM YYYY"); const hasExtGar = tppc.marCiternes || tppc.marDenreesSousTemp || tppc.marAnimaux || tppc.marFranchise || tppc.marEnExpo; let sinistre = projet.antSin; let aucunSinistre = false; let unSeulSinistre = false; let plusSinistre = false; if (sinistre === 0) { aucunSinistre = true; } else if (sinistre == 1) { unSeulSinistre = true; } else { plusSinistre = true; } const hasTemporaire = contrat.type === "TEMPORAIRE"; const hasMensuel = projet.tempo === "mensuel"; let formatTarifFlotte = null; if (tppc.tarFlotte) { formatTarifFlotte = tppc.tarFlotte.map((item) => { item.primeVehComTarif = parseFloat(item.primeVehComTarif) item.capitalTarif = parseFloat(item.capitalTarif) item.primeHTComTarif = parseFloat(item.primeHTComTarif) return { typeTarif: item.typeVehTarif, capitalTarif: globalService.customFormatNumber(item.capitalTarif,true), primeTarif: globalService.customFormatNumber(item.primeVehComTarif, true), nbVehiculesTarif: item.nbVehiculesTarif, primeHTTarif: globalService.customFormatNumber(item.primeHTComTarif, true), }; }); } let formatListDesiVehicule = null; if (projet.designationVehicule) { formatListDesiVehicule = projet.designationVehicule.map((item) => { item.capital = parseFloat(item.capital) return { marque: item.marque, genre: item.genre, type: item.type, immat: item.immat, capital: globalService.customFormatNumber(item.capital, true), }; }); } const selectedFranchiseTitre = tarif ? getSelectedFranchiseTitre(tarif.franchiseId) : "A DÉFINIR" const hasADefinir = tarif ? false : true try { doc.render({ //conditionnel hasTemporaire: hasTemporaire, hasMensuel: hasMensuel, plusSinistre: plusSinistre, unSeulSinistre: unSeulSinistre, aucunSinistre: aucunSinistre, // Client nomClient: client.nom, adrClient: client.adresse, postalClient: client.codePostal, villeClient: client.ville, numClient: client.numClient, // Intermédiaire nomInter: intermediaire.nom, hasInterMutualist: intermediaire.type == "AGENT MUTUALISTE" ? true : false, adrInter: intermediaire.adresse, postalInter: intermediaire.codePostal, villeInter: intermediaire.ville, oriasInter: intermediaire.numOrias, hasOrias: intermediaire.numOrias == "" ? false : true, numInter: intermediaire.numTelephone, mailInter: intermediaire.mail, hasMail: intermediaire.mail ? true : false, // Contrat numSaisine: contrat.numSaisine, numContrat: contrat.numContrat, numProjet: contrat.numSaisine ? contrat.numSaisine : contrat.numContrat, hasCP: contrat.type == "AN" || contrat.type == "TEMPORAIRE" ? true : false, hasRemplacement: contrat.type == "REMPLACEMENT" ? true : false, hasAssAdd: listAssAdd.length > 0 ? true : false, listAssAdd: listAssAdd, listDesiVehicule: formatListDesiVehicule, listeTarifFlotte: formatTarifFlotte, hasCotForfaitaire: projet.typeCot == "forfaitaire" ? true : false, hasRev: projet.typeCot == "revisable" ? true : false, hasCotCA: projet.typeRev == "CotCA" ? true : false, hasFlotteOuverte: projet.typeRev == "FlotteOuverte" ? true : false, hasCourtier: intermediaire.type == "COURTIER" ? true : false, hasAgent: intermediaire.type == "COURTIER" ? false : true, actAssuree: tppc.actAssuree, //Les garanties hasGarIAC: tppc.garanties.includes('IAC'), hasGarHIAC: tppc.garanties.includes('HIAC'), hasGarVol: tppc.garanties.includes('Vol'), //Ext Garantie hasGarCit: tppc.marCiternes, hasGarFrigo: tppc.marDenreesSousTemp, hasGarAniViv: tppc.marAnimaux, hasVehiculeTransp: tppc.marFranchise, hasGarMarExp: tppc.marEnExpo, nombreExp: tppc.nbExpo, franchiseMarExpo : tppc.franchiseMarExpo == "500" ? "500€" : "10% minimum 150€ maximum 1000€", hasExtGar: hasExtGar, hasADefinir : hasADefinir, //Antécedent de sinitre antSinistre: projet.antSin, nombreVehicule: tppc.nbVehic, // Informations sur les cotisations cotCapitalVeh:tppc.cotCapVeh, CA: globalService.customFormatNumber(projet.ca, true), cotTauxTax: globalService.customFormatNumber(projet.cotTauxTax, true, true), cotAnnuelleHT: globalService.customFormatNumber(tppc.primeHT, true), cotAnnuelleTTC: globalService.customFormatNumber(projet.tarifComTTC, true), cotIrrMini: globalService.customFormatNumber(projet.cotIrreductible, true), // Temporalité contrat dateJour: dateNow, tempo: projet.tempo, hasTypeTemporaire: contrat.type == "TEMPORAIRE" ? true : false, hasTypeAutreTempo: contrat.type == "AN" || contrat.type == "REMPLACEMENT" ? true : false, dateDebutEffet: projet.dateEffet == "00/00/0000" ? "A PRECISER" : projet.dateEffet, hasDateDebutEffet : projet.dateEffet == "00/00/0000" ? false : true, dateFinEffet: projet.dateFin == "00/00/0000" ? "A PRECISER" : projet.dateFin, hasDateFinEffet : projet.dateFin == "00/00/0000" ? false : true, dateEcheance: projet.dateEcheance == "00/00" ? "A PRECISER" : projet.dateEcheance, hasDateEcheance : projet.dateEcheance == "00/00" ? false : true, // Franchise selectedFranchiseTitle: selectedFranchiseTitre, }); } catch (error) { const e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties, }; logger.log("error", JSON.stringify({error: e})); // Envoyez une réponse d'erreur si le rendu échoue return res.status(500).send("Erreur lors de la génération du document"); } const buf = doc.getZip().generate({type: "nodebuffer"}); const currentDate = new Date(); // Formatage de la date au format "JJ-MM-AAAA-HH-MM-SS" const day = String(currentDate.getDate()).padStart(2, "0"); const month = String(currentDate.getMonth() + 1).padStart(2, "0"); const year = currentDate.getFullYear(); const hours = String(currentDate.getHours()).padStart(2, "0"); const minutes = String(currentDate.getMinutes()).padStart(2, "0"); const seconds = String(currentDate.getSeconds()).padStart(2, "0"); const formattedDate = `${day}-${month}-${year}-${hours}-${minutes}-${seconds}`; // Génération du nom de fichier const sanitizedClientNom = client.nom .replace(/[^\w\s.-]/gi, "") .replace(/\s+/g, "-"); const filename = `Projet-${contrat.produit}-${parcours.numParcours}-${sanitizedClientNom}-${formattedDate}`; // Définit le type de contenu et un nom de fichier par défaut pour le téléchargement res.setHeader( "Content-Type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ); res.setHeader( "Content-Disposition", "attachment; filename=" + filename + ".docx" ); // Envoie le buffer au client, déclenchant le téléchargement res.send(buf); }); //generate declinaison tarifaire TPPC router.post("/tppc/tarif/:numParcours", async (req, res) => { // TODO Attention conditionner en fonction du type de CP const content = fs.readFileSync( path.resolve("src/templates/template-declinaison-tarifaire-tppc.docx"), "binary" ); const zip = new PizZip(content); const doc = new Docxtemplater(zip, {paragraphLoop: true, linebreaks: true}); const numParcours = req.params.numParcours.toUpperCase(); const parcours = await parcoursService.getParcoursByNumParcours(numParcours); const contrat = await contratService.getContratById(parcours.contrat); const client = contrat?.["@expand"]?.client || {}; const tppc = contrat?.["@expand"]?.enCours || {}; const tarif = tppc?.["@expand"]?.tarif || {}; const user = await userService.getUserById(parcours.dernierUtilisateur); var formatTarifFlotte = null; const selectedFranchiseTitre = getSelectedFranchiseTitre(tarif.franchiseId) const selectedFranchise = getSelectedFranchise(tarif.franchiseId, tarif) const tarif150 = tarif.franchise150.proposition const tarif300 = tarif.franchise300.proposition const tarifMini150 = tarif.franchiseMini150.proposition const tarifMini300 = tarif.franchiseMini300.proposition const tarifParVeh = tppc.primeHT / tppc.nbVehic if (tppc.tarFlotte) { formatTarifFlotte = tppc.tarFlotte.map((item) => { item.primeVehModRefTarif = parseFloat(item.primeVehModRefTarif) item.capitalTarif = parseFloat(item.capitalTarif) item.primeVehTarif = parseFloat(item.primeVehTarif) item.primeHTModRefTarif = parseFloat(item.primeHTModRefTarif) return { typeVehTarif: item.typeVehTarif, capitalTarif: globalService.customFormatNumber(item.capitalTarif, false, false) + " €", primeVehTarif: globalService.customFormatNumber(item.primeVehTarif, false, false) + " €", garTarif: item.garTarif, typeMarTarif: moduloTPPC.objModMar[item.typeMarTarif].tarif, primeVehModRefTarif: globalService.customFormatNumber(item.primeVehModRefTarif) + " €", nbVehiculesTarif: item.nbVehiculesTarif, primeHTModRefTarif: globalService.customFormatNumber(item.primeHTModRefTarif, true, false) + " €", }; }); } var marAssuree = [] if (tppc.marOrdinaires) { marAssuree.push(moduloTPPC.objModMar.marOrdinaires.tarif) } if (tppc.marBennes) { marAssuree.push(moduloTPPC.objModMar.marBennes.tarif) } if (tppc.marDenreesHorsTemp) { marAssuree.push(moduloTPPC.objModMar.marDenreesHorsTemp.tarif) } if (tppc.marAuto) { marAssuree.push(moduloTPPC.objModMar.marAuto.tarif) } if (tppc.marRisques) { marAssuree.push(moduloTPPC.objModMar.marRisques.tarif) } if (tppc.marEngins) { marAssuree.push(moduloTPPC.objModMar.marEngins.tarif) } if (tppc.marCiternes) { marAssuree.push(moduloTPPC.objModMar.marCiternes.tarif) } if (tppc.marAnimaux) { marAssuree.push(moduloTPPC.objModMar.marAnimaux.tarif) } if (tppc.marDenreesSousTemp) { marAssuree.push(moduloTPPC.objModMar.marDenreesSousTemp.tarif) } marAssuree = marAssuree.join(', ') try { doc.render({ matricule : user.matricule, hasContrat: contrat.numContrat || false, numContrat: contrat.numContrat, hasSaisine: contrat.numSaisine || false, numSaisine: contrat.numSaisine, nomClient: client.nom, actAssuree: tppc.actAssuree, montantSin: tarif.montantSinistre, franchiseSelected: selectedFranchiseTitre, tarFlotte: formatTarifFlotte, tarif150: tarif150, tarif300: tarif300, tarifMini150: tarifMini150, tarifMini300: tarifMini300, marAssuree: marAssuree, tarifSelected: selectedFranchise.proposition, tarifCommercial: tppc.primeHT, tarifParVeh: tarifParVeh, isEnsemble: tarif.typeContrat == "ensemble", isDetaillee: tarif.typeContrat == "detaillee", //Les garanties hasHIAC: tppc.garanties.includes('HIAC'), hasVol: tppc.garanties.includes('Vol'), nbVehic: tppc.nbVehic, // Informations sur les cotisations cotCapVeh: tppc.cotCapVeh }); } catch (error) { const e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties, }; logger.log("error", JSON.stringify({error: e})); // Envoyez une réponse d'erreur si le rendu échoue return res.status(500).send("Erreur lors de la génération du document"); } const buf = doc.getZip().generate({type: "nodebuffer"}); const currentDate = new Date(); // Formatage de la date au format "JJ-MM-AAAA-HH-MM-SS" const day = String(currentDate.getDate()).padStart(2, "0"); const month = String(currentDate.getMonth() + 1).padStart(2, "0"); const year = currentDate.getFullYear(); const hours = String(currentDate.getHours()).padStart(2, "0"); const minutes = String(currentDate.getMinutes()).padStart(2, "0"); const seconds = String(currentDate.getSeconds()).padStart(2, "0"); const formattedDate = `${day}-${month}-${year}-${hours}-${minutes}-${seconds}`; // Génération du nom de fichier const sanitizedClientNom = client.nom .replace(/[^\w\s.-]/gi, "") .replace(/\s+/g, "-"); const filename = `Tarif-${contrat.produit}-${parcours.numParcours}-${sanitizedClientNom}-${formattedDate}`; // Définit le type de contenu et un nom de fichier par défaut pour le téléchargement res.setHeader( "Content-Type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ); res.setHeader( "Content-Disposition", "attachment; filename=" + filename + ".docx" ); // Envoie le buffer au client, déclenchant le téléchargement res.send(buf); }); module.exports = router;