personnal/ecole/src copy/controllers/generateFacController.js

522 lines
21 KiB
JavaScript

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 globalService = require("../services/globalService");
const userService = require("../services/userService");
const constantesFAC = require("../constantes/json-modulateur-fac");
require("moment/locale/fr");
moment.locale("fr");
router.post("/fac/projet/:numParcours", async (req, res) => {
const content = fs.readFileSync(
path.resolve("src/templates/template-projet-fac.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 fac = contrat?.["@expand"]?.enCours || null;
const projet = fac?.["@expand"]?.projet || null;
const moyenTransportList = ["terrestre", "maritime", "aerien", "postal", "fluvial"]
const selectedTransportList = []
try {
moyenTransportList.forEach((transport) => {
if (projet[transport] !== "") {
selectedTransportList.push(transport)
}
})
} catch (error) {}
var transportListVirguleEt
if (selectedTransportList.length > 1) {
transportListVirguleEt = selectedTransportList
.slice(0, selectedTransportList.length - 1)
.join(', ')
+ ' et ' + selectedTransportList[selectedTransportList.length - 1]
} else {
transportListVirguleEt = selectedTransportList.toString()
}
//au féminin
const transportListOuEt = selectedTransportList.join(" et/ou ")
.replace('fluvial', "fluviale")
.replace('postal', 'postale')
.replace('aerien', 'aerienne')
const listAssAdd = [];
try {
projet.assureAdditionnel.forEach((objet) => {
listAssAdd.push(objet.nom + " - Adresse : " + objet.adresse + " - Siret : " + objet.siret);
});
} catch (error) {}
const risqueTransport = {
"achat": "des contrats d'achat",
"vente": "des contrats de vente",
"sav": "des opérations de SAV",
"demo": "des démonstrations",
"transfert": "des transferts inter-usines"
}
Object.keys(risqueTransport).forEach((risque) => {
if (!projet.risqueTransport.includes(risque)) {
delete risqueTransport[risque]
}
})
const listRisqueTransport = Object.keys(risqueTransport).map((key) => risqueTransport[key])
const mondeEntier = (fac.zones.includes('zone1') &&
fac.zones.includes('zone2') &&
fac.zones.includes('zone3') &&
fac.zones.includes('zone4') &&
fac.zones.includes('zone5') &&
fac.zones.includes('zone6'))
const hasZone456 = (fac.zones.includes('zone4') &&
fac.zones.includes('zone5') &&
fac.zones.includes('zone6'))
const hasGarOptAuto = projet.garOpt.includes('auto')
const hasGarOptEmballage = projet.garOpt.includes('emballage')
const hasGarOptEtiquette = projet.garOpt.includes('etiquette')
const hasGarOptTemperature = projet.garOpt.includes('temperature')
const hasGarOptMarque = projet.garOpt.includes('marque')
const hasTPPC = fac.tppc
const hasMarchandiseExposition = fac.nbVehicExpo > 0
const condition4 = (hasGarOptAuto || hasGarOptEmballage || hasGarOptEtiquette || hasGarOptMarque || hasTPPC || hasMarchandiseExposition)
const hasGarOpt = projet.garOpt.length > 0
const condition2 = hasGarOpt || hasTPPC || hasMarchandiseExposition
const anneeProchaine = moment().add(1, 'years').format('YYYY')
const dateFin = (projet.dateFin == "00/00" || projet.dateFin == "00/00/0000") ? "A PRECISER" : projet.dateFin
const dateEffet = (projet.dateEffet == "00/00" || projet.dateEffet == "00/00/0000") ? "A PRECISER" : projet.dateEffet
const dateEcheance = (projet.dateEcheance == "00/00" || projet.dateEcheance == "00/00/0000") ? "A PRECISER" : projet.dateEcheance + '/' + anneeProchaine
const renderObject = {
nomClient: client.nom,
adrClient: client.adresse,
postalClient: client.codePostal,
villeClient: client.ville,
numClient: client.numClient,
nomInter: intermediaire.nom,
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,
numProjet: contrat.numSaisine ? contrat.numSaisine : contrat.numContrat,
hasCP: (contrat.type == "AN" || contrat.type == "TEMPORAIRE"),
hasRemplacement: (contrat.type == "REMPLACEMENT"),
hasRGAuto: (fac.rg == "auto"),
hasRGDemande: (fac.rg == 'demande'),
hasRG: (fac.rg == 'demande' || fac.rg == 'auto'),
hasEtendue: (fac.typeRG == "etendue"),
hasWaterborne: (fac.typeRG == "waterborne"),
hasProgrammeInternational: projet.programmeInternational,
hasAssuresAdditionnels: listAssAdd.length > 0,
listAssAdd: listAssAdd,
hasTemporaire: contrat.type == "TEMPORAIRE",
actAssure: fac.actAssure,
typeMar: fac.typeMar,
listMoyenTransportEtOu: transportListOuEt,
listMoyenTransportVirguleEt: transportListVirguleEt,
listRisqueTransport: listRisqueTransport,
depart: projet.lieuDepart,
arrivee: projet.lieuArrivee,
dateJour: moment().format("DD MMMM YYYY"),
dateEffet: dateEffet,
dateFin: dateFin,
dateEcheance: dateEcheance,
hasMarchandiseExposition: hasMarchandiseExposition,
hasMondeEntier: mondeEntier,
hasZone1: fac.zones.includes('zone1'),
hasZone2: fac.zones.includes('zone2'),
hasZone3: fac.zones.includes('zone3'),
hasZone4: fac.zones.includes('zone4'),
hasZone5: fac.zones.includes('zone5'),
hasZone6: fac.zones.includes('zone6'),
hasZone456: hasZone456,
hasTPPC: hasTPPC,
hasTPPCTousRisques: projet.typeTPPC.includes('tousRisques'),
hasTPPCFlotteND: projet.typeTPPC.includes('flotteND'),
capitalMax: projet.capitalMax,
franchiseTransport: projet.franchiseTransport,
condition4: condition4,
hasGarOpt: hasGarOpt,
condition2: condition2,
hasGarOptAuto: hasGarOptAuto,
hasGarOptEmballage: hasGarOptEmballage,
hasGarOptEtiquette: hasGarOptEtiquette,
hasGarOptMarque: hasGarOptMarque,
hasGarOptTemperature: hasGarOptTemperature,
capitalTPPC: fac.capitalTPPC,
franchiseExpo: fac.franchiseExpo,
hasCG: projet.valeurAssuree.includes('cg'),
hasDerogation: projet.valeurAssuree.includes('derogation'),
hasVaBasePrix: projet.valeurAssureeBase.includes('prix'),
hasVaBaseAchat: projet.valeurAssureeBase.includes('achat'),
hasVaBaseVente: projet.valeurAssureeBase.includes('vente'),
hasAerienTousRisques: fac.aerien.includes('tousRisques'),
hasAerienEventMaj: fac.aerien.includes('eventMaj'),
hasMaritimeTousRisques: fac.maritime.includes('tousRisques'),
hasMaritimeEventMaj: fac.maritime.includes('eventMaj'),
hasTerrestreTousRisques: fac.terrestre.includes('tousRisques'),
hasTerrestreEventMaj: fac.terrestre.includes('eventMaj'),
hasPostalTousRisques: fac.postal.includes('tousRisques'),
hasPostalEventMaj: fac.postal.includes('eventMaj'),
hasFluvialTousRisques: fac.fluvial.includes('tousRisques'),
hasFluvialEventMaj: fac.fluvial.includes('eventMaj'),
hasFranchiseTransport: projet.franchiseTransport !== "",
cotRO: globalService.customFormatNumber(fac.cotRO),
cotRG: globalService.customFormatNumber(fac.cotRG),
cotProvRO: globalService.customFormatNumber(fac.cotProvRO),
cotProvRG: globalService.customFormatNumber(fac.cotProvRG),
cotComptant: globalService.customFormatNumber(projet.cotComptant),
tauxCotRO: globalService.customFormatNumber(fac.tauxCotRO, true),
tauxCotRG: globalService.customFormatNumber(fac.tauxCotRG, true),
cotAnnuelle: globalService.customFormatNumber(fac.primeHT),
cotIrred: globalService.customFormatNumber(fac.primeMini),
capitalTPPC: globalService.customFormatNumber(fac.capitalTPPC),
capitalExpo: globalService.customFormatNumber(fac.capitalExpo),
franchiseTPPC: globalService.customFormatNumber(fac.franchiseTPPC),
chiffreAffaires: globalService.customFormatNumber(fac.ca),
hasMensuel: (projet.tempo == "mensuel"),
hasChiffreAffaires: (projet.typeContrat == "chiffreAffaires"),
hasAvisAliments: (projet.typeContrat == "avisAliments"),
hasPartResultat: projet.participationResultat,
hasAgentMutualiste: (intermediaire.type == "AGENT MUTUALISTE"),
hasAgent: (intermediaire.type == "AGENT MUTUALISTE" || intermediaire.type == "AGENT NON MUTUALISTE"),
hasCourtier: (intermediaire.type == "COURTIER"),
tempo: projet.tempo,
}
try {
doc.render(renderObject)
} 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 formattedDate = moment().format('DD-MM-YYYY-HH-mm-ss')
// 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 FAC
router.post("/fac/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-fac.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 fac = contrat?.["@expand"]?.enCours || {};
const tarif = fac?.["@expand"]?.tarif || {};
const user = await userService.getUserById(parcours.dernierUtilisateur);
function getSelectedFranchise(franchiseId) {
switch (franchiseId) {
case "sansFranchise":
return tarif.sansFranchise
case "franchise350":
return tarif.franchise350
case "franchise750":
return tarif.franchise750
}
}
function getSelectedFranchiseTitre(franchiseId) {
switch (franchiseId) {
case "sansFranchise":
return "Sans Franchise"
case "franchise350":
return "Franchise 350 €"
case "franchise750":
return "Franchise 750 €"
}
}
function initialeMaj(str) {
return typeof str == "string" ? str.charAt(0).toUpperCase() + str.slice(1) : ""
}
const selectedFranchiseTitre = getSelectedFranchiseTitre(tarif.selectedFranchise)
const selectedFranchise = getSelectedFranchise(tarif.selectedFranchise)
const transports = []
if (fac.terrestre !== "") {
transports.push("Terrestre")
}
if (fac.maritime !== "") {
transports.push("Maritime")
}
if (fac.aerien !== "") {
transports.push("Aerien")
}
if (fac.postal !== "") {
transports.push("Postal")
}
if (fac.fluvial !== "") {
transports.push("Fluvial")
}
if (fac.multimodal !== "") {
transports.push('Multimodal')
}
const listTransports = transports.join(', ')
const hasMondeEntier = (
fac.zones.includes("zone1") &&
fac.zones.includes("zone2") &&
fac.zones.includes("zone3") &&
fac.zones.includes("zone4") &&
fac.zones.includes("zone5") &&
fac.zones.includes("zone6")
)
const typeRO = tarif.typeRO == "tousRisques" ? "Tous Risques" : "Evenements Majeurs"
var typePolice
switch (tarif.typePolice) {
case "ca":
typePolice = "Police au Chiffre d'Affaires";
break;
case "national":
typePolice = "Police au Voyage National";
break;
case "international":
typePolice = "Police au Voyage International";
break;
}
try {
doc.render({
matricule: user.matricule,
hasContrat: contrat.numContrat || false,
numContrat: contrat.numContrat,
hasSaisine: contrat.numSaisine || false,
numSaisine: contrat.numSaisine,
nomClient: client.nom,
actAssuree: fac.actAssuree,
montantSin: tarif.sinistres,
franchiseSelected: selectedFranchiseTitre,
typeMar: fac.typeMar,
ca: fac.ca,
montantGarantir: tarif.montantGarantir,
conditionnement: constantesFAC.objModCond?.[tarif.conditionnement]?.nom ?? "",
typeMar: fac.typeMar,
transports: listTransports,
hasMondeEntier: hasMondeEntier,
hasZone1: fac.zones.includes("zone1"),
hasZone2: fac.zones.includes("zone2"),
hasZone3: fac.zones.includes("zone3"),
hasZone4: fac.zones.includes("zone4"),
hasZone5: fac.zones.includes("zone5"),
hasZone6: fac.zones.includes("zone6"),
hasZone1Achats: tarif.fluxAchats?.zone == "zone1",
hasZone2Achats: tarif.fluxAchats?.zone == "zone2",
hasZone3Achats: tarif.fluxAchats?.zone == "zone3",
hasZone4Achats: tarif.fluxAchats?.zone == "zone4",
hasZone5Achats: tarif.fluxAchats?.zone == "zone5",
hasZone6Achats: tarif.fluxAchats?.zone == "zone6",
conditionnementAchats: constantesFAC.objModCond[tarif.fluxAchats?.conditionnement]?.nom ?? "",
hasZone1Ventes: tarif.fluxVentes?.zone == "zone1",
hasZone2Ventes: tarif.fluxVentes?.zone == "zone2",
hasZone3Ventes: tarif.fluxVentes?.zone == "zone3",
hasZone4Ventes: tarif.fluxVentes?.zone == "zone4",
hasZone5Ventes: tarif.fluxVentes?.zone == "zone5",
hasZone6Ventes: tarif.fluxVentes?.zone == "zone6",
conditionnementVentes: constantesFAC.objModCond[tarif.fluxVentes?.conditionnement]?.nom ?? "",
hasFluxGlobal: tarif.typeFlux == "global",
hasFluxDetailles: tarif.typeFlux == "detailles",
hasFluxVentes: (tarif.fluxVentes),
hasFluxAchats: (tarif.fluxAchats),
hasFluxIntersites: tarif.fluxIntersites,
fluxAchats: tarif.fluxAchats,
fluxVentes: tarif.fluxVentes,
transportVentes: initialeMaj(tarif.fluxVentes?.transport),
transportAchats: initialeMaj(tarif.fluxAchats?.transport),
typeRO: typeRO,
typePolice: typePolice,
hasTPPC: fac.tppc,
hasMarExpo: (fac.nbVehicExpo > 0),
hasRG: fac.rg == "auto",
hasRGAchats: (tarif.fluxAchats?.typeRG),
hasRGVentes: (tarif.fluxVentes?.typeRG),
tarif350: tarif.franchise350.proposition,
// pourcentAct350: parseFloat(tarif.franchise350.pourcentAct) * 100,
// pourcentCA350: parseFloat(tarif.franchise350.pourcentCA) * 100,
// pourcentMar350: parseFloat(tarif.franchise350.pourcentMar) * 100,
// pourcentFranchise350: parseFloat(tarif.franchise350.pourcentFranchise) * 100,
tauxRO350: tarif.franchise350.tauxRO,
tauxRG350: tarif.franchise350.tauxRG,
franchiseTPPC350: tarif.franchise350.franchiseTPPC ?? "",
franchiseExpo350: tarif.franchise350.franchiseExpo ?? "",
tarif750: tarif.franchise750.proposition,
// pourcentAct750: parseFloat(tarif.franchise750.pourcentAct) * 100,
// pourcentCA750: parseFloat(tarif.franchise750.pourcentCA) * 100,
// pourcentMar750: parseFloat(tarif.franchise750.pourcentMar) * 100,
// pourcentFranchise750: parseFloat(tarif.franchise750.pourcentFranchise) * 100,
tauxRO750: tarif.franchise750.tauxRO,
tauxRG750: tarif.franchise750.tauxRG,
franchiseTPPC750: tarif.franchise750.franchiseTPPC ?? "",
franchiseExpo750: tarif.franchise750.franchiseExpo ?? "",
tarifSansFranchise: tarif.sansFranchise.proposition,
// pourcentActSansFranchise: parseFloat(tarif.sansFranchise.pourcentAct) * 100,
// pourcentCASansFranchise: parseFloat(tarif.sansFranchise.pourcentCA) * 100,
// pourcentMarSansFranchise: parseFloat(tarif.sansFranchise.pourcentMar) * 100,
// pourcentFranchiseSansFranchise: parseFloat(tarif.sansFranchise.pourcentFranchise) * 100,
franchiseTPPCSansFranchise: tarif.sansFranchise.franchiseTPPC ?? "",
franchiseExpoSansFranchise: tarif.sansFranchise.franchiseExpo ?? "",
tauxROSansFranchise: tarif.sansFranchise.tauxRO,
tauxRGSansFranchise: tarif.sansFranchise.tauxRG,
tarifSelected: selectedFranchise.proposition,
tarifCommercial: fac.primeHT,
franchiseTPPCSelected: selectedFranchise.franchiseTPPC ?? "",
franchiseExpoSelected: selectedFranchise.franchiseExpo ?? "",
tauxROSelected: fac.tauxCotRO,
tauxRGSelected: fac.tauxCotRG
});
} 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;