///////////////////////////////////////////////// // APPELS DES MODULES ///////////////////////////////////////////////// const moment = require('moment'); const ejs = require('ejs'); const nodemailer = require('nodemailer'); const path = require("path"); const stripe = require('stripe')(process.env.STRIPE_PRIVATE_KEY); const pdf = require("pdf-creator-node"); const fs = require("fs"); const mysql = require('mysql2'); const mysql_promise = require('mysql2/promise'); // Weasyprint const weasyprint = require("htmltopdf-weasyprint"); ///////////////////////////////////////////////// // APPELS DES MODULES PERSOS ///////////////////////////////////////////////// // loggings const logger = require("../public/js/app/logger_wuzuki"); // Envoie mail const envoie_mail = require("../modules/envoie_mail"); // DB const { connect_DB_promise } = require('../modules/db/databaseconnect'); const { generateInsertSQL, extractValues } = require('../modules/db/sqlqueries'); ///////////////////////////////////////////////// // APPELS DES FONCTIONS ///////////////////////////////////////////////// // FAIRE UNE PAUSE const sleep = require("./../modules/sleep"); //////////////////////////////////////////////////// // FILE NAME //////////////////////////////////////////////////// const filename = path.parse(__filename).base; ///////////////////////////////////////////////// // GOOGLE SHEET PARAMETERS ///////////////////////////////////////////////// const { GoogleSpreadsheet } = require('google-spreadsheet'); const GS_creds = require('../inscriptionsafps-53b60452f63d.json'); const { error } = require("console"); // Initialize the sheet - doc ID is the long id in the sheets URL const GS_don = new GoogleSpreadsheet(process.env.gsheet_don); ///////////////////////////////////////////////// // VARIABLES GLOBALES ///////////////////////////////////////////////// ///////////////////////////////////////////////// // ENREGISTREMENT DES INFORMATIONS SAISIES // ENVOIE VERS STRIPE POUR PAIEMENT ///////////////////////////////////////////////// const post_form_don = async function(req, res){ logger.info("======================================"); logger.info("======== FUNCTION post_form_don =========="); logger.info("======================================"); ///////////////////////////////////////////////// // RÉCUPÉRATION DES DONNÉES DU FORMULAIRE DANS LA SESSION EN COURS et dans la tableau DATA ///////////////////////////////////////////////// // un tableau : pour récupérer en même temps les informations saisies dans un tableau let data = []; // Boucle sur les noms des champs // ajout des infos dans le tablea ['montant', 'nom', 'prenom', 'adresse_rue', 'adresse_complement', 'adresse_codepostal', 'adresse_ville', 'adresse_pays', 'mail', 'telephone_mobile', 'commentaire'].forEach(field => { req.session[field] = req.body[field]; data.push({[field] : req.body[field]}); logger.info("#0" + field + " = " + req.body[field], { numsession: req.session.id, label: filename}); }); console.log("data = ", data); ///////////////////////////////////////////////// // AJOUT DANS LA BASE DE DONNÉES ///////////////////////////////////////////////// try { //Connexion let db_connection_promise = await connect_DB_promise(); // AJOUT DON if (req.session.montant) { let table = "don"; // Fusionner les objets du tableau "data" qui contient les infos saisis dans le formulaire en un seul objet pour pouvoir le traiter dans la fonction "generateInsertSQL" const mergedData = Object.assign({}, ...data); console.log("mergedData = ", mergedData); // Appel de la fonction qui génère la requête SQL const sql = generateInsertSQL(table, mergedData); console.log("sql = ", sql); const values = extractValues(mergedData); console.log("values = ", values); // lancement de la requête const [result_sql, fields] = await db_connection_promise.execute(sql, values); logger.info("#1 result_sql Row ID added : " + result_sql.insertId, { numsession: req.session.id, label: filename}); ///////////////////////////////////////////////// // ENVOIE VERS STRIPE logger.info("======== ENVOIE VERS STRIPE ==========", { label: filename }); // STRIPE - ETAPE 1 - CREER l'INTENTION DE PAIEMENT const session_stripe = await stripe.checkout.sessions.create({ metadata: {app: "don", identifiant: result_sql.insertId, montant: req.session.montant, nom: req.session.nom +" "+ req.session.prenom}, customer_email: req.session.mail, mode: 'payment', success_url: process.env.STRIPE_DON_SUCCESSURL, cancel_url: process.env.STRIPE_DON_CANCELURL, line_items: [{ price_data: { currency: 'eur', unit_amount: req.session.montant * 100, product_data: { name: 'Don AFPS', description: 'DON AFPS depuis site AFPS', }, }, quantity: 1, }], success_url: process.env.STRIPE_DON_SUCCESSURL, cancel_url: process.env.STRIPE_DON_CANCELURL, }); res.redirect(session_stripe.url) } else { // Les informations saisies sont vides logger.info("Il y a un problème avec la saisie des informations du formulaire", { numsession: req.session.id }); req.session.affiche_err_1 = 'Il y a un problème avec la saisie des informations du formulaire, veuillez recommencer.'; res.redirect('/don'); } } catch (error) { // Echec de connection à la BD logger.error("Il y a un problème avec la connection à la base de données ou Stripe post_form_don : " + error, { numsession: req.session.id }); req.session.affiche_err_1 = '"Il y a un problème système connexion base de données, veuillez recommencer, "' + error; res.redirect('/don'); } } ///////////////////////////////////////////////// // RETOUR STRIPE ///////////////////////////////////////////////// const don_accompte_reussi = async function(req, res) { logger.info("======================================"); logger.info("======== FUNCTION don_accompte_reussi =========="); logger.info("======================================"); ////////////////////////////////////////////////////////////////////////////// // RETOUR STRIPE let id = req.query.id; const session_stripe = await stripe.checkout.sessions.retrieve(id); let customer_email = session_stripe.customer_email; let payment_status = session_stripe.payment_status; let amount_total = session_stripe.amount_total/100; let stripe_customer = session_stripe.customer; let stripe_payment_intent = session_stripe.payment_intent; let payment_method_types = session_stripe.payment_method_types; let stripe_status = session_stripe.status; console.log("payment_status = ", payment_status); console.log("stripe_customer = ", stripe_customer); console.log("stripe_payment_intent = ", stripe_payment_intent); console.log("payment_method_types = ", payment_method_types); console.log("stripe_status = ", stripe_status); ////////////////////////////////////////////////////////////////////////////// // PRÉPARATION PAGE PAIEMENT RÉUSSI moment.locale('fr'); let now = moment().format("YYYY-MM-DD HH:mm:ss"); res.locals.today = now; res.locals.montant = amount_total; res.locals.mail = customer_email; ////////////////////////////////////////////////////////////////////////////// // AFFICHAGE PAGE PAIEMENT RÉUSSI res.render('don/page_templates/don_paiement_reussi.ejs'); } ///////////////////////////////////////////////// // RETOUR STRIPE ///////////////////////////////////////////////// const don_accompte_annule = async function(req, res) { logger.info("======================================"); logger.info("======== FUNCTION don_accompte_annule =========="); logger.info("======================================"); ////////////////////////////////////////////////////////////////////////////// // RETOUR STRIPE let id = req.query.id; const session_stripe = await stripe.checkout.sessions.retrieve(id); let customer_email = session_stripe.customer_email; let payment_status = session_stripe.payment_status; let amount_total = session_stripe.amount_total/100; let stripe_customer = session_stripe.customer; let stripe_payment_intent = session_stripe.payment_intent; let payment_method_types = session_stripe.payment_method_types; let stripe_status = session_stripe.status; console.log("payment_status = ", payment_status); console.log("stripe_customer = ", stripe_customer); console.log("stripe_payment_intent = ", stripe_payment_intent); console.log("payment_method_types = ", payment_method_types); console.log("stripe_status = ", stripe_status); ////////////////////////////////////////////////////////////////////////////// // PRÉPARATION PAGE PAIEMENT RÉUSSI moment.locale('fr'); let now = moment().format("YYYY-MM-DD HH:mm:ss"); res.locals.today = now; res.locals.montant = amount_total; res.locals.mail = customer_email; ////////////////////////////////////////////////////////////////////////////// // AFFICHAGE PAGE PAIEMENT ANNULÉE res.render('don/page_templates/don_paiement_annule.ejs'); } ///////////////////////////////////////////////// // WEBHOOK STRIPE // BD STATUS PAIEMENT // ENVOIE PDF JUSTIFICATIF PAR MAIL // AJOUT DANS LA GOOGLE SHEET ///////////////////////////////////////////////// async function wh_stripe_don(req, res, event) { logger.info("======================================"); logger.info("======== FUNCTION wh_stripe_don =========="); logger.info("======================================"); moment.locale('fr'); let now = moment().format("DD/MM/YYYY"); let dateheure = moment().format("YYYY-MM-DDTHH-mm"); try { ///////////////////////////////////////////////// // MODIFICATION BD STATUS PAYMENT //Connexion DB let db_connection_promise = await connect_DB_promise(); // AJOUT STATUS PAIEMENT let table = "don"; let sql = 'UPDATE '; sql += table; sql += ' SET '; sql += 'stripe_retour = "' + event.data.object.id + '", '; sql += 'statut_paiement = "' + event.data.object.payment_status + '" '; sql += ' WHERE id = ' + event.data.object.metadata.identifiant; logger.info("#2 sql : " + sql, { numsession: req.session.id, label: filename}); // lancement de la requête const [result_sql, fields] = await db_connection_promise.execute(sql); logger.info("#2 result_sql Row ID changed : " + result_sql.changedRows, { numsession: req.session.id, label: filename}); ///////////////////////////////////////////////// // SI PAIEMENT RÉUSSI if (event.data.object.payment_status === "paid") { ///////////////////////////////////////////////// // RÉCUPÉRATION DES INFOS DE LA BASE DE DONNÉES let sql_select = 'SELECT * FROM '; sql_select += table; sql_select += ' WHERE id = ' + event.data.object.metadata.identifiant; logger.info("#3 sql_select : " + sql_select, { numsession: req.session.id, label: filename}); // lancement de la requête const [result_sql_select, fields_select] = await db_connection_promise.execute(sql_select); logger.info("REQUETE SQL - result_sql_select = " + result_sql_select.length, { numsession: req.session.id, label: filename}); logger.info("#3 result_sql_select nom : " + result_sql_select[0].nom, { numsession: req.session.id, label: filename}); ///////////////////////////////////////////////// // PDF JUSTIFICATIF DE DON const data = { nom: result_sql_select[0].nom + ' ' + result_sql_select[0].prenom, rue: result_sql_select[0].adresse_rue, complement: result_sql_select[0].adresse_complement, ville: result_sql_select[0].adresse_codepostal + ' ' + result_sql_select[0].adresse_ville, pays: result_sql_select[0].adresse_pays, montant: result_sql_select[0].montant, date: now }; const htmlContent = await ejs.renderFile('./pdf/template/don_wp.html', data); const buffer = await weasyprint(htmlContent); const pdfOutputPath = path.join(__dirname, `../pdf/don/don_${result_sql_select[0].nom}_${dateheure}.pdf`); fs.writeFileSync(pdfOutputPath, buffer); logger.info("PDF CREATED", { numsession: req.session.id, label: filename}); ///////////////////////////////////////////////// // ENVOIE MAIL CONFIRM + JUSTIF var attachment_name = `${result_sql_select[0].nom}_justificatif_don_AFPS_${dateheure}.pdf`; var mail_objet = `ASSOCIATION FRANÇAISE POUR LA PÉDAGOGIE SUZUKI - VOTRE DON - ${result_sql_select[0].nom}`; var mail_html = `

Bonjour,


Nous vous remercions chaleureusement pour votre don de ${result_sql_select[0].montant}€ à l'Association Française pour le Pédagogie Suzuki.


Veuillez trouver le justificatif en pièce jointe.


Association Française pour la pédagogie Suzuki
Chez Anne PAGES
30 rue des Tattes
74500 PUBLIER

`; var mailOptions = { from: 'afps.inscription@gmail.com', to: result_sql_select[0].mail, subject: mail_objet, html: mail_html, attachments: [{ filename: attachment_name, path: pdfOutputPath }], }; envoie_mail.envoie_mail(mailOptions); ///////////////////////////////////////////////// // AJOUT GOOGLE SHEET await GS_don.useServiceAccountAuth(GS_creds); await GS_don.loadInfo(); let GS_sheet_don = GS_don.sheetsByTitle['dons']; await GS_sheet_don.addRows ( [ { id: result_sql_select[0].id, date: result_sql_select[0].date_auto, montant: result_sql_select[0].montant, nom: result_sql_select[0].nom, prenom: result_sql_select[0].prenom, adresse_rue: result_sql_select[0].adresse_rue, adresse_complement: result_sql_select[0].adresse_complement, adresse_codepostal: result_sql_select[0].adresse_codepostal, adresse_ville: result_sql_select[0].adresse_ville, adresse_pays: result_sql_select[0].adresse_pays, mail: result_sql_select[0].mail, telephone_mobile: result_sql_select[0].telephone_mobile, commentaire: result_sql_select[0].commentaire, statut_paiement: result_sql_select[0].statut_paiement, stripe_retour: result_sql_select[0].stripe_retour } ] ); logger.info("AJOUT GOOGLESHEET FIN", { numsession: req.session.id, label: filename}); } } catch (error) { // Echec de connection à la BD logger.error("Il y a un problème avec wh_stripe_don : " + error, { numsession: req.session.id }); return res.status(400).send(`Webhook Error: ${error.message}`); } res.json({ received: true }); } ///////////////////////////////////////////////// // TEST WEASYPRINT ///////////////////////////////////////////////// async function test_weasyprint(req, res, event) { try { const htmlFilePath = path.join(__dirname, '../pdf/template/don_wp.html'); const htmlContent = fs.readFileSync(htmlFilePath, 'utf-8'); const buffer = await weasyprint(htmlContent); fs.writeFileSync("./pdf/don/output.pdf", buffer); logger.info("PDF CREATED", { numsession: req.session.id, label: filename}); } catch (error) { logger.error("Il y a un problème avec WeasyPrint : " + error, { numsession: req.session.id }); } } ///////////////////////////////////////////////// // EXPORT DE MODULE POUR QU'IL SOIT LU DANS LES AUTRES FICHIERS JS ///////////////////////////////////////////////// module.exports = { post_form_don, don_accompte_reussi, don_accompte_annule, wh_stripe_don, test_weasyprint }