8 * Vérification des champs fournis pour la modification de donnée
9 * @param array $data Tableau contenant les champs à ajouter/modifier
12 protected function _checkFields(&$data)
14 $db = DB
::getInstance();
16 if (empty($data['id_cotisation'])
17 ||
!$db->simpleQuerySingle('SELECT 1 FROM cotisations WHERE id = ?;', false, (int) $data['id_cotisation']))
19 throw new UserException('Cotisation inconnue.');
22 $data['id_cotisation'] = (int) $data['id_cotisation'];
24 if ((trim($data['delai']) === '') ||
!is_numeric($data['delai']))
26 throw new UserException('Délai avant rappel invalide : doit être indiqué en nombre de jours.');
29 $data['delai'] = (int) $data['delai'];
31 if (!isset($data['sujet']) ||
trim($data['sujet']) === '')
33 throw new UserException('Le sujet du rappel ne peut être vide.');
36 $data['sujet'] = trim($data['sujet']);
38 if (!isset($data['texte']) ||
trim($data['texte']) === '')
40 throw new UserException('Le contenu du rappel ne peut être vide.');
43 $data['texte'] = trim($data['texte']);
48 * @param array $data Données du rappel
49 * @return integer Numéro ID du rappel créé
51 public function add($data)
53 $db = DB
::getInstance();
55 $this->_checkFields($data);
57 $db->simpleInsert('rappels', $data);
59 return $db->lastInsertRowId();
63 * Modifier un rappel automatique
64 * @param integer $id Numéro du rappel
65 * @param array $data Données du rappel
66 * @return boolean TRUE si tout s'est bien passé
67 * @throws UserException En cas d'erreur dans une donnée à modifier
69 public function edit($id, $data)
71 $db = DB
::getInstance();
73 $this->_checkFields($data);
75 return $db->simpleUpdate('rappels', $data, 'id = ' . (int)$id);
79 * Supprimer un rappel automatique
80 * @param integer $id Numéro du rappel
81 * @param boolean $delete_history Effacer aussi l'historique des rappels envoyés
82 * @return boolean TRUE en cas de succès
84 public function delete($id, $delete_history = false)
86 $db = DB
::getInstance();
92 $db->simpleExec('DELETE FROM rappels_envoyes WHERE id_rappel = ?;', (int) $id);
96 $db->simpleExec('UPDATE rappels_envoyes SET id_rappel = NULL WHERE id_rappel = ?;', (int) $id);
99 $db->simpleExec('DELETE FROM rappels WHERE id = ?;', (int) $id);
106 * Renvoie les données sur un rappel
107 * @param integer $id Numéro du rappel
108 * @return array Données du rappel
110 public function get($id)
112 return DB
::getInstance()->simpleQuerySingle('SELECT * FROM rappels WHERE id = ?;', true, (int)$id);
116 * Renvoie le nombre de rappels automatiques enregistrés
117 * @return integer Nombre de rappels
119 public function countAll()
121 return DB
::getInstance()->simpleQuerySingle('SELECT COUNT(*) FROM rappels;');
125 * Liste des rappels triés par cotisation
126 * @return array Liste des rappels
128 public function listByCotisation()
130 return DB
::getInstance()->simpleStatementFetch('SELECT r.*,
131 c.intitule, c.montant, c.duree, c.debut, c.fin
133 INNER JOIN cotisations AS c ON c.id = r.id_cotisation
134 ORDER BY r.id_cotisation, r.delai, r.sujet;');
138 * Liste des rappels pour une cotisation donnée
139 * @param integer $id Numéro du rappel
140 * @return array Liste des rappels
142 public function listForCotisation($id)
144 return DB
::getInstance()->simpleStatementFetch('SELECT * FROM rappels
145 WHERE id_cotisation = ? ORDER BY delai, sujet;', \SQLITE3_ASSOC
, (int)$id);
149 * Envoi des rappels automatiques par e-mail
150 * @return boolean TRUE en cas de succès
152 public function sendPending()
154 $db = DB
::getInstance();
155 $config = Config
::getInstance();
157 // Requête compliquée qui fait tout le boulot
158 // la logique est un JOIN des tables rappels, cotisations, cotisations_membres et membres
159 // pour récupérer la liste des membres qui doivent recevoir une cotisation
163 /* Nombre de jours avant ou après expiration */
164 (julianday(date()) - julianday(expiration)) AS nb_jours,
165 /* Date de mise en œuvre du rappel */
166 date(expiration, delai || \' days\') AS date_rappel
168 SELECT m.*, r.delai, r.sujet, r.texte, r.id_cotisation,
169 m.'.$config->get('champ_identite').' AS identite,
170 CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\')
171 WHEN c.fin IS NOT NULL THEN c.fin ELSE 0 END AS expiration
173 INNER JOIN cotisations AS c ON c.id = r.id_cotisation
174 INNER JOIN cotisations_membres AS cm ON cm.id_cotisation = c.id
175 INNER JOIN membres AS m ON m.id = cm.id_membre
177 /* Inutile de sélectionner les membres sans email */
178 m.email IS NOT NULL AND m.email != \'\'
179 /* Les cotisations ponctuelles ne comptent pas */
180 AND (c.fin IS NOT NULL OR c.duree IS NOT NULL)
181 /* Rien nest envoyé aux membres des catégories cachées, logique */
182 AND m.id_categorie NOT IN (SELECT id FROM membres_categories WHERE cacher = 1)
185 WHERE nb_jours >= delai
186 /* Pour ne pas spammer on n\'envoie pas de rappel antérieur au dernier rappel déjà effectué */
187 AND id NOT IN (SELECT id_membre FROM rappels_envoyes AS re
188 WHERE id_cotisation = re.id_cotisation AND id = re.id_membre
189 AND re.date >= date(expiration, delai || \' days\')
191 /* Grouper par membre, pour n\'envoyer qu\'un seul rappel par membre/cotise */
192 GROUP BY id, id_cotisation
193 ORDER BY nb_jours DESC;';
196 $st = $db->prepare($query);
197 $res = $st->execute();
198 $re = new Rappels_Envoyes
;
200 while ($row = $res->fetchArray(DB
::ASSOC
))