Correction erreurs, sécurisation code, personnalisation présentation (Jordan)
This commit is contained in:
parent
717fc5320f
commit
fffbfcac93
19 changed files with 822 additions and 471 deletions
|
|
@ -4,7 +4,7 @@ namespace Paheko\Plugin\Facturation;
|
|||
|
||||
use Paheko\DB;
|
||||
use Paheko\DynamicList;
|
||||
use Paheko\Entities\Plugin;
|
||||
use Paheko\Plugins;
|
||||
use Paheko\UserException;
|
||||
use Paheko\Utils;
|
||||
|
||||
|
|
@ -29,9 +29,12 @@ class Client
|
|||
|
||||
public function __construct()
|
||||
{
|
||||
$plugin = new Plugin('facturation');
|
||||
$this->config['unique_client_name'] = $plugin->getConfig('unique_client_name') ?: false;
|
||||
$this->config['validate_cp'] = $plugin->getConfig('validate_cp') ?: false;
|
||||
$plugin = Plugins::get('facturation');
|
||||
|
||||
if ($plugin) {
|
||||
$this->config['unique_client_name'] = (bool) $plugin->getConfig('unique_client_name');
|
||||
$this->config['validate_cp'] = (bool) ($plugin->getConfig('validate_cp') ?? true);
|
||||
}
|
||||
}
|
||||
|
||||
public function _checkFields(&$data)
|
||||
|
|
@ -102,8 +105,20 @@ class Client
|
|||
{
|
||||
$db = DB::getInstance();
|
||||
|
||||
return $db->first('SELECT *, strftime(\'%s\', date_creation) AS date_creation
|
||||
$client = $db->first('SELECT *, strftime(\'%s\', date_creation) AS date_creation
|
||||
FROM plugin_facturation_clients WHERE id = ? LIMIT 1;', (int)$id);
|
||||
|
||||
if (!$client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (['siret', 'telephone', 'email', 'nom_contact', 'note'] as $key) {
|
||||
if (!property_exists($client, $key)) {
|
||||
$client->$key = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
public function listAll()
|
||||
|
|
|
|||
111
lib/Facture.php
111
lib/Facture.php
|
|
@ -6,9 +6,10 @@ use DateTime;
|
|||
use Paheko\Config;
|
||||
use Paheko\DB;
|
||||
use Paheko\DynamicList;
|
||||
use Paheko\Plugins;
|
||||
use Paheko\UserException;
|
||||
use Paheko\Users\DynamicFields;
|
||||
use Paheko\Utils;
|
||||
use Paheko\Services\Services_User;
|
||||
|
||||
class Facture
|
||||
{
|
||||
|
|
@ -47,17 +48,52 @@ class Facture
|
|||
'accounts' => [],
|
||||
'label' => 'Facture',
|
||||
'help' => ''],
|
||||
CERFA => [
|
||||
'id' => CERFA,
|
||||
'accounts' => [],
|
||||
'label' => 'Reçu fiscal',
|
||||
'help' => 'Fonction historique conservée pour les anciens reçus. Le module Paheko "Reçus fiscaux" est recommandé pour les nouveaux usages.'],
|
||||
COTIS => [
|
||||
'id' => COTIS,
|
||||
'accounts' => [],
|
||||
'label' => 'Reçu de cotisation',
|
||||
'help' => 'Fonction historique conservée pour les anciens reçus. Le module Paheko "Reçu de paiement" est recommandé pour les nouveaux usages.'],
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
private function normalizeDate($value, string $field): string
|
||||
{
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
return $value->format('Y-m-d');
|
||||
}
|
||||
|
||||
$value = trim((string) $value);
|
||||
|
||||
foreach (['!Y-m-d', '!d/m/Y'] as $format) {
|
||||
$date = DateTime::createFromFormat($format, $value);
|
||||
$errors = DateTime::getLastErrors();
|
||||
|
||||
if ($date && (!$errors || (!$errors['warning_count'] && !$errors['error_count']))) {
|
||||
return $date->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
throw new UserException(sprintf('La date "%s" est invalide pour le champ %s.', $value, $field));
|
||||
}
|
||||
|
||||
// Fix : est dépendant de l'ordre des données dans l'array
|
||||
// et implique que toutes les données soient présentes (pas possible de faire un update partiel)
|
||||
public function _checkFields(&$datas)
|
||||
{
|
||||
$type_facture = isset($datas['type_facture']) ? (int) $datas['type_facture'] : null;
|
||||
$fac = in_array($type_facture, [DEVIS, FACT], true);
|
||||
$cerfa = $type_facture === CERFA;
|
||||
$recu = $type_facture === COTIS;
|
||||
$total = 0;
|
||||
|
||||
foreach($datas as $k=>$data)
|
||||
{
|
||||
if (!in_array($k, $this->keys))
|
||||
|
|
@ -76,24 +112,11 @@ class Facture
|
|||
switch($k)
|
||||
{
|
||||
case 'type_facture':
|
||||
if (!array_key_exists($datas[$k], $this->types)) {
|
||||
$datas[$k] = (int) $datas[$k];
|
||||
|
||||
if (!array_key_exists($datas[$k], self::TYPES_NAMES)) {
|
||||
throw new UserException("$k est de type non-attendue ($data).");
|
||||
}
|
||||
if ($datas[$k] < 2) {
|
||||
$fac = true;
|
||||
$cerfa = false;
|
||||
$recu = false;
|
||||
}
|
||||
elseif ($datas[$k] == 2) {
|
||||
$fac = false;
|
||||
$cerfa = true;
|
||||
$recu = false;
|
||||
}
|
||||
elseif ($datas[$k] == 3) {
|
||||
$fac = false;
|
||||
$cerfa = false;
|
||||
$recu = true;
|
||||
}
|
||||
break;
|
||||
case 'receveur_membre':
|
||||
case 'reglee':
|
||||
|
|
@ -108,11 +131,11 @@ class Facture
|
|||
}
|
||||
break;
|
||||
case 'date_emission':
|
||||
$datas[$k] = \DateTime::createFromFormat('!d/m/Y', $data)->format('Y-m-d');
|
||||
$datas[$k] = $this->normalizeDate($data, $k);
|
||||
break;
|
||||
case 'date_echeance':
|
||||
$datas[$k] = \DateTime::createFromFormat('!d/m/Y', $data)->format('Y-m-d');
|
||||
if (DateTime::createFromFormat('!Y-m-d', $datas[$k])->format('U') < DateTime::createFromFormat('!Y-m-d', $datas['date_emission'])->format('U'))
|
||||
$datas[$k] = $this->normalizeDate($data, $k);
|
||||
if (isset($datas['date_emission']) && DateTime::createFromFormat('!Y-m-d', $datas[$k])->format('U') < DateTime::createFromFormat('!Y-m-d', $datas['date_emission'])->format('U'))
|
||||
{
|
||||
throw new UserException("La date d'échéance est antérieure à la date d'émission ($data).");
|
||||
}
|
||||
|
|
@ -134,12 +157,12 @@ class Facture
|
|||
if (empty($r['designation']) && empty($r['prix']))
|
||||
{
|
||||
unset($datas[$k][$g]);
|
||||
unset($datas[$k]['prix']);
|
||||
continue;
|
||||
}
|
||||
elseif (! is_numeric($r['prix']) && empty($r['prix']))
|
||||
elseif (!isset($r['prix']) || $r['prix'] === '')
|
||||
{
|
||||
$datas[$k]['prix'] = 0;
|
||||
$datas[$k][$g]['prix'] = 0;
|
||||
$r['prix'] = 0;
|
||||
}
|
||||
elseif (empty($r['designation'])) {
|
||||
throw new UserException("Une au moins des désignations est absente.");
|
||||
|
|
@ -251,7 +274,7 @@ class Facture
|
|||
$type = ctype_digit($v) ? 'd' : 's';
|
||||
return sprintf('%' . $match[1] . $type, $v);
|
||||
}, $selpattern);
|
||||
$modele = '/^' . $prefixe . '\d+$/';
|
||||
$modele = '/^' . preg_quote($prefixe, '/') . '\d+$/';
|
||||
$numeros_filtres = array_filter($numeros, function($elem) use ($modele) {
|
||||
return preg_match($modele, $elem);
|
||||
}, 0);
|
||||
|
|
@ -292,6 +315,12 @@ class Facture
|
|||
$r->contenu = json_decode($r->contenu, true);
|
||||
}
|
||||
|
||||
foreach (['nom_contact', 'numero_commande', 'reference_acheteur'] as $key) {
|
||||
if (!property_exists($r, $key)) {
|
||||
$r->$key = null;
|
||||
}
|
||||
}
|
||||
|
||||
$r->date_emission = \DateTime::createFromFormat('!Y-m-d', $r->date_emission);
|
||||
if ($r->date_echeance)
|
||||
{
|
||||
|
|
@ -320,15 +349,19 @@ class Facture
|
|||
|
||||
public function list($all = true): DynamicList
|
||||
{
|
||||
$id_field = \Paheko\Users\DynamicFields::getNameFieldsSQL('u');
|
||||
$plugin_name = preg_replace('/^.*\/(\w+)\/$/', '${1}', \Paheko\PLUGIN_ADMIN_URL);
|
||||
$plugin = \Paheko\Plugins::get($plugin_name);
|
||||
$db = DB::getInstance();
|
||||
$id_field = DynamicFields::getNameFieldsSQL('u');
|
||||
$plugin = Plugins::get('facturation');
|
||||
$user_fields = DynamicFields::getInstance()->listAssocNames();
|
||||
|
||||
// adresse et ville peuvent être redéfinies dans la configuration du plugin
|
||||
$adresse_client = $plugin->getConfig('adresse_client');
|
||||
if ($adresse_client == null) { $adresse = 'u.adresse'; } else { $adresse = 'u.' . $adresse_client; }
|
||||
$ville_client = $plugin->getConfig('ville_client');
|
||||
if ($ville_client == null) { $ville = 'u.ville'; } else { $ville = 'u.' . $ville_client; }
|
||||
$adresse_client = $plugin ? $plugin->getConfig('adresse_client') : null;
|
||||
$adresse_client = $adresse_client ?: 'adresse';
|
||||
$adresse = array_key_exists($adresse_client, $user_fields) ? 'u.' . $db->quoteIdentifier($adresse_client) : 'NULL';
|
||||
|
||||
$ville_client = $plugin ? $plugin->getConfig('ville_client') : null;
|
||||
$ville_client = $ville_client ?: 'ville';
|
||||
$ville = array_key_exists($ville_client, $user_fields) ? 'u.' . $db->quoteIdentifier($ville_client) : 'NULL';
|
||||
|
||||
$columns = [
|
||||
// Sélectionner cette colonne, mais ne pas la mettre dans la liste des colonnes
|
||||
|
|
@ -357,7 +390,7 @@ class Facture
|
|||
'receveur' => [
|
||||
'label' => 'Receveur',
|
||||
// l'identité du membre peut être redéfinie dans la configuration des membres
|
||||
'select' => sprintf('CASE WHEN receveur_membre THEN CASE %s WHEN "" THEN "** ABSENT **" ELSE %s END ELSE c.nom END', $id_field, $id_field),
|
||||
'select' => sprintf('CASE WHEN receveur_membre THEN COALESCE(NULLIF(%s, \'\'), \'** ABSENT **\') ELSE c.nom END', $id_field),
|
||||
],
|
||||
'receveur_adresse' => [
|
||||
// l'adresse peut être redéfinie dans la configuration du plugin
|
||||
|
|
@ -393,7 +426,7 @@ class Facture
|
|||
|
||||
$tables = 'plugin_facturation_factures AS f
|
||||
INNER JOIN plugin_facturation_paiement AS mp ON mp.code = f.moyen_paiement
|
||||
LEFT JOIN users AS u ON f.receveur_membre = 1 AND u.id = f.receveur_id
|
||||
LEFT JOIN users_view AS u ON f.receveur_membre = 1 AND u.id = f.receveur_id
|
||||
LEFT JOIN plugin_facturation_clients AS c ON f.receveur_membre = 0 AND c.id = f.receveur_id';
|
||||
|
||||
if ($all) {
|
||||
|
|
@ -404,7 +437,7 @@ class Facture
|
|||
$list = new DynamicList($columns, $tables, $where);
|
||||
$list->orderBy('date_emission', true);
|
||||
|
||||
$currency = Config::getInstance()->monnaie;
|
||||
$currency = Config::getInstance()->currency;
|
||||
|
||||
$list->setModifier(function ($row) use ($currency) {
|
||||
// Remplir la colonne virtuelle
|
||||
|
|
@ -460,7 +493,10 @@ class Facture
|
|||
}
|
||||
else // Si c'est un membre de l'asso
|
||||
{
|
||||
throw new UserException("Woopsie, g pô encore implémenté l'usage des users de l'asso comme clients");
|
||||
if (!\Paheko\Users\Users::exists((int) $id))
|
||||
{
|
||||
throw new UserException("Ce membre n'existe pas.");
|
||||
}
|
||||
}
|
||||
|
||||
$r = (array)DB::getInstance()->get('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
|
||||
|
|
@ -492,7 +528,10 @@ class Facture
|
|||
}
|
||||
else // Si c'est un membre de l'asso
|
||||
{
|
||||
throw new UserException("Woopsie, g pô encore implémenté l'usage des users de l'asso comme clients");
|
||||
if (!\Paheko\Users\Users::exists((int) $id))
|
||||
{
|
||||
throw new UserException("Ce membre n'existe pas.");
|
||||
}
|
||||
}
|
||||
|
||||
return DB::getInstance()->test('plugin_facturation_factures', 'receveur_membre = ? AND receveur_id = ?', $base, $id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue