PROQUELEC

Expertise & Formation en Électricité Industrielle

📍Immeuble Coumba Castel, 12 rue Saint-Michel, 4e étage - BP: 32 037 Dakar
📞Tél: (+221) 33 848 68 55
✉️oumarkebe@proquelec.sn / proquelec@proquelec.sn
🌐www.proquoelec.sn
📄NINEA: 0191403 089

Configuration de la Formation

Le nom du client est obligatoire.
Veuillez sélectionner au moins un pack.
Le nombre de participants doit être entre 1 et 15. Min: 1, Max: 15
Option 1: Salle de Formation PROQUELEC (100 000 FCFA) + Déjeuner (20 000 FCFA/participant)

📊 Récapitulatif du Devis

BROUILLON
Packs sélectionnés:Aucun
Nombre de participants:12
Option logistique:Option 1
Coût des packs:0 FCFA
Frais logistiques:0 FCFA
TOTAL:0 FCFA

Personnalisation des Documents

Aperçu des Documents

📋

Aperçu des Documents

Sélectionnez un aperçu pour visualiser le document ici.

`; this.downloadWordDocument(quoteHTML, `Devis_${quoteNumber}_${clientName.replace(/\s+/g, '_')}.doc`); this.showNotification("Devis généré avec succès !"); } previewQuote(){ if(!this.validateForm()){ this.elements.documentPreview.innerHTML=`
📄

Erreur

Veuillez remplir les champs obligatoires.

`; return; } const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; const quoteNumber=this.state.quoteNumber; const participants=this.state.participants; const notes=this.state.notes; let selectedPacks=[]; let totalPacksCost=0; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack){ selectedPacks.push(pack); totalPacksCost +=pack.price; }}); const logisticsOption=CONFIG.logisticsOptions[this.state.logisticsOption]; const logisticsCost=logisticsOption.roomCost + logisticsOption.mealCostPerParticipant * participants; const totalCost=totalPacksCost + logisticsCost; let previewHTML=`
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
NINEA: ${CONFIG.company.ninea} | Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2||CONFIG.company.email}
DEVIS
N° ${quoteNumber} - Date: ${formatDate(new Date().toISOString())} - Valable 3 mois
Client${clientName}
Date de formation${formatDate(formationDate)}
Nombre de participants${participants}
Option logistique${ this.state.logisticsOption===CONFIG.logisticsOptions.option1.id ? "Option 1 (Salle + Restauration PROQUELEC)" : "Option 2 (Client prend en charge)" }
${selectedPacks.map(pack=> ` `).join('')} ${logisticsCost > 0 ? ` `:''}
Description Durée Prix
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''} ${pack.duration} jour(s) ${formatCurrency(pack.price)}
Frais logistiques (Salle + Restauration) - ${formatCurrency(logisticsCost)}
TOTAL ${formatCurrency(totalCost)}

Conditions de règlement : 30% à la commande, solde à la livraison.

Validité : Ce devis est valable 3 mois à compter de la date ci-dessus.

Engagement : Ce document constitue une proposition commerciale. L'engagement est pris après signature du "Bon pour accord".

Mentions légales : TVA non applicable selon le régime fiscal. Fournitures et documents offerts gratuitement.

${notes ? `
Notes:
${sanitizeHTML(notes)}
`:''}
Bon pour accord
Nom et signature du client :

${CONFIG.company.name} - ${this.state.template.footer}

NINEA: ${CONFIG.company.ninea} | ${CONFIG.company.website}

`; this.elements.documentPreview.innerHTML=previewHTML; } this.elements.generateQuoteBtn.addEventListener("click", ()=> this.generateQuote()); this.elements.previewQuoteBtn.addEventListener("click", ()=> this.previewQuote()); this.elements.quoteNumberInput.value=this.state.quoteNumber; `; this.downloadWordDocument(quoteHTML, `Devis_${quoteNumber}_${clientName.replace(/\s+/g, '_')}.doc`); this.showNotification("Devis généré avec succès !"); } previewQuote(){ if(!this.validateForm()){ this.elements.documentPreview.innerHTML=`
📄

Erreur

Veuillez remplir les champs obligatoires.

`; return; } const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; const quoteNumber=this.state.quoteNumber; const participants=this.state.participants; const notes=this.state.notes; let selectedPacks=[]; let totalPacksCost=0; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack){ selectedPacks.push(pack); totalPacksCost +=pack.price; }}); const logisticsOption=CONFIG.logisticsOptions[this.state.logisticsOption]; const logisticsCost=logisticsOption.roomCost + logisticsOption.mealCostPerParticipant * participants; const totalCost=totalPacksCost + logisticsCost; let previewHTML=`
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
NINEA: ${CONFIG.company.ninea} | Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2} / ${CONFIG.company.email}
DEVIS
N° ${quoteNumber} - Date: ${formatDate(new Date().toISOString())} - Valable 3 mois
Client${clientName}
Date de formation${formatDate(formationDate)}
Nombre de participants${participants}
Option logistique${ this.state.logisticsOption===CONFIG.logisticsOptions.option1.id ? "Option 1 (Salle + Restauration PROQUELEC)" : "Option 2 (Client prend en charge)" }
${selectedPacks.map(pack=> ` `).join('')} ${logisticsCost > 0 ? ` `:''}
Description Durée Prix
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''} ${pack.duration} jour(s) ${formatCurrency(pack.price)}
Frais logistiques (Salle + Restauration) - ${formatCurrency(logisticsCost)}
TOTAL ${formatCurrency(totalCost)}

Conditions de règlement : 30% à la commande, solde à la livraison.

Validité : Ce devis est valable 3 mois à compter de la date ci-dessus.

Engagement : Ce document constitue une proposition commerciale. L'engagement est pris après signature du "Bon pour accord".

Mentions légales : TVA non applicable selon le régime fiscal. Fournitures et documents offerts gratuitement.

${notes ? `
Notes:
${sanitizeHTML(notes)}
`:''}
Bon pour accord
Nom et signature du client :

${CONFIG.company.name} - ${this.state.template.footer}

NINEA: ${CONFIG.company.ninea} | ${CONFIG.company.website}

`; this.elements.documentPreview.innerHTML=previewHTML; } generateInvoice(){ if(!this.validateForm()) return; const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; const invoiceNumber=this.state.invoiceNumber; const participants=this.state.participants; const notes=this.state.notes; let selectedPacks=[]; let totalPacksCost=0; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack){ selectedPacks.push(pack); totalPacksCost +=pack.price; }}); const logisticsOption=CONFIG.logisticsOptions[this.state.logisticsOption]; const logisticsCost=logisticsOption.roomCost + logisticsOption.mealCostPerParticipant * participants; const totalCost=totalPacksCost + logisticsCost; const dueDate=new Date(); dueDate.setDate(dueDate.getDate() + 30); let invoiceHTML=` Facture ${invoiceNumber} - ${CONFIG.company.name}
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
NINEA: ${CONFIG.company.ninea}
Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2} / ${CONFIG.company.email}
Site: ${CONFIG.company.website}
FACTURE
N° ${invoiceNumber}
Date: ${formatDate(new Date().toISOString())}
À régler avant le ${formatDate(dueDate.toISOString())}
Client${clientName}
Date de formation${formatDate(formationDate)}
Nombre de participants${participants}
Option logistique${ this.state.logisticsOption===CONFIG.logisticsOptions.option1.id ? "Option 1 (Salle + Restauration PROQUELEC)" : "Option 2 (Client prend en charge)" }
${selectedPacks.map(pack=> ` `).join('')} ${logisticsCost > 0 ? ` `:''}
Description Durée Prix
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''} ${pack.duration} jour(s) ${formatCurrency(pack.price)}
Frais logistiques (Salle + Restauration) - ${formatCurrency(logisticsCost)}
TOTAL À RÉGLER ${formatCurrency(totalCost)}
${notes ? `
Notes:
${sanitizeHTML(notes)}
`:''} `; this.downloadWordDocument(quoteHTML, `Devis_${quoteNumber}_${clientName.replace(/\s+/g, '_')}.doc`); this.showNotification("Devis généré avec succès !"); } previewQuote(){ if(!this.validateForm()){ this.elements.documentPreview.innerHTML=`
📄

Erreur

Veuillez remplir les champs obligatoires.

`; return; } const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; const quoteNumber=this.state.quoteNumber; const participants=this.state.participants; const notes=this.state.notes; let selectedPacks=[]; let totalPacksCost=0; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack){ selectedPacks.push(pack); totalPacksCost +=pack.price; }}); const logisticsOption=CONFIG.logisticsOptions[this.state.logisticsOption]; const logisticsCost=logisticsOption.roomCost + logisticsOption.mealCostPerParticipant * participants; const totalCost=totalPacksCost + logisticsCost; let previewHTML=`
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
NINEA: ${CONFIG.company.ninea} | Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2||CONFIG.company.email}
DEVIS
N° ${quoteNumber} - Date: ${formatDate(new Date().toISOString())} - Valable 3 mois
Client${clientName}
Date de formation${formatDate(formationDate)}
Nombre de participants${participants}
Option logistique${ this.state.logisticsOption===CONFIG.logisticsOptions.option1.id ? "Option 1 (Salle + Restauration PROQUELEC)" : "Option 2 (Client prend en charge)" }
${selectedPacks.map(pack=> ` `).join('')} ${logisticsCost > 0 ? ` `:''}
Description Durée Prix
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''} ${pack.duration} jour(s) ${formatCurrency(pack.price)}
Frais logistiques (Salle + Restauration) - ${formatCurrency(logisticsCost)}
TOTAL ${formatCurrency(totalCost)}

Conditions de règlement : 30% à la commande, solde à la livraison.

Validité : Ce devis est valable 3 mois à compter de la date ci-dessus.

Engagement : Ce document constitue une proposition commerciale. L'engagement est pris après signature du "Bon pour accord".

Mentions légales : TVA non applicable selon le régime fiscal. Fournitures et documents offerts gratuitement.

${notes ? `
Notes:
${sanitizeHTML(notes)}
`:''}
Bon pour accord
Nom et signature du client :

${CONFIG.company.name} - ${this.state.template.footer}

NINEA: ${CONFIG.company.ninea} | ${CONFIG.company.website}

`; this.elements.documentPreview.innerHTML=previewHTML; } this.elements.generateQuoteBtn.addEventListener("click", ()=> this.generateQuote()); this.elements.previewQuoteBtn.addEventListener("click", ()=> this.previewQuote()); this.elements.quoteNumberInput.value=this.state.quoteNumber; `; this.downloadWordDocument(invoiceHTML, `Facture_${invoiceNumber}_${clientName.replace(/\s+/g, '_')}.doc`); this.showNotification("Facture générée avec succès !"); } previewInvoice(){ if(!this.validateForm()) return; const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; const invoiceNumber=this.state.invoiceNumber; const participants=this.state.participants; const notes=this.state.notes; let selectedPacks=[]; let totalPacksCost=0; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack){ selectedPacks.push(pack); totalPacksCost +=pack.price; }}); const logisticsOption=CONFIG.logisticsOptions[this.state.logisticsOption]; const logisticsCost=logisticsOption.roomCost + logisticsOption.mealCostPerParticipant * participants; const totalCost=totalPacksCost + logisticsCost; const dueDate=new Date(); dueDate.setDate(dueDate.getDate() + 30); let previewHTML=`
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
NINEA: ${CONFIG.company.ninea} | Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2} / ${CONFIG.company.email}
FACTURE
N° ${invoiceNumber} - Date: ${formatDate(new Date().toISOString())} - À régler avant le ${formatDate(dueDate.toISOString())}
Client ${clientName}
Date de formation ${formatDate(formationDate)}
Nombre de participants ${participants}
Option logistique ${ this.state.logisticsOption===CONFIG.logisticsOptions.option1.id ? "Option 1 (Salle + Restauration PROQUELEC)" : "Option 2 (Client prend en charge)" }
${selectedPacks.map(pack=> ` `).join('')} ${logisticsCost > 0 ? ` `:''}
Description Durée Prix
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''} ${pack.duration} jour(s) ${formatCurrency(pack.price)}
Frais logistiques (Salle + Restauration) - ${formatCurrency(logisticsCost)}
TOTAL À RÉGLER ${formatCurrency(totalCost)}

Mentions légales : TVA non applicable selon le régime fiscal. Fournitures et documents offerts gratuitement.

${notes ? `
Notes:
${sanitizeHTML(notes)}
`:''}

${CONFIG.company.name} - ${this.state.template.footer}

NINEA: ${CONFIG.company.ninea} | ${CONFIG.company.website}

`; this.elements.documentPreview.innerHTML=previewHTML; } generatePlanning(){ if(!this.validateForm()) return; const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; let selectedPacks=[]; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack) selectedPacks.push(pack); }); if(selectedPacks.length===0){ this.showNotification("Veuillez sélectionner au moins un pack de formation."); return; } let planningHTML=` Planning Formation - ${CONFIG.company.name}
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2} / ${CONFIG.company.email}
PLANNING DE FORMATION
${clientName} - ${formatDate(formationDate)}
${selectedPacks.map(pack=> `
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''}
${pack.program.map(day=> ` ${day.themes.map(theme=> ` `).join('')}
Jour ${day.day}
Durée Thème Savoirs Savoir-faire
${theme.time} ${theme.topic} ${theme.knowledge} ${theme.skills}
`).join('')} `).join('')} `; this.downloadWordDocument(quoteHTML, `Devis_${quoteNumber}_${clientName.replace(/\s+/g, '_')}.doc`); this.showNotification("Devis généré avec succès !"); } previewQuote(){ if(!this.validateForm()){ this.elements.documentPreview.innerHTML=`
📄

Erreur

Veuillez remplir les champs obligatoires.

`; return; } const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; const quoteNumber=this.state.quoteNumber; const participants=this.state.participants; const notes=this.state.notes; let selectedPacks=[]; let totalPacksCost=0; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack){ selectedPacks.push(pack); totalPacksCost +=pack.price; }}); const logisticsOption=CONFIG.logisticsOptions[this.state.logisticsOption]; const logisticsCost=logisticsOption.roomCost + logisticsOption.mealCostPerParticipant * participants; const totalCost=totalPacksCost + logisticsCost; let previewHTML=`
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
NINEA: ${CONFIG.company.ninea} | Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2||CONFIG.company.email}
DEVIS
N° ${quoteNumber} - Date: ${formatDate(new Date().toISOString())} - Valable 3 mois
Client${clientName}
Date de formation${formatDate(formationDate)}
Nombre de participants${participants}
Option logistique${ this.state.logisticsOption===CONFIG.logisticsOptions.option1.id ? "Option 1 (Salle + Restauration PROQUELEC)" : "Option 2 (Client prend en charge)" }
${selectedPacks.map(pack=> ` `).join('')} ${logisticsCost > 0 ? ` `:''}
Description Durée Prix
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''} ${pack.duration} jour(s) ${formatCurrency(pack.price)}
Frais logistiques (Salle + Restauration) - ${formatCurrency(logisticsCost)}
TOTAL ${formatCurrency(totalCost)}

Conditions de règlement : 30% à la commande, solde à la livraison.

Validité : Ce devis est valable 3 mois à compter de la date ci-dessus.

Engagement : Ce document constitue une proposition commerciale. L'engagement est pris après signature du "Bon pour accord".

Mentions légales : TVA non applicable selon le régime fiscal. Fournitures et documents offerts gratuitement.

${notes ? `
Notes:
${sanitizeHTML(notes)}
`:''}
Bon pour accord
Nom et signature du client :

${CONFIG.company.name} - ${this.state.template.footer}

NINEA: ${CONFIG.company.ninea} | ${CONFIG.company.website}

`; this.elements.documentPreview.innerHTML=previewHTML; } this.elements.generateQuoteBtn.addEventListener("click", ()=> this.generateQuote()); this.elements.previewQuoteBtn.addEventListener("click", ()=> this.previewQuote()); this.elements.quoteNumberInput.value=this.state.quoteNumber; `; this.downloadWordDocument(planningHTML, `Planning_${clientName.replace(/\s+/g, '_')}.doc`); this.showNotification("Planning généré avec succès !"); } previewPlanning(){ if(!this.validateForm()){ this.elements.documentPreview.innerHTML=`
📅

Aucun Pack Sélectionné

Veuillez sélectionner au moins un pack de formation pour voir le planning.

`; return; } const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; let selectedPacks=[]; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack) selectedPacks.push(pack); }); let previewHTML=`
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2} / ${CONFIG.company.email}
PLANNING DE FORMATION
${clientName} - ${formatDate(formationDate)}
`; selectedPacks.forEach(pack=> { const isRecyclage=pack.type==='recyclage'; previewHTML +=`
${pack.name} ${isRecyclage ? 'RECYCLAGE':''}
`; pack.program.forEach(day=> { previewHTML +=` ${day.themes.map(theme=> ` `).join('')}
Jour ${day.day}
Durée Thème Savoirs Savoir-faire
${theme.time} ${theme.topic} ${theme.knowledge} ${theme.skills}
`; }); }); previewHTML +=`

${CONFIG.company.name} - ${this.state.template.footer}

NINEA: ${CONFIG.company.ninea} | ${CONFIG.company.website}

`; this.elements.documentPreview.innerHTML=previewHTML; }} document.addEventListener("DOMContentLoaded", ()=> { new FormationConfigurator(); }); `; this.downloadWordDocument(quoteHTML, `Devis_${quoteNumber}_${clientName.replace(/\s+/g, '_')}.doc`); this.showNotification("Devis généré avec succès !"); } previewQuote(){ if(!this.validateForm()){ this.elements.documentPreview.innerHTML=`
📄

Erreur

Veuillez remplir les champs obligatoires.

`; return; } const clientName=this.state.clientName||"Client"; const formationDate=this.state.formationDate; const quoteNumber=this.state.quoteNumber; const participants=this.state.participants; const notes=this.state.notes; let selectedPacks=[]; let totalPacksCost=0; this.state.selectedPacks.forEach(packId=> { const pack=CONFIG.packs[packId]; if(pack){ selectedPacks.push(pack); totalPacksCost +=pack.price; }}); const logisticsOption=CONFIG.logisticsOptions[this.state.logisticsOption]; const logisticsCost=logisticsOption.roomCost + logisticsOption.mealCostPerParticipant * participants; const totalCost=totalPacksCost + logisticsCost; let previewHTML=`
${this.state.template.logo ? `` : `
${CONFIG.company.name}
` }
${CONFIG.company.address}
NINEA: ${CONFIG.company.ninea} | Tél: ${CONFIG.company.phone} | Email: ${CONFIG.company.email2||CONFIG.company.email}
DEVIS
N° ${quoteNumber} - Date: ${formatDate(new Date().toISOString())} - Valable 3 mois
Client${clientName}
Date de formation${formatDate(formationDate)}
Nombre de participants${participants}
Option logistique${ this.state.logisticsOption===CONFIG.logisticsOptions.option1.id ? "Option 1 (Salle + Restauration PROQUELEC)" : "Option 2 (Client prend en charge)" }
${selectedPacks.map(pack=> ` `).join('')} ${logisticsCost > 0 ? ` `:''}
Description Durée Prix
${pack.name} ${pack.type==='recyclage' ? 'RECYCLAGE':''} ${pack.duration} jour(s) ${formatCurrency(pack.price)}
Frais logistiques (Salle + Restauration) - ${formatCurrency(logisticsCost)}
TOTAL ${formatCurrency(totalCost)}

Conditions de règlement : 30% à la commande, solde à la livraison.

Validité : Ce devis est valable 3 mois à compter de la date ci-dessus.

Engagement : Ce document constitue une proposition commerciale. L'engagement est pris après signature du "Bon pour accord".

Mentions légales : TVA non applicable selon le régime fiscal. Fournitures et documents offerts gratuitement.

${notes ? `
Notes:
${sanitizeHTML(notes)}
`:''}
Bon pour accord
Nom et signature du client :

${CONFIG.company.name} - ${this.state.template.footer}

NINEA: ${CONFIG.company.ninea} | ${CONFIG.company.website}

`; this.elements.documentPreview.innerHTML=previewHTML; } this.elements.generateQuoteBtn.addEventListener("click", ()=> this.generateQuote()); this.elements.previewQuoteBtn.addEventListener("click", ()=> this.previewQuote()); this.elements.quoteNumberInput.value=this.state.quoteNumber;