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

Last change on this file since 113726 was 113726, checked in by cedric@…, 20 months ago

retour sur r109419 : pas de trouver_fond() au moment de l'appel de notification, c'est presumer de ce que fait la notification. Mais on passe statut et statut_ancien dans les options en cas de changement de statut, ce qui permet a la notification d'aiguiller sur un squelette en particulier si besoin (ou de faire la même chose en utilisant simplement un fond qui verie selon le statut)

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