Files
aduzuki/controllers/donController.js
2026-07-20 16:33:04 +02:00

399 lines
16 KiB
JavaScript

/////////////////////////////////////////////////
// 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 = `<p>Bonjour,</p><br><p>Nous vous remercions chaleureusement pour votre don de ${result_sql_select[0].montant}€ à l'Association Française pour le Pédagogie Suzuki.</p><br><p>Veuillez trouver le justificatif en pièce jointe.</p><br><p>Association Française pour la pédagogie Suzuki<br>Chez Anne PAGES<br>30 rue des Tattes<br>74500 PUBLIER</p>`;
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
}