2019-11-02 17:53:27 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Garradin\Plugin\Facturation;
|
|
|
|
|
|
|
|
use Garradin\DB;
|
|
|
|
use Garradin\UserException;
|
|
|
|
|
|
|
|
class Facture
|
|
|
|
{
|
|
|
|
private $keys = [
|
2020-10-24 03:22:22 +02:00
|
|
|
'type_facture', // 0 : devis, 1 : facture, 2 : reçu cerfa, 3 : reçu cotis
|
2019-11-02 17:53:27 +01:00
|
|
|
'numero',
|
|
|
|
'receveur_membre',
|
|
|
|
'receveur_id',
|
2020-10-24 05:40:42 +02:00
|
|
|
'date_emission', // Reçus : date du don
|
|
|
|
'date_echeance', // Reçus : date d'édition du reçu
|
2019-11-02 17:53:27 +01:00
|
|
|
'reglee',
|
|
|
|
'archivee',
|
|
|
|
'moyen_paiement',
|
|
|
|
'contenu',
|
|
|
|
'total'
|
|
|
|
];
|
|
|
|
|
2020-10-24 05:40:42 +02:00
|
|
|
public $type = [
|
|
|
|
0 => 'devis',
|
|
|
|
1 => 'facture',
|
|
|
|
2 => 'cerfa',
|
|
|
|
3 => 'cotis',
|
|
|
|
];
|
|
|
|
|
2019-11-02 17:53:27 +01:00
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-10-24 05:40:42 +02:00
|
|
|
// Wsh je sais que data c invariable, laissez-moi tranquille jsp comment faire sinon
|
2019-11-02 17:53:27 +01:00
|
|
|
public function _checkFields(&$datas)
|
|
|
|
{
|
|
|
|
foreach($datas as $k=>$data)
|
|
|
|
{
|
|
|
|
if (!in_array($k, $this->keys))
|
|
|
|
{
|
|
|
|
throw new UserException("Clé inattendue : $k.");
|
|
|
|
}
|
2019-11-03 17:51:31 +01:00
|
|
|
|
2019-11-02 17:53:27 +01:00
|
|
|
if(!is_array($data)){
|
|
|
|
$datas[$k] = trim($data);
|
|
|
|
}
|
|
|
|
if ($datas[$k] === '')
|
|
|
|
{
|
|
|
|
throw new UserException("La valeur de $k est vide");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch($k)
|
|
|
|
{
|
2020-10-24 05:40:42 +02:00
|
|
|
case 'type_facture':
|
2020-10-24 07:04:06 +02:00
|
|
|
if (!array_key_exists($datas[$k], $this->type)) {
|
2020-10-24 05:40:42 +02:00
|
|
|
throw new UserException("$k est de type non-attendue ($data).");
|
|
|
|
}
|
2020-10-24 22:06:16 +02:00
|
|
|
if ($datas[$k] < 2) {
|
|
|
|
$fac = true;
|
|
|
|
$cerfa = false;
|
|
|
|
$recu = false;
|
2020-10-24 07:04:06 +02:00
|
|
|
}
|
2020-10-24 22:06:16 +02:00
|
|
|
elseif ($datas[$k] == 2) {
|
|
|
|
$fac = false;
|
|
|
|
$cerfa = true;
|
2020-10-24 07:04:06 +02:00
|
|
|
$recu = false;
|
|
|
|
}
|
2020-10-24 22:06:16 +02:00
|
|
|
elseif ($datas[$k] == 3) {
|
|
|
|
$fac = false;
|
|
|
|
$cerfa = false;
|
|
|
|
$recu = true;
|
|
|
|
}
|
2020-10-24 05:40:42 +02:00
|
|
|
break;
|
|
|
|
case 'receveur_membre':
|
|
|
|
case 'reglee':
|
|
|
|
case 'archivee':
|
2020-10-24 07:04:06 +02:00
|
|
|
if ($datas[$k] != 1 && $datas[$k] != 0) {
|
2020-10-24 05:40:42 +02:00
|
|
|
throw new UserException("$k est de valeur non-attendue ($data).");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
break;
|
2020-03-22 06:24:13 +01:00
|
|
|
case 'receveur_id':
|
|
|
|
if (!is_numeric($datas[$k]) || $datas[$k] < 0) {
|
|
|
|
throw new UserException("L'id du receveur est non-attendu ($data).");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
break;
|
2020-03-22 06:24:13 +01:00
|
|
|
case 'date_emission':
|
|
|
|
if (!strtotime($datas[$k])) {
|
|
|
|
throw new UserException("La date d'émission est non-attendue ($data).");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
break;
|
2020-03-22 06:24:13 +01:00
|
|
|
case 'date_echeance':
|
|
|
|
if (!strtotime($datas[$k])) {
|
|
|
|
throw new UserException("La date d'émission est non-attendue ($data).");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
2020-10-24 05:40:42 +02:00
|
|
|
if (isset($datas['date_emission']) && (strtotime($datas[$k]) < strtotime($datas['date_emission']))) {
|
|
|
|
throw new UserException("La date d'échéance est antérieure à la date d'émission ($data).");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
break;
|
2020-03-22 06:24:13 +01:00
|
|
|
case 'moyen_paiement':
|
|
|
|
$cats = new \Garradin\Compta\Categories;
|
|
|
|
if (!array_key_exists($datas[$k], $cats->listMoyensPaiement())) {
|
|
|
|
throw new UserException("Le moyen de paiement ne correspond pas à la liste interne ($data).");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
unset($cats);
|
|
|
|
break;
|
2020-03-22 06:24:13 +01:00
|
|
|
case 'contenu':
|
2020-10-24 22:06:16 +02:00
|
|
|
if ($fac)
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
2020-10-24 22:06:16 +02:00
|
|
|
if (!is_array($datas[$k]) || empty($datas[$k])) {
|
|
|
|
throw new UserException("Le contenu du document est vide ($data).");
|
|
|
|
}
|
|
|
|
$total = 0;
|
|
|
|
$vide = 1;
|
|
|
|
foreach($datas[$k] as $g=>$r)
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
2020-10-24 22:06:16 +02:00
|
|
|
if ($r['designation'] !== '' && is_numeric($r['prix']))
|
|
|
|
{
|
|
|
|
$vide = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unset($datas[$k][$g]);
|
|
|
|
}
|
|
|
|
$total += $r['prix'];
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
2020-10-24 22:06:16 +02:00
|
|
|
if($fac && $vide)
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
2020-10-24 22:06:16 +02:00
|
|
|
throw new UserException("Toutes les désignations/prix sont vides.");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
}
|
2020-10-24 22:06:16 +02:00
|
|
|
elseif ($cerfa)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
elseif ($recu)
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
2020-10-24 22:06:16 +02:00
|
|
|
// $fields = ['id', 'intitule', 'date', 'expiration'];
|
|
|
|
// foreach ($datas[$k]as $)
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
2020-03-22 06:24:13 +01:00
|
|
|
$datas[$k] = json_encode($datas[$k]);
|
2019-11-02 17:53:27 +01:00
|
|
|
break;
|
2020-03-22 06:24:13 +01:00
|
|
|
case 'total':
|
2020-10-24 22:06:16 +02:00
|
|
|
if ($cerfa && $datas[$k] < 1) {
|
2020-10-24 07:28:31 +02:00
|
|
|
throw new UserException('Le total ne peut être inférieur à 1€ pour les reçus (bug encore non résolu).');
|
|
|
|
}
|
2020-10-24 22:06:16 +02:00
|
|
|
if ($fac && !isset($datas['contenu'])) {
|
2020-03-22 06:24:13 +01:00
|
|
|
throw new UserException("Pas de contenu fourni pour vérifier le total.");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
2020-10-24 22:06:16 +02:00
|
|
|
if ($fac && $total != $datas[$k])
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
|
|
|
throw new UserException("Les totaux sont différents ($total != $datas[$k].");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function add($data)
|
|
|
|
{
|
|
|
|
$db = DB::getInstance();
|
|
|
|
|
|
|
|
$this->_checkFields($data);
|
|
|
|
|
|
|
|
if(isset($data['numero']) && $db->test('plugin_facturation_factures', 'numero = ? COLLATE NOCASE', $data['numero']))
|
|
|
|
{
|
2020-10-24 05:40:42 +02:00
|
|
|
throw new UserException('Un document avec ce numéro existe déjà, hors le numéro doit être unique.');
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
$db->insert('plugin_facturation_factures', $data);
|
|
|
|
return $db->lastInsertRowId();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function get($id)
|
2019-11-03 17:51:31 +01:00
|
|
|
{
|
|
|
|
$db = DB::getInstance();
|
2019-11-02 17:53:27 +01:00
|
|
|
|
|
|
|
$r = $db->first('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
|
|
|
|
strftime(\'%s\', date_echeance) AS date_echeance
|
|
|
|
FROM plugin_facturation_factures WHERE id = ? LIMIT 1;', (int)$id);
|
|
|
|
|
|
|
|
if(!$r)
|
|
|
|
{
|
2020-10-24 05:40:42 +02:00
|
|
|
throw new UserException("Pas de document retournée avec cet id.");
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
2019-11-03 17:51:31 +01:00
|
|
|
|
2020-10-24 05:40:42 +02:00
|
|
|
if ($r->contenu)
|
|
|
|
{
|
|
|
|
$r->contenu = json_decode($r->contenu, true);
|
|
|
|
}
|
2019-11-02 17:53:27 +01:00
|
|
|
|
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function listAll()
|
|
|
|
{
|
|
|
|
$r = (array)DB::getInstance()->get('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
|
|
|
|
strftime(\'%s\', date_echeance) AS date_echeance
|
|
|
|
FROM plugin_facturation_factures');
|
2019-11-03 17:51:31 +01:00
|
|
|
|
2019-11-02 17:53:27 +01:00
|
|
|
foreach ($r as $e)
|
|
|
|
{
|
2020-10-24 05:40:42 +02:00
|
|
|
if($e->contenu)
|
|
|
|
{
|
|
|
|
$e->contenu = json_decode((string)$e->contenu, true);
|
|
|
|
}
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function edit($id, $data = [])
|
|
|
|
{
|
|
|
|
$db = DB::getInstance();
|
|
|
|
|
|
|
|
$this->_checkFields($data);
|
|
|
|
|
|
|
|
if(isset($data['numero']) && $db->test('plugin_facturation_factures', 'numero = ? COLLATE NOCASE AND id != ?', $data['numero'], (int)$id))
|
|
|
|
{
|
2020-10-24 05:40:42 +02:00
|
|
|
throw new UserException('Un document avec ce numéro existe déjà, hors le numéro doit être unique.');
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
|
|
|
return $db->update('plugin_facturation_factures', $data, $db->where('id', (int)$id));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function listUserDoc($base = 0, $id)
|
|
|
|
{
|
|
|
|
$client = new Client;
|
|
|
|
|
2020-10-24 05:40:42 +02:00
|
|
|
if ($base == 0) // Si c'est un client
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
|
|
|
if(!$client->get($id))
|
|
|
|
{
|
|
|
|
throw new UserException("Ce client n'existe pas.");
|
|
|
|
}
|
|
|
|
}
|
2020-10-24 05:40:42 +02:00
|
|
|
else // Si c'est un membre de l'asso
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
|
|
|
throw new UserException("Woopsie, g pô encore implémenté l'usage des membres de l'asso comme clients");
|
|
|
|
}
|
|
|
|
|
|
|
|
$r = (array)DB::getInstance()->get('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
|
2019-11-03 17:51:31 +01:00
|
|
|
strftime(\'%s\', date_echeance) AS date_echeance
|
|
|
|
FROM plugin_facturation_factures
|
|
|
|
WHERE receveur_membre = ? AND receveur_id = ?', (int)$base, (int)$id);
|
2019-11-02 17:53:27 +01:00
|
|
|
|
|
|
|
foreach ($r as $e)
|
|
|
|
{
|
2020-10-24 05:40:42 +02:00
|
|
|
if ($e->contenu)
|
|
|
|
{
|
|
|
|
$e->contenu = json_decode((string)$e->contenu, true);
|
|
|
|
}
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|
2019-11-03 17:51:31 +01:00
|
|
|
|
2019-11-02 17:53:27 +01:00
|
|
|
return empty($r)?false:$r;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasDocs($base = 0, $id)
|
|
|
|
{
|
|
|
|
$client = new Client;
|
|
|
|
|
2020-10-24 05:40:42 +02:00
|
|
|
if ($base == 0) // Si c'est un client
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
|
|
|
if(!$client->get($id))
|
|
|
|
{
|
|
|
|
throw new UserException("Ce client n'existe pas.");
|
|
|
|
}
|
|
|
|
}
|
2020-10-24 05:40:42 +02:00
|
|
|
else // Si c'est un membre de l'asso
|
2019-11-02 17:53:27 +01:00
|
|
|
{
|
|
|
|
throw new UserException("Woopsie, g pô encore implémenté l'usage des membres de l'asso comme clients");
|
|
|
|
}
|
|
|
|
|
|
|
|
return DB::getInstance()->test('plugin_facturation_factures', 'receveur_membre = '. $base .' AND receveur_id = '. $id);
|
|
|
|
}
|
|
|
|
|
2020-10-24 22:06:16 +02:00
|
|
|
// ** Pour type reçu **
|
|
|
|
|
|
|
|
public $recu_fields = ['id', 'intitule', 'montant', 'date', 'expiration'];
|
|
|
|
|
|
|
|
public function getCotis($membre_id = 1)
|
|
|
|
{
|
|
|
|
// C un peu overkill nn?
|
|
|
|
// Copié/modifié de Membres\Cotisations::listSubscriptionsForMember($id)
|
|
|
|
$db = DB::getInstance();
|
|
|
|
return $db->get('SELECT cm.id, c.intitule, strftime(\'%s\', c.debut) AS debut, strftime(\'%s\', c.fin) AS fin, c.montant, strftime(\'%s\', cm.date) AS date,
|
|
|
|
CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\') >= date()
|
|
|
|
WHEN c.fin IS NOT NULL THEN (cm.id IS NOT NULL AND cm.date <= c.fin AND cm.date >= c.debut)
|
|
|
|
WHEN cm.id IS NOT NULL THEN 1 ELSE 0 END AS a_jour,
|
|
|
|
strftime(\'%s\', CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\')
|
|
|
|
WHEN c.fin IS NOT NULL THEN c.fin ELSE 1 END ) AS expiration,
|
|
|
|
(julianday(date()) - julianday(CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\')
|
|
|
|
WHEN c.fin IS NOT NULL THEN c.fin END)) AS nb_jours
|
|
|
|
FROM cotisations_membres AS cm
|
|
|
|
INNER JOIN cotisations AS c ON c.id = cm.id_cotisation
|
|
|
|
WHERE cm.id_membre = ?
|
|
|
|
AND ((c.fin IS NOT NULL AND cm.date <= c.fin AND cm.date >= c.debut) OR c.fin IS NULL)
|
|
|
|
GROUP BY cm.id_cotisation
|
|
|
|
ORDER BY cm.date DESC;', (int)$membre_id);
|
|
|
|
}
|
2019-11-02 17:53:27 +01:00
|
|
|
}
|