/** * Vérification des champs fournis pour la modification de donnée * @param array $data Tableau contenant les champs à ajouter/modifier * @return void */ protected function _checkFields(&$data, $compta = false) { $db = DB::getInstance(); if (empty($data['date']) || !Utils::checkDate($data['date'])) { throw new UserException('Date vide ou invalide.'); } if (empty($data['id_cotisation']) || !$db->simpleQuerySingle('SELECT 1 FROM cotisations WHERE id = ?;', false, (int) $data['id_cotisation'])) { throw new UserException('Cotisation inconnue.'); } $data['id_cotisation'] = (int) $data['id_cotisation']; if (empty($data['id_membre']) || !$db->simpleQuerySingle('SELECT 1 FROM membres WHERE id = ?;', false, (int) $data['id_membre'])) { throw new UserException('Membre inconnu ou invalide.'); } $data['id_membre'] = (int) $data['id_membre']; if ($compta) { if (!isset($data['moyen_paiement']) || trim($data['moyen_paiement']) === '') { throw new UserException('Moyen de paiement inconnu ou invalide.'); } if ($data['moyen_paiement'] != 'ES') { if (trim($data['banque']) == '') { throw new UserException('Le compte bancaire choisi est invalide.'); } if (!$db->simpleQuerySingle('SELECT 1 FROM compta_comptes_bancaires WHERE id = ?;', false, $data['banque'])) { throw new UserException('Le compte bancaire choisi n\'existe pas.'); } } if (empty($data['montant']) || !is_numeric($data['montant'])) { throw new UserException('Le montant indiqué n\'est pas un nombre valide.'); } } }
/** * Clôturer un exercice et en ouvrir un nouveau * Le report à nouveau n'est pas effectué automatiquement par cette fonction, voir doReports pour ça. * @param integer $id ID de l'exercice à clôturer * @param string $end Date de clôture de l'exercice au format Y-m-d * @return integer L'ID du nouvel exercice créé */ public function close($id, $end) { $db = DB::getInstance(); if (!Utils::checkDate($end)) { throw new UserException('Date de fin vide ou invalide.'); } $db->exec('BEGIN;'); // Clôture de l'exercice $db->simpleUpdate('compta_exercices', ['cloture' => 1, 'fin' => $end], 'id = \'' . (int) $id . '\''); // Date de début du nouvel exercice : lendemain de la clôture du précédent exercice $new_begin = Utils::modifyDate($end, '+1 day'); // Date de fin du nouvel exercice : un an moins un jour après l'ouverture $new_end = Utils::modifyDate($new_begin, '+1 year -1 day'); // Enfin sauf s'il existe déjà des opérations après cette date, auquel cas la date de fin // est fixée à la date de la dernière opération, ceci pour ne pas avoir d'opération // orpheline d'exercice $last = $db->simpleQuerySingle('SELECT date FROM compta_journal WHERE id_exercice = ? AND date >= ? ORDER BY date DESC LIMIT 1;', false, $id, $new_end); $new_end = $last ?: $new_end; // Création du nouvel exercice $new_id = $this->add(['debut' => $new_begin, 'fin' => $new_end, 'libelle' => 'Nouvel exercice']); // Ré-attribution des opérations de l'exercice à clôturer qui ne sont pas dans son // intervale au nouvel exercice $db->simpleExec('UPDATE compta_journal SET id_exercice = ? WHERE id_exercice = ? AND date >= ?;', $new_id, $id, $new_begin); $db->exec('END;'); return $new_id; }
protected function _checkFields(&$data) { $db = DB::getInstance(); if (empty($data['libelle']) || !trim($data['libelle'])) { throw new UserException('Le libellé ne peut rester vide.'); } $data['libelle'] = trim($data['libelle']); if (!empty($data['moyen_paiement']) && !$db->simpleQuerySingle('SELECT 1 FROM compta_moyens_paiement WHERE code = ?;', false, $data['moyen_paiement'])) { throw new UserException('Moyen de paiement invalide.'); } if (empty($data['date']) || !Utils::checkDate($data['date'])) { throw new UserException('Date vide ou invalide.'); } if (!$db->simpleQuerySingle('SELECT 1 FROM compta_exercices WHERE cloture = 0 AND debut <= :date AND fin >= :date;', false, ['date' => $data['date']])) { throw new UserException('La date ne correspond pas à l\'exercice en cours.'); } if (empty($data['moyen_paiement'])) { $data['moyen_paiement'] = null; $data['numero_cheque'] = null; } else { $data['moyen_paiement'] = strtoupper($data['moyen_paiement']); if ($data['moyen_paiement'] != 'CH') { $data['numero_cheque'] = null; } if (!$db->simpleQuerySingle('SELECT 1 FROM compta_moyens_paiement WHERE code = ? LIMIT 1;', false, $data['moyen_paiement'])) { throw new UserException('Moyen de paiement invalide.'); } } $data['montant'] = str_replace(',', '.', $data['montant']); $data['montant'] = (double) $data['montant']; if ($data['montant'] <= 0) { throw new UserException('Le montant ne peut être égal ou inférieur à zéro.'); } foreach (['remarques', 'numero_piece', 'numero_cheque'] as $champ) { if (empty($data[$champ]) || !trim($data[$champ])) { $data[$champ] = ''; } else { $data[$champ] = trim($data[$champ]); } } if (!array_key_exists('compte_debit', $data) || !is_null($data['compte_debit']) && !$db->simpleQuerySingle('SELECT 1 FROM compta_comptes WHERE id = ?;', false, $data['compte_debit'])) { throw new UserException('Compte débité inconnu.'); } if (!array_key_exists('compte_credit', $data) || !is_null($data['compte_credit']) && !$db->simpleQuerySingle('SELECT 1 FROM compta_comptes WHERE id = ?;', false, $data['compte_credit'])) { throw new UserException('Compte crédité inconnu.'); } $data['compte_credit'] = is_null($data['compte_credit']) ? null : strtoupper(trim($data['compte_credit'])); $data['compte_debit'] = is_null($data['compte_debit']) ? null : strtoupper(trim($data['compte_debit'])); if ($data['compte_credit'] == $data['compte_debit']) { throw new UserException('Compte crédité identique au compte débité.'); } if (isset($data['id_categorie'])) { if (!$db->simpleQuerySingle('SELECT 1 FROM compta_categories WHERE id = ?;', false, (int) $data['id_categorie'])) { throw new UserException('Catégorie inconnue.'); } $data['id_categorie'] = (int) $data['id_categorie']; } else { $data['id_categorie'] = NULL; } if (isset($data['id_auteur'])) { $data['id_auteur'] = (int) $data['id_auteur']; } return true; }
public function fromCitizen($path) { if (!file_exists($path) || !is_readable($path)) { throw new \RuntimeException('Fichier inconnu : ' . $path); } $fp = fopen($path, 'r'); if (!$fp) { return false; } $db = DB::getInstance(); $db->exec('BEGIN;'); $comptes = new Comptes(); $banques = new Comptes_Bancaires(); $cats = new Categories(); $journal = new Journal(); $columns = []; $liste_comptes = $db->simpleStatementFetchAssoc('SELECT id, id FROM compta_comptes;'); $liste_cats = $db->simpleStatementFetchAssoc('SELECT intitule, id FROM compta_categories;'); $liste_moyens = $cats->listMoyensPaiement(); $get_compte = function ($compte, $intitule) use(&$liste_comptes, &$comptes, &$banques) { if (substr($compte, 0, 2) == '51') { $compte = '512' . substr($compte, -1); } // Création comptes if (!array_key_exists($compte, $liste_comptes)) { if (substr($compte, 0, 3) == '512') { $liste_comptes[$compte] = $banques->add(['libelle' => $intitule, 'banque' => 'Inconnue']); } else { $liste_comptes[$compte] = $comptes->add(['id' => $compte, 'libelle' => $intitule, 'parent' => substr($compte, 0, -1)]); } } return $compte; }; $col = function ($column) use(&$row, &$columns) { if (!isset($columns[$column])) { return null; } if (!isset($row[$columns[$column]])) { return null; } return $row[$columns[$column]]; }; $line = 0; $delim = Utils::find_csv_delim($fp); while (!feof($fp)) { $row = fgetcsv($fp, 4096, $delim); $line++; if (empty($row)) { continue; } if (empty($columns)) { $columns = $row; $columns = array_flip($columns); continue; } $date = $col('Date'); if (!preg_match('!^\\d{2}/\\d{2}/\\d{4}$!', $date)) { $db->exec('ROLLBACK;'); throw new UserException('Erreur sur la ligne ' . $line . ' : la date n\'est pas au format jj/mm/aaaa.'); } $date = explode('/', $date); $date = $date[2] . '-' . $date[1] . '-' . $date[0]; if ($db->simpleQuerySingle('SELECT 1 FROM compta_exercices WHERE (? < debut OR ? > fin) AND cloture = 0;', false, $date, $date)) { continue; } $debit = $get_compte($col('Compte débité - Numéro'), $col('Compte débité - Intitulé')); $credit = $get_compte($col('Compte crédité - Numéro'), $col('Compte crédité - Intitulé')); $cat = $col('Rubrique'); $moyen = strtoupper(substr($col('Moyen de paiement'), 0, 2)); if (!$moyen || !array_key_exists($moyen, $liste_moyens)) { $moyen = false; $cat = false; } if ($cat && !array_key_exists($cat, $liste_cats)) { if ($col('Nature') == 'Recette') { $type = $cats::RECETTES; $compte = $credit; } elseif ($col('Nature') == 'Dépense') { $type = $cats::DEPENSES; $compte = $debit; } else { $type = $cats::AUTRES; $cat = false; } if ($type != $cats::AUTRES) { $liste_cats[$cat] = $cats->add(['intitule' => $cat, 'type' => $type, 'compte' => $compte]); } } $data = ['libelle' => $col('Libellé'), 'montant' => $col('Montant'), 'date' => $date, 'compte_credit' => $credit, 'compte_debit' => $debit, 'numero_piece' => $col('Numéro de pièce'), 'remarques' => $col('Remarques')]; if ($cat) { $data['moyen_paiement'] = $moyen; $data['numero_cheque'] = $col('Numéro de chèque'); $data['id_categorie'] = $liste_cats[$cat]; } $journal->add($data); } $db->exec('END;'); fclose($fp); return true; }
protected function _checkBankFields(&$data) { if (empty($data['banque']) || !trim($data['banque'])) { throw new UserException('Le nom de la banque ne peut rester vide.'); } if (empty($data['bic'])) { $data['bic'] = ''; } else { $data['bic'] = trim(strtoupper($data['bic'])); $data['bic'] = preg_replace('![^\\dA-Z]!', '', $data['bic']); if (!Utils::checkBIC($data['bic'])) { throw new UserException('Code BIC/SWIFT invalide.'); } } if (empty($data['iban'])) { $data['iban'] = ''; } else { $data['iban'] = trim(strtoupper($data['iban'])); $data['iban'] = preg_replace('![^\\dA-Z]!', '', $data['iban']); if (!Utils::checkIBAN($data['iban'])) { throw new UserException('Code IBAN invalide.'); } } return true; }
/** * Importer un CSV de la liste des membres depuis un export Garradin * @param string $path Chemin vers le CSV * @return boolean TRUE en cas de succès */ public function fromCSV($path) { if (!file_exists($path) || !is_readable($path)) { throw new \RuntimeException('Fichier inconnu : ' . $path); } $fp = fopen($path, 'r'); if (!$fp) { return false; } $db = DB::getInstance(); $db->exec('BEGIN;'); $membres = new Membres(); // On récupère les champs qu'on peut importer $champs = Config::getInstance()->get('champs_membres')->getAll(); $champs = array_keys($champs); $champs[] = 'date_inscription'; //$champs[] = 'date_connexion'; $champs[] = 'id'; //$champs[] = 'id_categorie'; $line = 0; $delim = Utils::find_csv_delim($fp); while (!feof($fp)) { $row = fgetcsv($fp, 4096, $delim); $line++; if (empty($row)) { continue; } if ($line == 1) { if (is_numeric($row[0])) { throw new UserException('Erreur sur la ligne 1 : devrait contenir l\'en-tête des colonnes.'); } $columns = array_flip($row); continue; } if (count($row) != count($columns)) { $db->exec('ROLLBACK;'); throw new UserException('Erreur sur la ligne ' . $line . ' : le nombre de colonnes est incorrect.'); } $data = []; foreach ($columns as $name => $id) { $name = trim($name); // Champs qui n'existent pas dans le schéma actuel if (!in_array($name, $champs)) { continue; } if (trim($row[$id]) !== '') { $data[$name] = $row[$id]; } } if (!empty($data['id'])) { $id = (int) $data['id']; unset($data['id']); } else { $id = false; } try { if ($id) { $membres->edit($id, $data); } else { $membres->add($data); } } catch (UserException $e) { $db->exec('ROLLBACK;'); throw new UserException('Erreur sur la ligne ' . $line . ' : ' . $e->getMessage()); } } $db->exec('END;'); fclose($fp); return true; }
public function toString() { return Utils::write_ini_string($this->champs); }