diff --git a/lib/Personne.php b/lib/Personne.php new file mode 100644 index 0000000..d4ebf9e --- /dev/null +++ b/lib/Personne.php @@ -0,0 +1,52 @@ +id = $id; + $this->nomPrenom = $nomPrenom; + $this->adresse = $adresse; + $this->ville = $ville; + $this->codePostal = $codePostal; + $this->courriel = $courriel; + $this->versements = array(); + } + + /* + * ajouter un versement + */ + public function ajouterVersement( + $idActivite, + $idTarif, + $montant + ) { + // var_dump($this); + $this->versements[] = + new Versement( + $idActivite, + $idTarif, + $montant + ); + // var_dump($this); + } +} diff --git a/lib/RecusPDF.php b/lib/RecusPDF.php new file mode 100644 index 0000000..45984d1 --- /dev/null +++ b/lib/RecusPDF.php @@ -0,0 +1,174 @@ +AddFont($family, + '', + $family.$style.".ttf", + true); + // bold + $this->AddFont($family, + 'B', + $family.$style."-Bold.ttf", + true); + $this->nomAsso = $nomAsso; + $this->adresseAsso = $adresseAsso; + $this->logoCerfa = $logo; + $this->signature = $signature; + } + + // Header + function Header() + { + parent::Header(); + // Logo + $this->Image($this->logoCerfa, 10, 6, 30); + + // document title + $this->SetTextColor(0, 0, 0); + $this->SetFont('DejaVu','B',12); + $titre = "Reçu au titre des dons à certains organismes d'intérêt général"; + $this->SetXY(50, 10); + // Titre + $this->MultiCell(100, + 6, + $titre, + 0, + 'C'); + + // numéro de Cerfa + $cerfa = "N° 11580*3"; + $this->SetFont('DejaVu', 'B', 10); + $this->SetXY(10, 25); + $this->Cell(100, 0, $cerfa); + + // Articles + $this->SetFont('DejaVu', '', 9); + $this->SetXY(50, 25); + $this->Cell(100, 0, 'Article 200, 238 bis et 885-0 V bis A du code général des impôts'); + } + + // imprimer les informations du bénéficiaire + function imprimer_beneficiaire($nom, $adresse) + { + $this->titre_rubrique("Bénéficiaire des versements"); + $this->SetFont('DejaVu', 'B', 11); + $this->Cell(0, 6, 'Association « ' . $nom . ' »', 'LR', 1); + $this->Cell(0, 6, str_replace(array("\r\n", "\n", "\r"), " ", $adresse), 'LR', 1); + $this->imprimer_description("Objet : ", + "célébrer le culte protestant évangélique et pourvoir aux frais et besoins de ce culte."); + $this->Cell(0, 6, "", 'LRB', 1); + } + + // imprimer un libellé précédé de son titre en gras + function imprimer_description($titre, $libelle) + { + $this->SetFont('DejaVu', 'B', 11); + $this->Cell($this->GetStringWidth($titre), 6, $titre, 'L', 0); + $this->SetFont('DejaVu', '', 11); + $this->Cell(0, 6, $libelle, 'R', 1); + } + + function titre_rubrique($texte) + { + $this->SetFont('DejaVu','B',12); + $largeur_texte = $this->GetStringWidth($texte); + $this->setX(10); + $this->SetFillColor(0, 255, 255); + $this->Cell(0, 6, $texte, 'LTR', 1, 'C', true); + $this->Cell(0, 6, "", 'LR', 1); + } + + // imprimer le reçu + function imprimer_recu($annee_recu, + $numero, + $nom, + $lesMontants, + $adresse, + $ville, + $code_postal) + { + + $this->AddPage(); + // Numéro de reçu + $this->SetFont('DejaVu', 'B', 11); + $this->MultiCell(0, 20, 'Reçu numéro ' . $annee_recu . '/' . $numero); + + // bénéficiaire + $this->imprimer_beneficiaire($this->nomAsso, $this->adresseAsso); + + // donateur + $this->Ln(10); + $this->titre_rubrique("Donateur"); + $this->SetFont('DejaVu', 'B', 11); + $this->Cell(0, 6, $nom, 'LR', 1); + $this->Cell(0, 6, $adresse, 'LR', 1); + $this->Cell(0, 6, $code_postal . " " . $ville, 'LR', 1); + $this->Cell(0, 6, "", 'LRB', 1); + + // Montant et autres informations + $this->Ln(10); + $this->SetFont('DejaVu', '', 11); + $this->Cell(0, + 6, + "Le bénéficiaire reconnaît avoir reçu au titre des dons et versements ouvrant droit à réduction d'impôt", + 'LTR', + 1); + $this->Cell($this->GetStringWidth("la somme de "), + 6, + "la somme de ", + 'L', + 0); + $this->SetFont('DejaVu','B'); + foreach ($lesMontants as $montant) { + $this->Cell(0, + 6, + number_format($montant, 2, "," , "") . " euros.", + 'R', + 1); + } + $this->Cell(0, 3, "", 'LR', 1); + $this->imprimer_description('Date du versement ou du don : ', + 'année ' . $annee_recu); + $this->Cell(0, 3, "", 'LR', 1); + $this->MultiCell(0, 6, + "Le bénéficiaire certifie sur l’honneur que les dons et versements qu’il reçoit ouvrent droit à la réduction +d'impôt prévue à l’article 200 du CGI", + 'LR'); + $this->Cell(0, 3, "", 'LR', 1); + $this->imprimer_description("Forme du don : ", "Autre"); + $this->Cell(0, 3, "", 'LR', 1); + $this->imprimer_description("Nature du don : ", "Numéraire"); + $this->Cell(0, 3, "", 'LR', 1); + $this->imprimer_description("Mode de versement : ", "chèque et/ou virement"); + $this->Cell(0, 0, "", 'LRB', 1); + + // cartouche final + $this->Ln(10); + $this->Cell(0, 6, "", 'LRT', 1); + $this->Cell(0, 6, "Rennes le " . date("j/m/Y"), 'LR', 1, 'R'); + $this->Cell(0, 36, "", 'LR', 1); + $this->Cell(0, 0, "", 'LBR', 1); + $this->SetXY(100, 220); + $this->Image($this->signature, null, null, 50); + } +} // class RecusPDF diff --git a/lib/Services.php b/lib/Services.php new file mode 100644 index 0000000..d3f26d1 --- /dev/null +++ b/lib/Services.php @@ -0,0 +1,180 @@ +get( + "SELECT + id, + label, + description + FROM services + ORDER BY label" + ); + } + + /** + * @return liste des tarifs d'une activité + * @param $activite : identifiant de l'activité + */ + public static function getTarifs($activite) + { + return DB::getInstance()->get( + "SELECT + services_fees.id as idTarif, + services_fees.label as titreTarif, + services_fees.description as descTarif, + printf(\"%.2f\", services_fees.amount/100) as montantTarif + FROM services_fees + WHERE services_fees.id_service = ?", + $activite + ); + } + + /** + * @return liste de toutes les activités et tarifs + */ + public static function getActivitesEtTarifs() + { + return DB::getInstance()->get( + "SELECT + services.id as idService, + services.label as titreService, + services.description as descService, + services_fees.id as idTarif, + services_fees.label as titreTarif, + services_fees.description as descTarif + FROM services + LEFT JOIN services_fees ON services_fees.id_service = services.id + ORDER BY services.id, services_fees.id" + ); + } + + /** + * @return liste de toutes les activités, tarifs et comptes associés + */ + public static function getActivitesTarifsEtComptes() + { + return DB::getInstance()->get( + "SELECT + services.id as Id, + services.label, + services.description as descService, + services_fees.label as tarif, + services_fees.description as descTarif, + acc_accounts.code as numero_cpt, + acc_accounts.label as nom_cpt + FROM services + LEFT JOIN services_fees ON services_fees.id_service = services.id + LEFT JOIN acc_accounts ON services_fees.id_account = acc_accounts.id + ORDER BY services.label" + ); + } + + /** + * @return tous les versements de l'année + * @param $annee + */ + public static function getTousLesVersements($annee) + { + $sql = + "SELECT + services.id as idActivite, + services_fees.id as idTarif, + services.label as activite, + services_fees.label as tarif, + printf(\"%8.2f\", services_fees.amount/100) as montant, + acc_transactions_users.id_user as idUser, + printf(\"%8.2f\", acc_transactions_lines.credit/100) as versement, + membres.id as idMembre, + membres.nom as nom, + membres.adresse as adresse, + membres.ville as ville, + membres.code_postal as codePostal, + membres.email as courriel, + acc_transactions.date as Date, + acc_transactions_users.id_transaction as idTrans + FROM acc_transactions_users + INNER JOIN membres on acc_transactions_users.id_user = membres.id + INNER JOIN acc_transactions on acc_transactions_users.id_transaction = acc_transactions.id + INNER JOIN services_users on acc_transactions_users.id_service_user = services_users.id + INNER JOIN services on services_users.id_service = services.id + INNER JOIN services_fees on services_users.id_fee = services_fees.id + INNER JOIN acc_transactions_lines on acc_transactions_lines.id_transaction = acc_transactions.id + WHERE + (strftime(\"%Y\", acc_transactions.date) = ? + AND + acc_transactions_lines.credit > 0) + ORDER by services.id, services_fees.id, membres.nom, acc_transactions.date"; + return DB::getInstance()->get($sql, $annee); + } + + /** + * @return versements d'une année pour une activité et un tarif donnés + * @param $annee + * @param $activite + * @param $tarif + */ + public static function getVersementsActivite($annee, $activite, $tarif) + { + $sql = + "SELECT + services.id as idActivite, + services_fees.id as idTarif, + services.label as activite, + services_fees.label as tarif, + printf(\"%8.2f\", services_fees.amount/100) as montant, + acc_transactions_users.id_user as idUser, + printf(\"%8.2f\", acc_transactions_lines.credit/100) as versement, + membres.nom as nom, + acc_transactions.date as Date, + acc_transactions_users.id_transaction as idTrans + FROM acc_transactions_users + INNER JOIN membres on acc_transactions_users.id_user = membres.id + INNER JOIN acc_transactions on acc_transactions_users.id_transaction = acc_transactions.id + INNER JOIN services_users on acc_transactions_users.id_service_user = services_users.id + INNER JOIN services on services_users.id_service = services.id + INNER JOIN services_fees on services_users.id_fee = services_fees.id + INNER JOIN acc_transactions_lines on acc_transactions_lines.id_transaction = acc_transactions.id + WHERE + (strftime(\"%Y\", acc_transactions.date) = ? + AND + services.id = ? + AND + services_fees.id = ? + AND + acc_transactions_lines.credit > 0) + ORDER by membres.nom, acc_transactions.date"; + return DB::getInstance()->get($sql, $annee, $activite, $tarif); + } + + /** + * @return nom de l'association + */ + public static function getNomAsso() { + return DB::getInstance()->get( + "SELECT value + FROM config + WHERE key = 'nom_asso'" + )[0]->value; + } + + /** + * @return adresse de l'association + */ + public static function getAdresseAsso() { + return DB::getInstance()->get( + "SELECT value + FROM config + WHERE key = 'adresse_asso'" + )[0]->value; + } +} diff --git a/lib/Versement.php b/lib/Versement.php new file mode 100644 index 0000000..c5d0145 --- /dev/null +++ b/lib/Versement.php @@ -0,0 +1,20 @@ +idActivite = $idActivite; + $this->idTarif = $idTarif; + $this->montant = $montant; + } +} diff --git a/templates/index.tpl b/templates/index.tpl index 48fa22f..85ee2a8 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -27,7 +27,7 @@ {$activite.label} {$activite.descService} - {$activite.Tarif} + {$activite.tarif} {$activite.descTarif} {$activite.numero_cpt} {$activite.nom_cpt} @@ -82,7 +82,7 @@ {/if} {* Afficher les infos de la personne *} idTarif."_".$versement->idUser; ?> -

Versements de {$versement.Nom} : 0,00 €

+

Versements de {$versement.nom} : 0,00 €

-
+

- idUser; ?> + idUser; ?> {/if} {* afficher les infos du versement de la personne*}
@@ -104,8 +104,8 @@ value={$rang} onclick="cocherDecocherVersement(check_{$idVersements}_{$rang}, total_{$idVersements})" /> - {$versement.Versement} - {$versement.Date|date_format:"%d/%m/%Y"} + {$versement.versement} + {$versement.date|date_format:"%d/%m/%Y"}
{/if} {/foreach} {* Itération sur les versements *} @@ -113,6 +113,8 @@ {/foreach} {* Itération sur les tarifs de l'activité *} {/foreach} {* Itération sur les activités *} + + {* scripts pour cases à cocher *} diff --git a/www/admin/action.php b/www/admin/action.php new file mode 100644 index 0000000..b8b8ee9 --- /dev/null +++ b/www/admin/action.php @@ -0,0 +1,135 @@ + $ligne) { + $versementsSelectionnes[] = $_SESSION['lesVersements'][$ligne]; +} +// print_r($versementsSelectionnes); + +// cumuler les versements d'une personne +$totalPersonnes = cumulerVersements($versementsSelectionnes); +print_r($totalPersonnes); + +// générer les reçus +$nomAsso = Services::getNomAsso(); +$adresseAsso = Services::getAdresseAsso(); +// TODO +// - mémoriser numéro reçu pour pouvoir générer des reçus en plusieurs sessions indépendantes +// - paramétrer l'année fiscale +$num_recu = 1; +$annee_recu = "2021"; +// récupérer le logo CERFA (bôf) et la signature +// TODO : paramétrer le répertoire des images +$logoCERFA = PLUGIN_ROOT . "/data/logoCerfa.png"; +$signature = PLUGIN_ROOT . "/data/default_signature.png"; +$listeFichiers = []; + +foreach ($totalPersonnes as $idPersonne => $personne) { + // générer un fichier par reçu + $pdf = new RecusPDF( + 'DejaVu', + 'SerifCondensed', + $nomAsso, + $adresseAsso, + $logoCERFA, + $signature + ); + // extraire les montants des versements + $lesMontants = array(); + foreach ($personne->versements as $versement) { + $lesMontants[] = $versement->montant; + } + $pdf->imprimer_recu( + $annee_recu, + $num_recu, + $personne->nomPrenom, + $lesMontants, + $personne->adresse, + $personne->ville, + $personne->codePostal + ); + ++$num_recu; + // fabriquer le nom du fichier PDF + $nom = str_replace(' ', '_', $personne->nomPrenom); + $nom = str_replace("'", "", $nom); + // $nomFichier = Utils::getPDFDirectory() . "/" . 'recu_' . $annee_recu . '_' . $nom . '.pdf'; + $nomFichier = PLUGIN_ROOT . '/pdf/recu_' . $annee_recu . '_' . $nom . '.pdf'; + $pdf->Output('F', $nomFichier); + // ajouter le nom du fichier à la liste pour mettre dans une archive + $listeFichiers[] = $nomFichier; +} + +// faire une archive zip +/* +$fichierZip = Utils::makeArchive($listeFichiers, $annee_recu, Utils::getZipDirectory()); +$_SESSION['zipfile'] = $fichierZip; + +// afficher la page de téléchargement +$action = 'telecharger_archive'; +require('vue/vueTelechargerArchive.php'); +*/ + +/** + * Cumuler les versements de chaque pesonne par tarif et activité + * @param tableau des versements + * @return tableau des versements cumulés + */ +function cumulerVersements($versements) +{ + $totalPersonnes = array(); + $idActivite_courant = -1; + $idTarif_courant = -1; + $idPersonne_courant = -1; + $totalVersements = 0; + foreach ($versements as $ligne) { + if ( + $ligne->idActivite != $idActivite_courant || + $ligne->idTarif != $idTarif_courant || + $ligne->idUser != $idPersonne_courant + ) { + if ($idActivite_courant != -1) { + $totalPersonnes["$idPersonne_courant"]->ajouterVersement( + $idActivite_courant, + $idTarif_courant, + $totalVersements + ); + } + $idActivite_courant = $ligne->idActivite; + $idTarif_courant = $ligne->idTarif; + $idPersonne_courant = $ligne->idUser; + $totalVersements = $ligne->versement; + // créer les infos de la personne, sauf si elle est déjà présente + if (!array_key_exists($idPersonne_courant, $totalPersonnes)) { + $totalPersonnes["$idPersonne_courant"] = new Personne( + $ligne->idUser, + $ligne->nom, + $ligne->adresse, + $ligne->ville, + $ligne->codePostal, + $ligne->courriel + ); + } + } else { + // cumuler versements + $totalVersements += $ligne->versement; + } + } + // et le dernier + $totalPersonnes["$idPersonne_courant"]->ajouterVersement( + $idActivite_courant, + $idTarif_courant, + $totalVersements + ); + + return $totalPersonnes; +} \ No newline at end of file diff --git a/www/admin/index.php b/www/admin/index.php index 8c35315..eb07760 100644 --- a/www/admin/index.php +++ b/www/admin/index.php @@ -8,7 +8,7 @@ use Garradin\Plugin\RecusFiscaux\Services; $activitesTarifsComptes = Services::getActivitesTarifsEtComptes(); // liste des versements pour activités -$lesVersements = Services::getTousLesVersements("2021"); +$_SESSION['lesVersements'] = Services::getTousLesVersements("2021"); // liste des activités $activites = Services::getActivites(); @@ -20,7 +20,7 @@ foreach ($activites as $num => $activite) // préparation de l'affichage $tpl->assign('activitesTarifsComptes', $activitesTarifsComptes); -$tpl->assign('lesVersements', $lesVersements); +$tpl->assign('lesVersements', $_SESSION['lesVersements']); $tpl->assign('listeParActiviteEtTarif', $activites); $tpl->assign('plugin_css', ['style.css']); diff --git a/www/admin/script.js b/www/admin/script.js index d6bbd28..9821f82 100644 --- a/www/admin/script.js +++ b/www/admin/script.js @@ -61,6 +61,30 @@ function calculerTotal(listeCases, listeMontants, idTotal) { minimumFractionDigits: 2}); } +/** + * fonction appelée lors de la validation du formulaire + * @return vrai si au moins un choix a été fait + * @param : formulaire +*/ +function verifierChoix(formulaire) +{ + var listeCheck = formulaire.getElementsByTagName("input"); + var ok = false; + for (var i = 1; i < listeCheck.length; ++i) + { + if (listeCheck[i].checked) + { + ok = true; + break; + } + } + if (! ok) + { + alert("Erreur : il faut sélectionner au moins un versement"); + } + return ok; +} + /** * Cocher/décocher toutes les cases d'un tableau * en fonction de l'état de la première (ligne d'entête)