facturation/lib/Facture.php
2020-10-24 07:28:31 +02:00

257 lines
6.3 KiB
PHP

<?php
namespace Garradin\Plugin\Facturation;
use Garradin\DB;
use Garradin\UserException;
class Facture
{
private $keys = [
'type_facture', // 0 : devis, 1 : facture, 2 : reçu cerfa, 3 : reçu cotis
'numero',
'receveur_membre',
'receveur_id',
'date_emission', // Reçus : date du don
'date_echeance', // Reçus : date d'édition du reçu
'reglee',
'archivee',
'moyen_paiement',
'contenu',
'total'
];
public $type = [
0 => 'devis',
1 => 'facture',
2 => 'cerfa',
3 => 'cotis',
];
public function __construct()
{
}
// Wsh je sais que data c invariable, laissez-moi tranquille jsp comment faire sinon
public function _checkFields(&$datas)
{
foreach($datas as $k=>$data)
{
if (!in_array($k, $this->keys))
{
throw new UserException("Clé inattendue : $k.");
}
if(!is_array($data)){
$datas[$k] = trim($data);
}
if ($datas[$k] === '')
{
throw new UserException("La valeur de $k est vide");
}
switch($k)
{
case 'type_facture':
if (!array_key_exists($datas[$k], $this->type)) {
throw new UserException("$k est de type non-attendue ($data).");
}
if ($datas[$k] > 1) {
$recu = true;
}
else {
$recu = false;
}
break;
case 'receveur_membre':
case 'reglee':
case 'archivee':
if ($datas[$k] != 1 && $datas[$k] != 0) {
throw new UserException("$k est de valeur non-attendue ($data).");
}
break;
case 'receveur_id':
if (!is_numeric($datas[$k]) || $datas[$k] < 0) {
throw new UserException("L'id du receveur est non-attendu ($data).");
}
break;
case 'date_emission':
if (!strtotime($datas[$k])) {
throw new UserException("La date d'émission est non-attendue ($data).");
}
break;
case 'date_echeance':
if (!strtotime($datas[$k])) {
throw new UserException("La date d'émission est non-attendue ($data).");
}
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).");
}
break;
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).");
}
unset($cats);
break;
case 'contenu':
if (!$recu && (!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)
{
if ($r['designation'] !== '' && is_numeric($r['prix']))
{
$vide = 0;
}
else
{
unset($datas[$k][$g]);
}
$total += $r['prix'];
}
if(!$recu && $vide)
{
throw new UserException("Toutes les désignations/prix sont vides.");
}
$datas[$k] = json_encode($datas[$k]);
break;
case 'total':
if ($recu && $datas[$k] < 1) {
throw new UserException('Le total ne peut être inférieur à 1€ pour les reçus (bug encore non résolu).');
}
if (!$recu && !isset($datas['contenu'])) {
throw new UserException("Pas de contenu fourni pour vérifier le total.");
}
if ($total != $datas[$k])
{
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']))
{
throw new UserException('Un document avec ce numéro existe déjà, hors le numéro doit être unique.');
}
$db->insert('plugin_facturation_factures', $data);
return $db->lastInsertRowId();
}
public function get($id)
{
$db = DB::getInstance();
$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)
{
throw new UserException("Pas de document retournée avec cet id.");
}
if ($r->contenu)
{
$r->contenu = json_decode($r->contenu, true);
}
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');
foreach ($r as $e)
{
if($e->contenu)
{
$e->contenu = json_decode((string)$e->contenu, true);
}
}
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))
{
throw new UserException('Un document avec ce numéro existe déjà, hors le numéro doit être unique.');
}
return $db->update('plugin_facturation_factures', $data, $db->where('id', (int)$id));
}
public function listUserDoc($base = 0, $id)
{
$client = new Client;
if ($base == 0) // Si c'est un client
{
if(!$client->get($id))
{
throw new UserException("Ce client n'existe pas.");
}
}
else // Si c'est un membre de l'asso
{
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,
strftime(\'%s\', date_echeance) AS date_echeance
FROM plugin_facturation_factures
WHERE receveur_membre = ? AND receveur_id = ?', (int)$base, (int)$id);
foreach ($r as $e)
{
if ($e->contenu)
{
$e->contenu = json_decode((string)$e->contenu, true);
}
}
return empty($r)?false:$r;
}
public function hasDocs($base = 0, $id)
{
$client = new Client;
if ($base == 0) // Si c'est un client
{
if(!$client->get($id))
{
throw new UserException("Ce client n'existe pas.");
}
}
else // Si c'est un membre de l'asso
{
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);
}
}