source: spip-zone/_plugins_/commandes/trunk/inc/commandes.php @ 109419

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

Nouvelle possibilité de notification par statut. Par exemple, le squelette notifications/commande_client_attente.html sera utilisée à la place de la notification générique.

File size: 14.3 KB
Line 
1<?php
2/**
3 * Fonctions (bis) du 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\Fonctions
10 */
11
12// Sécurité
13if (!defined('_ECRIRE_INC_VERSION')) return;
14
15/**
16 * Créer une commande avec le statut `encours` pour le visiteur actuel.
17 *
18 * On part du principe qu'il ne peut y avoir qu'une seule commande `encours` par session,
19 * aussi on supprime de la base toute ancienne commande `encours` présente en session avant d'en créer une nouvelle.
20 * L'identifiant de la nouvelle commande est ensuite placé dans la session.
21 *
22 * Si le visiteur n'est pas identifie mais connu, on peut passer son id_auteur en argument pour permettre le rattachement de la commande a son compte
23 * mais attention dans tous les cas la commande sera associee a la session en cours.
24 * C'est utile si par exemple on demande l'email au visiteur dans le processus d'achat mais on veut pas l'obliger a se connecter pour simplifier le workflow :
25 * il peut faire tout le processus en restant non connecte, mais la commande sera quand meme rattachee a son compte
26 * Et ca permet aussi de faire une commande pour le compte de quelqu'un d'autre sans avoir besoin de ses identifiants (ie payer un abonnement a un ami)
27 *
28 * @uses commandes_reference()
29 * @uses commande_inserer()
30 *
31 * @param int $id_auteur
32 *   permet de preciser l'id_auteur de la session au cas ou le visiteur n'est pas connecte mais connu
33 *   (par son email qu'il a rentre dans le processus de commande par exemple)
34 * @return int $id_commande
35 *     identifiant SQL de la commande
36 */
37function creer_commande_encours($id_auteur = 0){
38        include_spip('inc/session');
39
40        // S'il y a une commande en cours dans la session, on la supprime
41        if (($id_commande = intval(session_get('id_commande'))) > 0){
42                // Si la commande est toujours "encours" il faut la mettre a la poubelle
43                // il ne faut pas la supprimer tant qu'il n'y a pas de nouvelles commandes pour etre sur qu'on reutilise pas son numero
44                // (sous sqlite la nouvelle commande reprend le numero de l'ancienne si on fait delete+insert)
45                if ($statut = sql_getfetsel('statut', 'spip_commandes', 'id_commande = '.intval($id_commande)) AND $statut == 'encours'){
46                        spip_log("Commande ancienne encours->poubelle en session : $id_commande",'commandes');
47                        sql_updateq("spip_commandes",array('statut'=>'poubelle'),'id_commande = '.intval($id_commande));
48                }
49                // Dans tous les cas on supprime la valeur de session
50                session_set('id_commande');
51        }
52
53        // Le visiteur en cours
54        if (!$id_auteur and session_get('id_auteur')>0) {
55                $id_auteur = session_get('id_auteur');
56        }
57
58        $champs = array(
59                'id_auteur' => $id_auteur
60        );
61
62        // Création de la commande
63        include_spip('action/editer_commande');
64        $id_commande = commande_inserer(null,$champs);
65        session_set('id_commande', $id_commande);
66
67        return $id_commande;
68}
69
70/**
71 * Supprimer une ou plusieurs commandes et leurs données associées
72 *
73 * La fonction va supprimer :
74 *
75 * - les détails des commandes
76 * - les liens entre les commandes et leurs adresses
77 * - les adresses si elles sont devenues orphelines
78 *
79 * @param int|array $ids_commandes
80 *     Identifiant d'une commande ou tableau d'identifiants
81 * @return bool
82 *     - false si pas d'identifiant de commande transmis
83 *     - true sinon
84**/
85function commandes_supprimer($ids_commandes) {
86        if (!$ids_commandes) return false;
87        if (!is_array($ids_commandes)) $ids_commandes = array($ids_commandes);
88
89        spip_log("commandes_effacer : suppression de commande(s) : " . implode(',', $ids_commandes),'commandes');
90
91        $in_commandes = sql_in('id_commande', $ids_commandes);
92
93        // On supprime ses détails
94        sql_delete('spip_commandes_details', $in_commandes);
95
96        // On dissocie les commandes et les adresses, et éventuellement on supprime ces dernières
97        include_spip('action/editer_liens');
98        if ($adresses_commandes = objet_trouver_liens(array('adresse'=>'*'), array('commande'=>$ids_commandes))) {
99                $adresses_commandes = array_unique(array_map('reset',$adresses_commandes));
100
101                // d'abord, on dissocie les adresses et les commandes
102                spip_log("commandes_effacer : dissociation des adresses des commandes à supprimer : " . implode(',', $adresses_commandes),'commandes');
103                objet_dissocier(array('adresse'=>$adresses_commandes), array('commande'=>$ids_commandes));
104
105                // puis si les adresses ne sont plus utilisées nul part, on les supprime
106                foreach($adresses_commandes as $id_adresse)
107                        if (!count(objet_trouver_liens(array('adresse'=>$id_adresse), '*')))
108                                sql_delete(table_objet_sql('adresse'), "id_adresse=".intval($id_adresse));
109        }
110
111        // On supprime les commandes
112        sql_delete(table_objet_sql('commande'), $in_commandes);
113
114        return true;
115}
116/**
117 * Supprimer des commandes
118 *
119 * @deprecated Alias de commandes_supprimer() pour rétro-compatibilité
120 * @see commandes_supprimer()
121 *
122 * @param int|array $ids_commandes
123 *     Identifiant d'une commande ou tableau d'identifiants
124 * @return bool
125 *     - false si pas d'identifiant de commande transmis
126 *     - true sinon
127 */
128function commandes_effacer($ids_commandes) {
129        return commandes_supprimer($ids_commandes);
130}
131
132/**
133 * Ajouter une ligne de detail dans une commande
134 * @param int $id_commande
135 * @param array $emplette
136 *   objet : type de l'objet ajoute
137 *   id_objet : id de l'objet ajoute
138 *   quantite : quantite ajoutee
139 * @param bool $ajouter
140 * @return int
141 */
142function commandes_ajouter_detail($id_commande, $emplette, $ajouter=true){
143        static $fonction_prix,$fonction_prix_ht;
144        if (!$fonction_prix OR !$fonction_prix_ht){
145                $fonction_prix = charger_fonction('prix', 'inc/');
146                $fonction_prix_ht = charger_fonction('ht', 'inc/prix');
147        }
148
149        // calculer la taxe
150        $prix_ht = $fonction_prix_ht($emplette['objet'], $emplette['id_objet'],6);
151        $prix = $fonction_prix($emplette['objet'], $emplette['id_objet'],6);
152        if($prix_ht > 0)
153                $taxe = round(($prix - $prix_ht) / $prix_ht, 3);
154        else
155                $taxe = 0;
156
157        $set = array(
158                'id_commande' => $id_commande,
159                'objet' => $emplette['objet'],
160                'id_objet' => $emplette['id_objet'],
161                'descriptif' => generer_info_entite($emplette['id_objet'], $emplette['objet'], 'titre', '*'),
162                'quantite' => $emplette['quantite'],
163                'prix_unitaire_ht' => $prix_ht,
164                'taxe' => $taxe,
165                'statut' => 'attente'
166        );
167
168        // chercher si une ligne existe deja ou l'ajouter
169        $where = array();
170        foreach($set as $k=>$w){
171                if (in_array($k,array('id_commande','objet','id_objet'))){
172                        $where[] = "$k=".sql_quote($w);
173                }
174        }
175
176        include_spip('action/editer_objet');
177        // est-ce que cette ligne est deja la ?
178        if ($ajouter
179          or !$id_commandes_detail = sql_getfetsel("id_commandes_detail","spip_commandes_details",$where)){
180                // sinon création et renseignement du détail de la commande
181                $id_commandes_detail = objet_inserer('commandes_detail');
182        }
183
184        // la mettre a jour
185        if ($id_commandes_detail) {
186                objet_modifier('commandes_detail', $id_commandes_detail, $set);
187        }
188
189        return $id_commandes_detail;
190}
191
192/**
193 * Supprimer un ou plusieurs détails d'une commande
194 *
195 * On supprime les détails correspondant à commande dans la table `spip_commandes_details`.
196 * Si tous ses détails sont supprimés par l'opération, la commande peut également être supprimée en présence du paramètre adéquat.
197 *
198 * @uses commandes_supprimer()
199 *
200 * @param int $id_commande
201 *     Identifiant de la commande
202 * @param int|array $ids_details
203 *     Identifiant d'un détail ou tableau d'identifiants
204 * @param bool $supprimer_commande
205 *     true pour effacer la commande si elle est vide après l'opération
206 * @return bool
207 *     false si pas d'identifiant de commande transmis, ou si pas autorisé à supprimer
208 *     true sinon
209 */
210function commandes_supprimer_detail($id_commande=0, $ids_details=array(), $supprimer_commande=false) {
211
212        if (!$id_commande) return false;
213        if (!is_array($ids_details)) $ids_details = array($ids_details);
214
215        include_spip('inc/autoriser');
216        if (autoriser('supprimerdetail','commande',$id_commande)) {
217                $nb_details = sql_countsel('spip_commandes_details', "id_commande=".intval($id_commande));
218                // suppression des détails
219                foreach($ids_details as $id_detail)
220                        sql_delete('spip_commandes_details', "id_commande=".intval($id_commande) . " AND id_commandes_detail=".intval($id_detail));
221                // optionnellement, si la commande est vide, on la supprime
222                if ($nb_details == count($ids_details) and $supprimer_commande)
223                        commandes_supprimer($id_commande);
224                return true;
225        } else {
226                return false;
227        }
228}
229
230
231/**
232 * Envoyer un mail de notification
233 *
234 * - On veut envoyer du html pour que le tableau de commandes soit lisible par le client
235 * - On peut avoir un expediteur specifique
236 * - Mais `notifications_envoyer_mails()` de spip ne peut pas envoyer de mails en html. On ne peut pas non plus y specifier un expediteur.
237 * Donc si les plugins notifications_avancees et Facteur sont presents, on prepare un joli mail en html. Sinon un moche en texte.
238 *
239 * @deprecated Voir traiter_notifications_commande()
240 *
241 * @param string $qui : vendeur ou client
242 * @param string $id_type
243 * @param int $id_commande
244 * @param string $expediteur
245 * @param array $destinataires
246 *
247 */
248function commandes_envoyer_notification( $qui, $id_type, $id_commande, $expediteur, $destinataires){
249        spip_log("commandes_envoyer_notification qui? $qui, id_type $id_type, id_commande $id_commande, expediteur $expediteur, destinataires ".implode(", ", $destinataires),'commandes');
250
251        notifications_nettoyer_emails($destinataires);
252
253        if(defined('_DIR_PLUGIN_NOTIFAVANCEES') && defined('_DIR_PLUGIN_FACTEUR')) {
254                spip_log("commandes_envoyer_notification via Notifications avancées",'commandes');
255                if (
256                        !notifications_envoyer(
257                                $destinataires,
258                                "email",
259                                "commande_".$qui,
260                                $id_commande,
261                                $options=array('from'=>$expediteur))
262                )
263                        spip_log("commandes_envoyer_notification Erreur d'envoi via Notifications avancées",'commandes');
264        } else {
265                $texte = recuperer_fond("notifications/commande",array(
266                        $id_type=>$id_commande,
267                        "id"=>$id_commande,
268                        "format_envoi"=>"plain",
269                        "qui"=>$qui));
270                if( $qui == "client" ) {
271                        $sujet = _T('commandes:votre_commande_sur', array('nom'=>$GLOBALS['meta']["nom_site"])) ;
272                } else {
273                        $sujet = _T('commandes:une_commande_sur', array('nom'=>$GLOBALS['meta']["nom_site"])) ;
274                }
275                // Si un expediteur est impose, on doit utiliser la fonction envoyer_email pour rajouter l'expediteur
276                if ($expediteur) {
277                        $envoyer_mail = charger_fonction('envoyer_mail','inc');
278                        spip_log("commandes_envoyer_notification via $envoyer_mail",'commandes');
279                        if( !$envoyer_mail($destinataires, $sujet, $texte, $expediteur))
280                                spip_log("commandes_envoyer_notification Erreur d'envoi via $envoyer_mail",'commandes');
281
282                } else {
283                        spip_log("commandes_envoyer_notification via notifications_envoyer_mails",'commandes');
284                        if ( !notifications_envoyer_mails($destinataires, $texte, $sujet) )
285                                spip_log("commandes_envoyer_notification Erreur d'envoi via notifications_envoyer_mails",'commandes');
286                }
287        }
288}
289
290
291/**
292 * Traitement des notifications par email d'une commande
293 *
294 * Selon les options de configuration et le statut de la commande, des emails seront envoyés au(x) vendeur(s) et optionnellement au client.
295 * Nécessite le plugin "Notifications avancées" pour fonctionner.
296 * Avec le plugin Facteur, les messages seront au format HTML, sinon au format texte.
297 *
298 * @uses notifications()
299 *
300 * @param int|string $id_commande
301 *     Identifiant de la commande
302 * @return void
303 */
304function commandes_notifier($id_commande=0){
305
306        if (intval($id_commande)==0) return;
307
308        if (
309                include_spip('inc/config')
310                and $config = lire_config('commandes')
311                and $quand = ($config['quand'] ? $config['quand'] : array())
312                and $config['activer'] // les notifications sont activées
313                and $statut = sql_getfetsel('statut', table_objet_sql('commande'), "id_commande=".intval($id_commande))
314                and in_array($statut, $quand) // le nouveau statut est valide pour envoyer une notification
315                and $notifications = charger_fonction('notifications', 'inc', true) // la fonction est bien chargée
316        ) {
317
318                // Sans les plugins Facteur et Notifications avancées, on ne fait rien
319                if (!defined('_DIR_PLUGIN_NOTIFAVANCEES')) {
320                        spip_log("traiter_notifications_commande : notifications impossibles sans le plugins Notifications avancées pour la commande $id_commande",'commandes.' . _LOG_ERREUR);
321                        return;
322                }
323
324                // Déterminer l'expéditeur
325                $options = array();
326                if( $config['expediteur'] != "facteur" )
327                        $options['expediteur'] = $config['expediteur_'.$config['expediteur']];
328
329        include_spip('inc/utils');
330
331                // Envoyer au vendeur
332                spip_log("traiter_notifications_commande : notification vendeur pour la commande $id_commande",'commandes.' . _LOG_INFO);
333        if ($notification_statut = trouver_fond('commande_vendeur_'.$statut, 'notifications')) {
334            $notifications('commande_vendeur_'.$statut, $id_commande, $options);
335        } else {
336            $notifications('commande_vendeur', $id_commande, $options);
337        }
338
339                // Envoyer optionnellement au client
340                if($config['client']) {
341   
342                        spip_log("traiter_notifications_commande : notification client pour la commande $id_commande",'commandes.' . _LOG_INFO);
343
344            if ($notification_statut = trouver_fond('notifications/commande_client_'.$statut)) {
345                $notifications('commande_client_'.$statut, $id_commande, $options);
346            } else {
347                $notifications('commande_client', $id_commande, $options);
348            }
349                }
350
351        }
352}
353
354
355/**
356 * Mettre a jour les taxes d'une commande selon exoneration ou non
357 * @param int $id_commande
358 * @param string $exoneration_raison
359 */
360function commandes_appliquer_taxes($id_commande, $exoneration_raison) {
361        $commande = sql_fetsel('*','spip_commandes','id_commande='.intval($id_commande));
362        if (!$commande) return;
363
364        $exoneration_raison = trim($exoneration_raison);
365        if ($commande['taxe_exoneree_raison'] !== $exoneration_raison) {
366                include_spip('action/editer_commande');
367                commande_modifier($id_commande, array('taxe_exoneree_raison' => $exoneration_raison));
368        }
369
370}
371
372
373/**
374 * legacy
375 * @uses commandes_notifier()
376 * @param int $id_commande
377 */
378function traiter_notifications_commande($id_commande=0){
379        return commandes_notifier($id_commande);
380}
381
Note: See TracBrowser for help on using the repository browser.