source: spip-zone/_plugins_/commandes/trunk/commandes_pipelines.php @ 103863

Last change on this file since 103863 was 103863, checked in by cedric@…, 3 years ago

Tous les cas de resiliation ne sont pas des erreurs : on peut resilier un abonnement volontairement depuis le back-office,
ou le client peut le demander depuis sa page mon compte, et dans ce cas tout est normal.
On repere donc le cas d'erreur lors de la resiliation via le flag erreur envoye par le plugin bank depuis
https://github.com/nursit/bank/commit/0706135e9540f0f7ea512237aa4f2f4ec27de81f

File size: 16.9 KB
Line 
1<?php
2/**
3 * Pieplines utilisées par le plugin Commandes
4 *
5 * @plugin     Commandes
6 * @copyright  2014
7 * @author     Ateliers CYM, Matthieu Marcillaud, Les Développements Durables
8 * @licence    GPL 3
9 * @package    SPIP\Commandes\Pipelines
10 */
11
12// Sécurité
13if (!defined('_ECRIRE_INC_VERSION')) return;
14
15
16/**
17 * Insertion de la feuille de style CSS sur les pages publiques
18 *
19 * @pipeline insert_head_css
20 * @param  array $flux Données du pipeline
21 * @return array       Données du pipeline
22 */
23function commandes_insert_head_css($flux){
24        $css = find_in_path('css/commandes.css');
25        $flux .= "<link rel='stylesheet' type='text/css' media='all' href='$css' />\n";
26        return $flux;
27}
28
29
30/**
31 * Optimiser la base de donnée en supprimant toutes les commandes en cours qui sont trop vieilles
32 *
33 * Le délai de "péremption" est défini dans les options de configuration du plugin
34 *
35 * @pipeline optimiser_base_disparus
36 * @param  array $flux Données du pipeline
37 * @return array       Données du pipeline
38 */
39function commandes_optimiser_base_disparus($flux){
40        include_spip('inc/config');
41        // On cherche la date depuis quand on a le droit d'avoir fait la commande (par défaut 1h)
42        $depuis = date('Y-m-d H:i:s', time() - 3600*intval(lire_config('commandes/duree_vie', 1)));
43        // On récupère les commandes trop vieilles
44        $commandes = sql_allfetsel(
45                'id_commande',
46                'spip_commandes',
47                'statut = '.sql_quote('encours').' and date<'.sql_quote($depuis)
48        );
49
50        // S'il y a bien des commandes à supprimer
51        if ($commandes) {
52                $commandes = array_map('reset', $commandes);
53                include_spip('inc/commandes');
54                commandes_supprimer($commandes);
55                $flux['data'] += count($commandes);
56        }
57
58        return $flux;
59}
60
61
62/**
63 * Ajout de contenu sur certaines pages
64 *
65 * - Formulaires pour modifier les dates sur la fiche d'une commande
66 *
67 * @pipeline affiche_milieu
68 * @param  array $flux Données du pipeline
69 * @return array       Données du pipeline
70 */
71function commandes_affiche_milieu($flux) {
72
73        if (
74                $exec = trouver_objet_exec($flux['args']['exec'])
75                and $exec['edition'] == false 
76                and $exec['type'] == 'commande'
77                and $id_table_objet = $exec['id_table_objet']
78                and (isset($flux['args'][$id_table_objet]) and $id_commande = intval($flux['args'][$id_table_objet]))
79        ) {
80                $texte = recuperer_fond('prive/squelettes/contenu/commande_affiche_milieu',array('id_commande'=>$id_commande));
81        }
82
83        if (isset($texte)) {
84                if ($p=strpos($flux['data'],"<!--affiche_milieu-->"))
85                        $flux['data'] = substr_replace($flux['data'],$texte,$p,0);
86                else
87                        $flux['data'] .= $texte;
88        }
89
90        return $flux;
91}
92
93
94/**
95 * Ajout de contenu dans la liste des éléments en attente de validation
96 *
97 * - Liste des commandes aux statuts définis comme "actifs" dans les options de configuration
98 *
99 * @pipeline accueil_encours
100 * @param  array $flux Données du pipeline
101 * @return array       Données du pipeline
102 */
103function commandes_accueil_encours($flux) {
104
105        include_spip('inc/config');
106        $activer = lire_config('commandes/accueil_encours');
107        $statuts = lire_config('commandes/statuts_actifs');
108        if ($activer and is_array($statuts)) {
109                foreach($statuts as $statut){
110                        if ($nb_{$statut} = sql_countsel(table_objet_sql('commande'), "statut=".sql_quote($statut))) {
111                                $titre_{$statut} = singulier_ou_pluriel($nb_{$statut}, 'commandes:info_1_commande_statut_'.$statut, 'commandes:info_nb_commandes_statut_'.$statut);
112                                $flux .= recuperer_fond('prive/objets/liste/commandes', array(
113                                        'titre' => $titre_{$statut},
114                                        'statut' => $statut,
115                                        'cacher_tri' => true,
116                                        'nb' => 5),
117                                        array('ajax' => true)
118                                );
119                        }
120                }
121        }
122
123        return $flux;
124}
125
126
127/**
128 * Ajout de liste sur la vue d'un auteur
129 *
130 * - Liste des commandes de l'auteur
131 *
132 * @pipeline affiche_auteurs_interventions
133 * @param  array $flux Données du pipeline
134 * @return array       Données du pipeline
135**/
136function commandes_affiche_auteurs_interventions($flux) {
137
138        if ($id_auteur = intval($flux['args']['id_auteur'])) {
139                $flux['data'] .= recuperer_fond('prive/objets/liste/commandes', array(
140                        'id_auteur' => $id_auteur,
141                        'titre' => _T('commandes:titre_commandes_auteur'),
142                        'cacher_tri' => true
143                        ),
144                        array('ajax' => true)
145                );
146        }
147
148        return $flux;
149}
150
151
152/**
153 * Compléter la liste des types d'adresses du plugin Coordonnées
154 *
155 * Ajout de 2 types d'adresses : facturation et livraison
156 *
157 * @pipeline types_coordonnees
158 * @param  array $liste Données du pipeline
159 * @return array        Données du pipeline
160**/
161function commandes_types_coordonnees($liste) {
162
163        $types_adresses = $liste['adresse'];
164        if (!$types_adresses or !is_array($types_adresses)) $types_adresses = array();
165
166        // on définit les couples types + chaînes de langue à ajouter
167        $types_adresses_commandes = array(
168                'livraison' => _T('commandes:type_adresse_livraison'),
169                'facturation' => _T('commandes:type_adresse_facturation')
170        );
171        // on les rajoute à la liste des types des adresses
172        $liste['adresse'] = array_merge($types_adresses, $types_adresses_commandes);
173
174        return $liste;
175}
176
177
178/**
179 * Enregistrer le bon reglement d'une commande liee a une transaction du plugin bank
180 *
181 * @pipeline bank_traiter_reglement
182 * @param array $flux
183 * @return array mixed
184 */
185function commandes_bank_traiter_reglement($flux){
186        // Si on est dans le bon cas d'un paiement de commande et qu'il y a un id_commande et que la commande existe toujours
187        if (
188                $id_transaction = $flux['args']['id_transaction']
189                and $transaction = sql_fetsel("*","spip_transactions","id_transaction=".intval($id_transaction))
190                and $id_commande = $transaction['id_commande']
191                and $commande = sql_fetsel('id_commande, statut, id_auteur, echeances, reference', 'spip_commandes', 'id_commande='.intval($id_commande))
192        ){
193                $statut_commande = $commande['statut'];
194                $montant_regle = $transaction['montant_regle'];
195                $transaction_mode = $transaction['mode'];
196                $statut_nouveau = 'paye';
197               
198                // Si la commande n'a pas d'échéance, le montant attendu est celui du prix de la commande
199                if (!$commande['echeances'] or !$echeances = unserialize($commande['echeances'])) {
200                        $fonction_prix = charger_fonction('prix', 'inc/');
201                        $montant_attendu = $fonction_prix('commande', $id_commande);
202                }
203                // Sinon le montant attendu est celui de la prochaine échéance (en ignorant la dernière transaction OK que justement on cherche à tester)
204                else {
205                        include_spip('inc/commandes_echeances');
206                        $montant_attendu = commandes_trouver_prochaine_echeance($id_commande, $echeances, true);
207                }
208                spip_log("commande #$id_commande attendu:$montant_attendu regle:$montant_regle", 'commandes');
209
210                // Si le plugin n'était pas déjà en payé et qu'on a pas assez payé
211                // (si le plugin était déjà en payé, ce sont possiblement des renouvellements)
212                if (
213                        $statut_commande != 'paye'
214                        and (floatval($montant_attendu) - floatval($montant_regle)) >= 0.01
215                ){
216                        $statut_nouveau = 'partiel';
217                }
218               
219                // S'il y a bien un statut à changer
220                if ($statut_nouveau !== $statut_commande){
221                        spip_log("commandes_bank_traiter_reglement marquer la commande #$id_commande statut=$statut_nouveau mode=$transaction_mode",'commandes');
222                        // On met a jour la commande
223                        include_spip("action/editer_commande");
224                        commande_modifier($id_commande, array('statut'=>$statut_nouveau, 'mode'=>$transaction_mode));
225                }
226
227                // un message gentil pour l'utilisateur qui vient de payer, on lui rappelle son numero de commande
228                $flux['data'] .= "<br />"._T('commandes:merci_de_votre_commande_paiement',array('reference'=>$commande['reference']));
229        }
230
231        return $flux;
232}
233
234/**
235 * Enregistrer le reglement en attente d'une commande liee a une transaction du plugin bank
236 * (cas du reglement par cheque par exemple)
237 *
238 * @pipeline trig_bank_reglement_en_attente
239 * @param array $flux
240 * @return array mixed
241 */
242function commandes_trig_bank_reglement_en_attente($flux){
243        // Si on est dans le bon cas d'un paiement de commande et qu'il y a un id_commande et que la commande existe toujours
244        if ($id_transaction = $flux['args']['id_transaction']
245          AND $transaction = sql_fetsel("*","spip_transactions","id_transaction=".intval($id_transaction))
246                AND $id_commande = $transaction['id_commande']
247                AND $commande = sql_fetsel('id_commande, statut, id_auteur, mode', 'spip_commandes', 'id_commande='.intval($id_commande))){
248
249                $statut_commande = $commande['statut'];
250                $transaction_mode = $transaction['mode'];
251                $commande_mode = $commande['mode'];
252                $statut_nouveau = 'attente';
253                if ($statut_nouveau !== $statut_commande OR $transaction_mode !==$commande_mode){
254                        spip_log("commandes_trig_bank_reglement_en_attente marquer la commande #$id_commande statut=$statut_nouveau mode=$transaction_mode",'commandes');
255                        //on met a jour la commande
256                        include_spip("action/editer_commande");
257                        commande_modifier($id_commande,array('statut'=>$statut_nouveau,'mode'=>$transaction_mode));
258                }
259        }
260
261        return $flux;
262}
263
264
265/**
266 * Enregistrer le reglement en echec d'une commande liee a une transaction du plugin bank
267 * (cas du reglement annule ou du refus de carte etc)
268 *
269 * @pipeline trig_bank_reglement_en_echec
270 * @param array $flux
271 * @return array mixed
272 */
273function commandes_trig_bank_reglement_en_echec($flux){
274        // Si on est dans le bon cas d'un paiement de commande et qu'il y a un id_commande et que la commande existe toujours
275        if ($id_transaction = $flux['args']['id_transaction']
276          AND $transaction = sql_fetsel("*","spip_transactions","id_transaction=".intval($id_transaction))
277                AND $id_commande = $transaction['id_commande']
278                AND $commande = sql_fetsel('id_commande, statut, id_auteur', 'spip_commandes', 'id_commande='.intval($id_commande))){
279
280                $statut_commande = $commande['statut'];
281                $transaction_mode = $transaction['mode'];
282                $statut_nouveau = $statut_commande;
283
284                // on ne passe la commande en erreur que si le reglement a effectivement echoue,
285                // pas si c'est une simple annulation (retour en arriere depuis la page de paiement bancaire)
286                if (strncmp($transaction['statut'],"echec",5)==0){
287                        $statut_nouveau = 'erreur';
288                }
289                if ($statut_nouveau !== $statut_commande){
290                        spip_log("commandes_trig_bank_reglement_en_attente marquer la commande #$id_commande statut=$statut_nouveau",'commandes');
291                        //on met a jour la commande
292                        include_spip("action/editer_commande");
293                        commande_modifier($id_commande,array('statut'=>$statut_nouveau,'mode'=>$transaction_mode));
294                }
295        }
296
297        return $flux;
298}
299
300/**
301 * Déclarer les échéances à la banque
302 *
303 * @pipeline bank_abos_decrire_echeance
304 **/
305function commandes_bank_abos_decrire_echeance($flux) {
306        if (
307                // si on doit bien faire du prélèvement auto
308                $flux['args']['force_auto'] == true
309                // et qu'on a une transaction sous la main
310                and $id_transaction = intval($flux['args']['id_transaction'])
311                // et que cette transaction a un id_commande
312                and $id_commande = intval(sql_getfetsel('id_commande', 'spip_transactions', 'id_transaction = '.$id_transaction))
313                // et que la commande a des informations d'échéances
314                and $commande = sql_fetsel('echeances_type, echeances', 'spip_commandes', 'id_commande = '.$id_commande)
315                and $echeances = unserialize($commande['echeances'])
316                and $echeances_type = $commande['echeances_type']
317                and in_array($echeances_type, array('mois', 'annee'))
318        ) {
319                // On définit la périodicité
320                switch($echeances_type) {
321                        case 'mois':
322                                $flux['data']['freq'] = 'monthly';
323                                break;
324                        case 'annee':
325                                $flux['data']['freq'] = 'yearly';
326                                break;
327                }
328               
329                // Si c'est une seule valeur toute simple
330                if (!is_array($echeances)) {
331                        $echeances = floatval($echeances);
332                        $flux['data']['montant'] = $echeances;
333                }
334                // Sinon c'est un peu plus compliqué, et pour l'instant on ne gère que DEUX montants possibles
335                elseif (count($echeances) >= 2) {
336                        // Premier montant d'échéances
337                        $flux['data']['montant_init'] = $echeances[0]['montant'];
338                        $flux['data']['count_init'] = $echeances[0]['nb'];
339                        // Deuxième montant d'échéances
340                        $flux['data']['montant'] = $echeances[1]['montant'];
341                        if (isset($echeances[1]['nb'])) {
342                                $flux['data']['count'] = $echeances[1]['nb'];
343                        }
344                }
345        }
346       
347        return $flux;
348}
349
350/**
351 * Lier une commande à un identifiant bancaire lorsqu'un prélèvement bancaire est bien validé
352 *
353 * @pipeline bank_abos_activer_abonnement
354 **/
355function commandes_bank_abos_activer_abonnement($flux){
356        // Si on a une transaction
357        if ($id_transaction = intval($flux['args']['id_transaction'])) {
358                $where = 'id_transaction = '.$id_transaction;
359        }
360        // Sinon on cherche par l'identifiant d'abonnement bancaire
361        elseif ($abo_uid = $flux['args']['abo_uid']) {
362                $where = 'abo_uid = '.sql_quote($abo_uid);
363        }
364       
365        // On gère d'abord les erreurs possibles si on ne trouve pas la bonne transaction
366        if (!$where or !$transaction = sql_fetsel('*', 'spip_transactions', $where)) {
367                spip_log("Impossible de trouver la transaction ($id_transaction / $abo_uid).", 'commandes.'._LOG_ERREUR);
368                $flux['data'] = false;
369        }
370        elseif ($transaction['statut'] == 'commande') {
371                spip_log("La transaction ${transaction['id_transaction']} n’a pas été réglée.", 'commandes.'._LOG_ERREUR);
372                $flux['data'] = false;
373        }
374        elseif (strncmp($transaction['statut'], 'echec',5) == 0) {
375                spip_log("La transaction ${transaction['id_transaction']} a echoué.",'commandes.'._LOG_ERREUR);
376                $flux['data'] = false;
377        }
378        // Si on a trouvé ce qu'il faut, on va lier la commande à l'identifiant bancaire
379        elseif ($id_commande = intval($transaction['id_commande'])) {
380                include_spip('action/editer_objet');
381               
382                objet_modifier('commande', $id_commande, array('bank_uid' => $flux['args']['abo_uid']));
383        }
384       
385        return $flux;
386}
387
388/**
389 * Créer la transaction correspondant à la prochaine échéance d'une commande
390 *
391 * @pipeline bank_abos_preparer_echeance
392 **/
393function commandes_bank_abos_preparer_echeance($flux){
394        // On commence par chercher la commande dont il s'agit
395        // et vérifier qu'elle a des échéances
396        if (
397                isset($flux['args']['id'])
398                and $id = $flux['args']['id']
399                and strncmp($id,"uid:",4) == 0
400                and $bank_uid = substr($id, 4)
401                and $commande = sql_fetsel('*', 'spip_commandes', 'bank_uid = '.sql_quote($bank_uid))
402                and $id_commande = intval($commande['id_commande'])
403                and $echeances = unserialize($commande['echeances'])
404                and $echeances_type = $commande['echeances_type']
405        ){
406                include_spip('inc/commandes_echeances');
407               
408                // Si on a bien trouvé une prochaine échéance
409                if ($montant = commandes_trouver_prochaine_echeance($id_commande, $echeances)) {
410                        include_spip('action/editer_objet');
411                       
412                        // On remet la commande en attente de paiement puisqu'on… attend un paiement !
413                        objet_modifier('commande', $id_commande, array('statut' => 'attente'));
414                       
415                        // On crée la transaction qui testera le vrai paiement
416                        $inserer_transaction = charger_fonction('inserer_transaction', 'bank');
417                        $options_transaction = array(
418                                'id_auteur' => intval($commande['id_auteur']),
419                                'champs' => array(
420                                        'id_commande' => $id_commande,
421                                ),
422                        );
423                        $id_transaction = intval($inserer_transaction($montant, $options_transaction));
424                       
425                        $flux['data'] = $id_transaction;
426                }
427        }
428       
429        return $flux;
430}
431
432/**
433 * Mettre en erreur une commande dont le prélèvement automatique aurait échoué
434 * on repere ce cas via le flag erreur=true envoyer lors de la resiliation
435 *
436 * @pipeline bank_abos_resilier
437 **/
438function commandes_bank_abos_resilier($flux){
439        // On commence par chercher la commande dont il s'agit
440        // et vérifier qu'elle a des échéances
441        if (
442                isset($flux['args']['erreur']) and $flux['args']['erreur']
443                and isset($flux['args']['id']) and $id = $flux['args']['id']
444                and strncmp($id,"uid:",4) == 0
445                and $bank_uid = substr($id, 4)
446                and $commande = sql_fetsel('*', 'spip_commandes', 'bank_uid = '.sql_quote($bank_uid))
447                and $id_commande = intval($commande['id_commande'])
448        ) {
449                include_spip('action/editer_objet');
450               
451                // Le prélèvement a échoué explicitement, donc la commande d'origine est en erreur
452                objet_modifier('commande', $id_commande, array('statut' => 'erreur'));
453        }
454       
455        return $flux;
456}
457
458/**
459 * Si le plugin Bank est activé, un changement de statut vers Payée redirige vers la page de paiement de la transaction
460 *
461 * @pipeline pre_edition
462 **/
463
464function commandes_pre_edition($flux){
465        if (test_plugin_actif('bank')
466                AND $flux['args']['table'] == 'spip_commandes'
467                AND $flux['args']['action'] == 'instituer'
468                AND $flux['data']['statut'] == 'paye') {
469
470                $id_commande = $flux['args']['id_objet'];
471
472                $transaction = sql_fetsel('id_transaction, transaction_hash, statut', 'spip_transactions', 'id_commande='.intval($id_commande));
473
474                if (!is_null($transaction) AND $transaction['statut'] != 'ok') {
475                        $arguments = "id_transaction=".$transaction['id_transaction']."&transaction_hash=".$transaction['transaction_hash'];
476
477                        include_spip('inc/headers');
478                        redirige_url_ecrire('payer' , $arguments);
479                }
480        }
481        return $flux;
482}
Note: See TracBrowser for help on using the repository browser.