recusfiscaux/lib/Utils.php

444 lines
16 KiB
PHP

<?php
namespace Garradin\Plugin\RecusFiscaux;
use Garradin\DB;
use KD2\ZipWriter;
class Utils
{
/**
* @return tarifs demandés
* @param array $tarifs
*/
public static function getTarifs($tarifs)
{
$db = DB::getInstance();
$sql = sprintf(
'SELECT id, id_service as idActivite, label, description, amount as montant
FROM services_fees
WHERE services_fees.%s',
$db->where('id', $tarifs));
return $db->get($sql);
}
/**
* @return activités correspondant aux tarifs demandés
* @param array $tarifs
*/
public static function getActivites($tarifs)
{
$db = DB::getInstance();
$sql = sprintf(
'SELECT services.id, services.label, services.description
FROM services
LEFT JOIN services_fees ON services_fees.id_service = services.id
WHERE services_fees.%s
GROUP BY services.id',
$db->where('id', $tarifs));
return $db->get($sql);
}
/**
* @return versements correspondants à l'année donnée
* @param $annee
* @param array $champsNom : liste non vide des champs de nom/prénom
*/
public static function getVersementsPersonnes($annee, $champsNom)
{
$db = DB::getInstance();
$tri = Utils::combinerTri($champsNom);
$sql = sprintf(
'SELECT
membres.id as idUser,
acc_transactions_lines.credit as versement,
acc_transactions.date
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 acc_transactions_lines on acc_transactions_lines.id_transaction = acc_transactions.id
WHERE
(strftime(%s, acc_transactions.date) = "%d"
AND
acc_transactions_lines.credit > 0)
ORDER by %s, acc_transactions.date',
'"%Y"',
$annee,
$tri
);
return $db->get($sql);
}
/**
* @return versements correspondants à l'année et aux tarifs donnés
* triés par tarif, nom, date
* @param $annee
* @param array $tarifs
* @param array $champsNom : liste non vide des champs de nom/prénom
*/
public static function getVersementsTarifs($annee, $tarifs, $champsNom)
{
$db = DB::getInstance();
$tri = Utils::combinerTri($champsNom);
$sql = sprintf(
'SELECT
services_fees.id as idTarif,
membres.id as idUser,
acc_transactions_lines.credit as versement,
acc_transactions.date
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_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(%s, acc_transactions.date) = "%d"
AND
services_fees.%s
AND
acc_transactions_lines.credit > 0)
ORDER by services_fees.id, %s, acc_transactions.date',
'"%Y"',
$annee,
$db->where('id', $tarifs),
$tri
);
return $db->get($sql);
}
/**
* @return versements correspondants à l'année et aux comptes donnés
* @param $annee
* @param $op : opérateur de combinaison des comptes
* @param array $comptes
* @param array $champsNom : liste non vide des champs de nom/prénom
* exemples :
* op = 'in', comptes = ['706', '7780', '756']
* op = 'like', comptes = '7%'
*/
public static function getVersementsComptes($annee, $op, $comptes, $champsNom)
{
$db = DB::getInstance();
$tri = Utils::combinerTri($champsNom);
$sql = sprintf(
'SELECT
services_fees.id as idTarif,
acc_accounts.code as compte,
membres.id as idUser,
acc_transactions_lines.credit as versement,
acc_transactions.date
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_fees
ON services_users.id_fee = services_fees.id
INNER JOIN acc_transactions_lines
ON acc_transactions_lines.id_transaction = acc_transactions.id
INNER JOIN acc_accounts
ON acc_transactions_lines.id_account = acc_accounts.id
WHERE
(strftime(%s, acc_transactions.date) = "%d"
AND
acc_accounts.%s
AND
acc_transactions_lines.credit > 0)
ORDER by %s, acc_transactions.date',
'"%Y"',
$annee,
$db->where('code', $op, $comptes),
$tri
);
return $db->get($sql);
}
/**
* @return personnes ayant versé des dons pour une année donnée
* @param $annee
* @param array $champsNom : champs qui définissent le nom et le prénom d'une personne
*/
public static function getDonateurs($annee, $champsNom) : array
{
// concaténer les champs nom/prénoms pour la sélection
$nom = Utils::combinerChamps($champsNom);
// et pour le tri
$tri = Utils::combinerTri($champsNom);
$sql = sprintf(
'SELECT
membres.id as idUser,
row_number() over(order by %s) as rang,
%s as nom,
membres.adresse as adresse,
membres.code_postal as codePostal,
membres.ville as ville
FROM
acc_transactions_users,
membres,
acc_transactions
INNER JOIN acc_transactions_lines
ON acc_transactions_lines.id_transaction = acc_transactions.id
WHERE (
strftime(%s, acc_transactions.date) = "%d"
AND
acc_transactions_lines.credit > 0
AND
acc_transactions_users.id_transaction = acc_transactions.id
AND
acc_transactions_users.id_user = membres.id
)
GROUP by membres.id
ORDER by %1$s COLLATE U_NOCASE
',
$tri,
$nom,
'"%Y"',
$annee
);
// error_log("getDonateurs = " . print_r($sql, true));
$donateurs = array();
foreach (DB::getInstance()->iterate($sql) as $personne)
{
$donateurs[$personne->idUser] = new Personne($personne->idUser,
$personne->rang,
$personne->nom,
$personne->adresse,
$personne->codePostal,
$personne->ville);
}
return $donateurs;
}
/**
* combiner les champs avec un opérateur
* @param array $champs : liste (non vide) de champs
* @return chaîne combinée
*/
private static function combinerChamps($champs)
{
$op = ' || " " || ';
$result = 'ifnull(membres.' . $champs[0] . ', "")';
for ($i = 1; $i < count($champs); ++$i)
{
$result .= $op . 'ifnull(membres.' . $champs[$i] . ', "")';
}
return 'trim(' . $result . ')';
}
private static function combinerTri($champs)
{
$tri = 'membres.' . $champs[0];
for ($i = 1; $i < count($champs); ++$i)
{
$tri .= ', membres.' . $champs[$i];
}
return $tri;
}
/** OBSOLETE
* Versements totaux par personne pour une année donnée
* @param année
* @param array $champsNom : liste non vide des champs de nom/prénom
*/
public static function getVersementsTotaux($annee, $champsNom)
{
$tri = Utils::combinerTri($champsNom);
$sql = sprintf(
'SELECT
membres.id as idUser,
sum(acc_transactions_lines.credit) AS versement
FROM
acc_transactions_users,
membres,
acc_transactions
INNER JOIN acc_transactions_lines
ON acc_transactions_lines.id_transaction = acc_transactions.id
WHERE (
strftime(%s, acc_transactions.date) = "%d"
AND
acc_transactions_lines.credit > 0
AND
acc_transactions_users.id_transaction = acc_transactions.id
AND
acc_transactions_users.id_user = membres.id
)
GROUP by acc_transactions_users.id_user
ORDER by %s COLLATE U_NOCASE',
'"%Y"',
$annee,
$tri);
return DB::getInstance()->get($sql);
}
public static function getDonateurs_old($annee, $champsNom) : array
{
// concaténer les champs nom/prénoms pour la sélection
$nom = 'trim(' . Utils::combinerChamps($champsNom) . ') as nom,';
// et pour le tri
$tri = Utils::combinerTri($champsNom);
$sql =
"SELECT
membres.id as idUser,
" .
$nom . "
membres.adresse as adresse,
membres.code_postal as codePostal,
membres.ville as ville
FROM
acc_transactions_users,
membres,
acc_transactions
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
AND
acc_transactions_users.id_transaction = acc_transactions.id
AND
acc_transactions_users.id_user = membres.id
)
GROUP by membres.id
ORDER by " . $tri . " COLLATE U_NOCASE
";
$donateurs = array();
foreach (DB::getInstance()->iterate($sql, $annee) as $personne)
{
$donateurs[$personne->idUser] = new Personne($personne->idUser,
$personne->nom,
$personne->adresse,
$personne->codePostal,
$personne->ville);
}
return $donateurs;
}
public static function getLignesReduction($lesTaux)
{
foreach ($lesTaux as $elem)
{
$lignes[$elem->taux] = $elem->remarque;
}
return $lignes;
}
public static function getLigneReduction($taux)
{
return $_SESSION['ligneReduction'][$taux];
}
/**
* @return liste de toutes les activités, tarifs et comptes associés
*/
public static function getActivitesTarifsEtComptes()
{
return DB::getInstance()->get(
"SELECT
services.id as idActivite,
services.label as titreActivite,
services.description as descActivite,
services_fees.id as idTarif,
services_fees.label as titreTarif,
services_fees.description as descTarif,
acc_accounts.code as numeroCpt,
acc_accounts.label as nomCpt
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 liste des années fiscales
*/
public static function getAnneesFiscales() : array
{
$rows = DB::getInstance()->get(
"SELECT strftime('%Y', start_date) as annee
FROM acc_years
ORDER by start_date DESC"
);
$anneesFiscales = array();
foreach ($rows as $row) {
$anneesFiscales[] = $row->annee;
}
return $anneesFiscales;
}
/**
* récupérer dans la config du plugin les champs des membres
* utilisés pour le nom et le prénom ; ajouter/supprimer les
* modifications par rapport à la config garradin
* @return tableau des champs : clé = nom, valeur = { titre, position }
*/
public static function getChampsNom($config, $plugin) : array
{
// récupérer dans la config du plugin les champs mémorisés
// pour le nom et le prénom (le tableau est vide si pas mémorisé)
$champsNom = (array) $plugin->getConfig('champsNom');
// récupérer dans la config Garradin les champs des membres
// utilisés pour le nom et le préno
$champsGarradin = $config->get('champs_membres')->listAssocNames();
foreach ($champsGarradin as $name => $title)
{
if (stristr($title, 'nom'))
{
// retenir les champs dont le titre contient le terme 'nom'
// est-il présent dans la config du plugin ?
if (! array_key_exists($name, $champsNom))
{
// absent => l'ajouter
$champ = new \stdClass();
$champ->titre = $title;
$champ->position = 0;
$champsNom[$name] = $champ;
}
}
}
// opération symétrique : un champ mémorisé dans la config du
// plugin a-t-il disparu de la config garradin ?
foreach ($champsNom as $nom => $champ)
{
if (! array_key_exists($nom, $champsGarradin))
{
// absent => le supprimer
unset($champsNom[$nom]);
}
}
// mettre à jour la config du plugin
$plugin->setConfig('champsNom', $champsNom);
return $champsNom;
}
/**
* enregistrer les fichiers dans une archive zip
* @param $fileList : liste des fichiers à archiver
* @param $year : pour générer le nom de l'archive
* @param $archiveDir : ne sert plus
*/
static function makeArchive(
$fileList,
$year,
$archiveDir = null)
{
$zipFilename = "recus_dons" . $year . ".zip";
header('Content-type: application/zip');
header(sprintf('Content-Disposition: attachment; filename="%s"', $zipFilename));
$zip = new ZipWriter('php://output');
$zip->setCompression(0);
foreach ($fileList as $fileName)
{
$zip->add(basename($fileName), null, $fileName);
}
$zip->close();
} // makeArchive
}