PEEL Shopping
Open source ecommerce : PEEL Shopping
Caddie.php
Go to the documentation of this file.
1 <?php
2 // This file should be in UTF8 without BOM - Accents examples: éèê
3 // +----------------------------------------------------------------------+
4 // | Copyright (c) 2004-2015 Advisto SAS, service PEEL - contact@peel.fr |
5 // +----------------------------------------------------------------------+
6 // | This file is part of PEEL Shopping 8.0.0, which is subject to an |
7 // | opensource GPL license: you are allowed to customize the code |
8 // | for your own needs, but must keep your changes under GPL |
9 // | More information: https://www.peel.fr/lire/licence-gpl-70.html |
10 // +----------------------------------------------------------------------+
11 // | Author: Advisto SAS, RCS 479 205 452, France, https://www.peel.fr/ |
12 // +----------------------------------------------------------------------+
13 // $Id: Caddie.php 46999 2015-09-22 15:01:17Z sdelaporte $
14 if (!defined('IN_PEEL')) {
15  die();
16 }
26 class Caddie {
27  /* Déclaration des tableaux */
28 
29  /* gestion de la liste cadeau */
30  var $giftlist_owners = array();
31  /* Tableau des articles */
32  var $articles = array();
33  /* Tableau des quantités */
34  var $quantite = array();
35  /* Tableau des poids (pour chaque ligne, le poids est déjà multiplié par la quantité) */
36  var $poids = array();
37  /* Tableau des points (pour chaque ligne, points est déjà multiplié par la quantité) */
38  var $points = array();
39  /* Tableau des couleurs */
40  var $couleurId = array();
41  /* Tableau des tailles */
42  var $tailleId = array();
43  /* Tableau des prix unitaire TTC*/
44  var $prix = array();
45  /* Tableau des prix unitaire HT*/
46  var $prix_ht = array();
47  /* Tableau des prix unitaire TTC*/
48  var $prix_cat = array();
49  /* Tableau des prix unitaire HT*/
50  var $prix_cat_ht = array();
51  /* Tableau prix TTC d'un produit avant l'application d'un code promotionnel*/
52  var $prix_avant_code_promo = array();
53  /* Tableau prix TTC d'un produit avant l'application d'un code promotionnel*/
55  /* Net produit vendu TTC prix x qte*/
56  var $total_prix = array();
57  /* Net produit vendu HT prix_ht x qte */
58  var $total_prix_ht = array();
59  /* Tableau des taux de TVA */
60  var $tva_percent = array();
61  /* Tableau des TVA en valeur */
62  var $tva = array();
63  // percent_remise_produit est le tableau des promotions en pourcentage (colonne "promotion" dans peel_produits + toutes les autres réductions en pourcentage) sur les produits
64  var $percent_remise_produit = array();
65  /* Tableau des type (EUR ou %) de remises par marque */
66  var $remise = array();
67  /* Tableau des remises HT par produit en EUR */
68  var $remise_ht = array();
69  /* Tableau stock produit géré ou non*/
70  var $etat_stock = array();
71  /* Tableau délai d'approvisionnement du stock */
72  var $delai_stock = array();
73  /* Tableau du prix des options */
74  var $option = array();
75  /* Tableau du prix des options */
76  var $option_ht = array();
77  /* Tableau des emails amis */
78  var $email_check = array();
79  /* Tableau de l'ecotaxe par ligne */
80  var $ecotaxe_ttc = array();
81  /* Tableau de l'ecotaxe HT par ligne */
82  var $ecotaxe_ht = array();
83  /* Tableau des attributs */
84  var $attribut = array();
85  var $id_attribut = array();
86  var $total_prix_attribut = array();
87  /* Références produits */
88  var $reference = array();
89 
90  /* Déclaration des variables */
91  /* Montant total du caddie */
92  var $total;
93  /* Montant total du caddie HT */
94  var $total_ht;
96  /* Montant total du caddie */
101  /* Montant total du caddie HT */
105  /* Poids total du caddie */
107  /* Total des points cadeaux */
109 
113 
117 
121 
122  /* Nom du code promo */
124 
130  // Détermine si un code promo s'applique à une seule catégorie ou toutes
132 
133  /* Avoir client en EURO */
134  var $avoir;
136  // Country name (and not id)
137  var $pays;
138  var $zone;
139  var $zoneId;
140  var $zoneTva;
143  var $type;
144  var $typeId;
146 
148  /* supplément pour le paiement */
150  /* supplément pour le paiement */
152  /* supplément pour le paiement */
154 
158 
160 
161  /*Order ID for Socolissimo */
163 
164  /* ID de la commande liée au caddie */
167 
168  // Module conditionnement
172 
173 
179  function Caddie($percent_remise_user)
180  {
181  $this->percent_remise_user = $percent_remise_user;
182  /* constructeur d'object */
183  $this->init(true, false);
184  }
185 
193  function init($load_from_caddie_cookie_if_available = false, $erase_caddie_cookie = true)
194  {
195  unset($_SESSION['session_commande']);
196  foreach($this->articles as $numero_ligne => $product_id) {
197  $this->delete_line($numero_ligne);
198  }
199  /* Montant total du caddie */
200  $this->total = 0;
201 
202  /* Montant total du caddie HT */
203  $this->total_ht = 0;
204  $this->total_tva = 0;
205 
206  $this->total_quantite = 0;
207 
208  /* Montant total des produits dans le caddie */
209  $this->total_produit = 0;
210  $this->total_produit_ht = 0;
211  $this->tva_total_produit = 0;
212  $this->total_produit_avant_code_promo = 0;
213 
214  /* Poids total du caddie */
215  $this->total_poids = 0;
216 
217  /* Total des points cadeaux */
218  $this->total_points = 0;
219 
220  $this->cout_transport = 0;
221  $this->cout_transport_ht = 0;
222  $this->tva_cout_transport = 0;
223 
224  $this->total_remise = 0;
225  $this->total_remise_ht = 0;
226  $this->tva_total_remise = 0;
227 
228  $this->total_option = 0;
229  $this->total_option_ht = 0;
230  $this->tva_total_option = 0;
231  $this->total_reduction_percent_code_promo = 0;
232  /* Nom du code promo */
233  $this->code_promo = "";
234  // NE PAS FAIRE $this->percent_remise_user = 0; : c'est le seul attribut à ne pas initialiser car défini dans le cosntructeur
235  $this->percent_code_promo = 0;
236  $this->valeur_code_promo = 0;
237 
238  /* Avoir client en EURO */
239  $this->avoir = 0;
240  $this->avoir_user = 0;
241  // type est ici le nom du type de livraison (en base de données, la colonne type est une id qui s'appelle ici typeId)
242  $this->type = "";
243  $this->typeId = "";
244  // zone est ici le nom de la zone de livraison (en base de données, la colonne zone est une id qui s'appelle ici zoneId)
245  $this->zone = "";
246  $this->zoneId = "";
247  // Valeur par défaut : on applique la TVA, tant qu'une zone n'est pas encore sélectionnée ce qui permettra de savoir si la TVA est bien applicable ou non
248  $this->zoneTva = 1;
249  $this->apply_vat = true;
250  $this->zoneFranco = 1;
251  $this->zone_technical_code = "";
252 
253  $this->payment_technical_code = '';
254  $this->tarif_paiement = 0;
255  $this->tarif_paiement_ht = 0;
256  $this->tva_tarif_paiement = 0;
257 
258  $this->total_ecotaxe_ttc = 0;
259  $this->total_ecotaxe_ht = 0;
260  $this->tva_total_ecotaxe = 0;
261 
262  $this->message_caddie = array();
263 
264  $this->commande_id = 0;
265  $this->commande_hash = '';
266 
267  $this->pallet_count = 0;
268  $this->global_percent_pallet_filled = 0;
269 
270  $this->delivery_orderid = String::substr(sha1(mt_rand(1, 10000000)), 0, 16);
271  if($load_from_caddie_cookie_if_available) {
272  if (!empty($GLOBALS['site_parameters']['save_caddie_in_cookie']) && !empty($_COOKIE[$GLOBALS['caddie_cookie_name']])) {
273  // Le panier vient d'être initialisé. Si un cookie qui contient des produits n'est pas vide, il faut remplir le panier avec les informations du cookie si le paramétrage de la boutique le permet.
274  $product_in_caddie_cookie = @unserialize($_COOKIE[$GLOBALS['caddie_cookie_name']]);
275  foreach ($product_in_caddie_cookie as $this_product_info) {
276  // Il ne faut pas mettre les données stockées dans le cookie directement dans le panier. Les données dans le cookies peuvent être erronées, ou frauduleuses.
277  $product_object = new Product($this_product_info['product_id'], null, false, null, true, !is_user_tva_intracom_for_no_vat() && !check_if_module_active('micro_entreprise'));
278  $product_object->set_configuration($this_product_info['couleurId'], $this_product_info['tailleId'], $this_product_info['id_attribut'], check_if_module_active('reseller') && is_reseller());
279  $this->add_product($product_object, $this_product_info['quantite'], $email_check, $listcadeaux_owner);
280  unset($product_object);
281  }
282  }
283  } elseif($erase_caddie_cookie) {
284  if (!empty($_COOKIE[$GLOBALS['caddie_cookie_name']])) {
285  // Il faut supprimer le cookie qui contient les produits du panier, sinon le caddie est automatiquement rechargé dans init().
286  unset($_COOKIE[$GLOBALS['caddie_cookie_name']]);
287  }
288  }
289  // Au cas où certaines variables ne seraient pas bien nettoyées, on recalcule l'ensemble pour assurer une parfaite cohérence
290  $this->update();
291  }
292 
299  {
300  if (count($this->message_caddie) > 0) {
301  if (!empty($this->message_caddie['ERROR_CODE_PROMO'])) {
302  echo $GLOBALS['tplEngine']->createTemplate('global_error.tpl', array('message' => String::html_entity_decode_if_needed($this->message_caddie['ERROR_CODE_PROMO'])))->fetch();
303  unset($this->message_caddie['ERROR_CODE_PROMO']);
304  }
305  if (!empty($this->message_caddie['SUCCES_CODE_PROMO'])) {
306  echo $GLOBALS['tplEngine']->createTemplate('global_success.tpl', array('message' => String::html_entity_decode_if_needed($this->message_caddie['SUCCES_CODE_PROMO'])))->fetch();
307  unset($this->message_caddie['SUCCES_CODE_PROMO']);
308  }
309  }
310  }
311 
322  function add_product(&$product_object, $added_quantity_wished, $email_check, $listcadeaux_owner = null, $custom_product_reference = null)
323  {
324  if(empty($GLOBALS['site_parameters']['allow_float_quantity'])) {
325  $added_quantity_wished = intval($added_quantity_wished);
326  }
327  if (in_array($product_object->id, $this->articles) && empty($email_check)) {
328  // Si le produit est dans le caddie, et que ce n'est pas un chèque cadeau, alors on va vouloir fusionner les données dans une même ligne
329  foreach ($this->articles as $k => $this_produit_id) {
330  if ($product_object->id == $this_produit_id && $product_object->configuration_color_id == $this->couleurId[$k] && $product_object->configuration_size_id == $this->tailleId[$k] && $product_object->configuration_attributs_list == $this->id_attribut[$k]) {
331  $numero_ligne = $k;
332  break;
333  }
334  }
335  }
336  if (check_if_module_active('listecadeau') && $listcadeaux_owner !== null && $this->giftlist_owners[$numero_ligne] != $listcadeaux_owner) {
337  // on teste pour qui est destiné le cadeau, et on ne fusionne pas deux lignes pour deux destinataires différents
338  unset($numero_ligne);
339  }
340  if (isset($numero_ligne)) {
341  // Le produit est déjà dans le panier avec la bonne configuration de couleur et de taille
342  $quantite_start = $this->quantite[$numero_ligne];
343  if (check_if_module_active('listecadeau') && $listcadeaux_owner !== null) {
344  // destinataire déjà répertorié
345  // on regarde ses besoins en quantité
346  $quantity_wished = min($this->quantite[$numero_ligne] + $added_quantity_wished, getNessQuantityFromGiftList($this->articles[$numero_ligne], $product_object->configuration_color_id, $product_object->configuration_size_id, $this->giftlist_owners[$numero_ligne]));
347  } else {
348  $quantity_wished = $this->quantite[$numero_ligne] + $added_quantity_wished;
349  }
350  } else {
351  // On ajoute le produit au panier : une nouvelle ligne doit être créée dans le panier
352  $quantite_start = 0;
353  if (!isset($this->articles[0])) {
354  $numero_ligne = 0;
355  } else {
356  $numero_ligne = max(array_keys($this->articles)) + 1;
357  }
358  $this->conditionnement[$numero_ligne] = $product_object->conditionnement;
359  $quantity_wished = $added_quantity_wished;
360  }
361 
362  $this->reference[$numero_ligne] = $custom_product_reference;
363  // On met à jour la ligne du caddie
364  // Si module de gestion de stock présent : on fait la gestion de stock temporaire et la vérification aussi avec les stocks réels
365  $this->change_line_data($numero_ligne, $product_object->id, $quantity_wished, $product_object->configuration_color_id, $product_object->configuration_size_id, $email_check, $product_object->configuration_attributs_list, $listcadeaux_owner);
366 
367  // On renvoie la quantité réellement ajoutée
368  return $this->quantite[$numero_ligne] - $quantite_start;
369  }
370 
377  function change_lines_data(&$line_infos)
378  {
379  if (!empty($line_infos['id'])) {
380  foreach ($line_infos['id'] as $numero_ligne => $product_id) {
381  if (!empty($this->articles[$numero_ligne])) {
382  $this->change_line_data($numero_ligne, $product_id, get_float_from_user_input(vn($line_infos['quantite'][$numero_ligne])), vn($line_infos['couleurId'][$numero_ligne]), vn($line_infos['tailleId'][$numero_ligne]), vb($line_infos['email_check'][$numero_ligne]), vn($line_infos['id_attribut'][$numero_ligne]), vb($line_infos['listcadeaux_owner'][$numero_ligne]));
383  }
384  }
385  }
386  // On recalcule tout, notamment pour les frais de port
387  // Par ailleurs à la fin de l'update, on va éventuellement rediriger vers la page de caddie si une quantité demandée n'a pas été donnée car pas en stock
388  $this->update();
389  }
390 
405  function change_line_data($numero_ligne, $product_id, $quantity_wished, $couleur_id, $taille_id, $email_check, $liste_attribut, $listcadeaux_owner = null, $do_update_line = true)
406  {
407  if (!is_numeric($numero_ligne)) {
408  return false;
409  }
410  if(empty($GLOBALS['site_parameters']['allow_float_quantity'])) {
411  $quantity_wished = intval($quantity_wished);
412  }
413  $this->articles[$numero_ligne] = $product_id;
414  // Si on gère les stocks pour ce produit, la valeur $quantite est temporaire avant validation du stock disponible
415  // $added_quantity_wished peut être négative, nulle ou positive suivant évolution depuis dernière mise à jour du caddie
416  $added_quantity_wished = $quantity_wished - vn($this->quantite[$numero_ligne]);
417  $this->couleurId[$numero_ligne] = $couleur_id;
418  $this->tailleId[$numero_ligne] = $taille_id;
419  $this->email_check[$numero_ligne] = $email_check;
420  $this->id_attribut[$numero_ligne] = $liste_attribut;
421  $this->giftlist_owners[$numero_ligne] = $listcadeaux_owner;
422  if (!empty($do_update_line)) {
423  // On appelle update_line pour mettre à jour les autres colonnes, telles que $this->etat_stock[$numero_ligne] qui sert pour les stocks ci-dessous
424  $this->update_line($numero_ligne, $this->get_available_point_for_current_line($numero_ligne));
425  }
426  // Que la valeur de commande_id soit définie ou pas, on continue à faire vivre l'évaluation des variables de stock temporaire
427  if(check_if_module_active('stock_advanced') && vb($this->etat_stock[$numero_ligne]) == 1) {
428  // Le module de gestion des stocks est activé et le produit a on_stock=1 ($this->etat_stock[$numero_ligne] est la valeur de on_stock du produit)
429  // On réserve des stocks temporaires pour les nouvelles informations de la ligne
430  // Si nécessaire on rectifie la quantité dans le panier en fonction de ce qui a pu être réservé après vérification des stocks temporaires et réels
431 
432  if (check_if_module_active('conditionnement') && !empty($this->conditionnement[$numero_ligne])) {
433  $this->quantite[$numero_ligne] += Conditionnement::reservation_stock_temp($this, $numero_ligne, $product_id, $couleur_id, $taille_id, $added_quantity_wished);
434  } else {
435  $this->quantite[$numero_ligne] += reservation_stock_temp($product_id, $couleur_id, $taille_id, $added_quantity_wished);
436  }
437  } else {
438  $this->quantite[$numero_ligne] += $added_quantity_wished;
439  }
440  if($this->quantite[$numero_ligne]<$quantity_wished) {
441  // Si on ne peut pas allouer la quantité souhaitée, alors nous redirigerons l'utilisateur vers le caddie pour que l'utilisateur se rende compte de l'état du caddie
442  // Mais on ne pourra le faire qu'uniquement après avoir tout traité, et seulement si ça semble adapté
443  $GLOBALS['quantity_wished_not_fulfilled'] = true;
444  }
445  // Si on veut avoir les totaux de cette ligne et du caddie, il faut appeler par la suite $this->update();
446  // On ne le fait pas après chaque ligne pour éviter surcharge inutile
447  }
448 
456  {
457  $max_available_gift_points = intval(vn($_SESSION['session_utilisateur']['points']));
458  foreach ($this->articles as $numero_ligne => $product_id) {
459  if($numero_ligne !== $this_line) {
460  $product_object = new Product($this->articles[$numero_ligne], null, false, null, true, $this->apply_vat);
461  $product_object->set_configuration($this->couleurId[$numero_ligne], $this->tailleId[$numero_ligne], $this->id_attribut[$numero_ligne], check_if_module_active('reseller') && is_reseller());
462  if(!empty($product_object->on_gift) && $product_object->on_gift_points > 0 && empty($this->prix_cat[$numero_ligne])) {
463  // Produit cadeau qui est mis dans caddie gratuitement avec les points disponibles
464  $max_available_gift_points -= $product_object->on_gift_points * $this->quantite[$numero_ligne];
465  }
466  }
467  }
468  return $max_available_gift_points;
469  }
470 
478  function update_line($numero_ligne, $max_available_gift_points)
479  {
480  $product_object = new Product($this->articles[$numero_ligne], null, false, null, true, $this->apply_vat);
481  $product_object->set_configuration($this->couleurId[$numero_ligne], $this->tailleId[$numero_ligne], $this->id_attribut[$numero_ligne], check_if_module_active('reseller') && is_reseller());
482  if(check_if_module_active('stock_advanced') && $product_object->etat_stock == 1) {
483  // Le module de gestion des stocks est activé et le produit a on_stock=1 ($product_object->etat_stock est la valeur de on_stock du produit)
484  // On réserve des stocks temporaires pour les nouvelles informations de la ligne
485  // Si nécessaire on rectifie la quantité dans le panier en fonction de ce qui a pu être réservé après vérification des stocks temporaires et réels.
486  if (empty($GLOBALS['site_parameters']['allow_add_product_with_no_stock_in_cart'])) {
487  // Dans le cas d'un timemax faible, si un produit avec un exemplaire en stock est commandé par un premier utilisateur, le produit sera à nouveau disponible si l'uilisateur fait une pause longue sur les pages de process de commande après le panier. Le produit pourra alors être à nouveau ajouté au panier par un autre utilisateur. On se retrouvera avec 2 panier avec ce produit qui est pourtant disponible en un seul exemplaire.
488  // => pour cette raison il faut vérifier à chaque mise à jour du panier si le produit est disponible dans le stock temporaire, et mettre la quantité à jour en fonction. Un utilisateur risque de voir son produit disparaitre de son panier sans comprendre pourquoi. Il faudra dans ce cas augmenter le timemax.
489  $quantity_wished = min($this->quantite[$numero_ligne], get_stock($product_object->id, $product_object->configuration_color_id, $product_object->configuration_size_id, 0));
490  if ($quantity_wished != $this->quantite[$numero_ligne]) {
491  // Si la quantité est différente, il faut mettre à jour le stock temporaire puis la quantité dans le panier via la fonction change_line_data
492  // $this->email_check[$numero_ligne] : le but est de contrôler la quantité, donc l'email check est repris des infos déjà dans le panier.
493  $this->change_line_data($numero_ligne, $product_object->id, $quantity_wished, $product_object->configuration_color_id, $product_object->configuration_size_id, $this->email_check[$numero_ligne], $product_object->configuration_attributs_list, null, false);
494  // On ne peut pas garder la quantité souhaitée car pas en stock réellement, alors nous redirigerons l'utilisateur vers le caddie pour que l'utilisateur se rende compte de l'état du caddie
495  // Mais on ne pourra le faire qu'uniquement après avoir tout traité, et seulement si ça semble adapté
496  $GLOBALS['quantity_wished_not_fulfilled'] = true;
497  }
498  }
499  }
500  if(!empty($product_object->on_gift) && $product_object->on_gift_points > 0) {
501  // Produit cadeau qui est susceptible d'être mis dans caddie gratuitement avec les points disponibles
502  $gift_max_quantity = floor($max_available_gift_points / $product_object->on_gift_points);
503  if($gift_max_quantity>=1 || $product_object->get_final_price(get_current_user_promotion_percentage(), display_prices_with_taxes_active(), check_if_module_active('reseller') && is_reseller()) == 0) {
504  // on limite la quantité au max possible payable avec les points dans 2 cas :
505  // - quantité prenable avec les points non nulle => ce mode de paiement a priorité
506  // - OU prix nul => produit pas commandable par ailleurs
507  $this->quantite[$numero_ligne] = min($this->quantite[$numero_ligne], $gift_max_quantity);
508  } else {
509  // On retire la propriété de cadeau au produit, car il a un prix et l'utilisateur n'a pas les points pour l'avoir gratuitement
510  $product_object->on_gift = 0;
511  $product_object->on_gift_points = 0;
512  }
513  }
514  /* Traitement de l'ecotaxe */
515  $this->delai_stock[$numero_ligne] = $product_object->delai_stock;
516  // Attention : etat_stock de Caddie est on_stock du produit
517  $this->etat_stock[$numero_ligne] = $product_object->on_stock;
518  $this->ecotaxe_ht[$numero_ligne] = $product_object->ecotaxe_ht;
519  if (check_if_module_active('gifts')) {
520  // Total points de la ligne
521  $this->points[$numero_ligne] = $product_object->points * $this->quantite[$numero_ligne];
522  }
523  if ($this->apply_vat) {
524  // Si la zone de TVA est active
525  $this->tva_percent[$numero_ligne] = $product_object->tva;
526  $this->ecotaxe_ttc[$numero_ligne] = $product_object->ecotaxe_ttc;
527  $apply_vat = true;
528  } else {
529  // Si zone hors TVA, on ne doit pas facturer la TVA de l'ecotaxe
530  $this->tva_percent[$numero_ligne] = 0;
531  $this->ecotaxe_ttc[$numero_ligne] = $product_object->ecotaxe_ht;
532  $apply_vat = false;
533  }
534  if (check_if_module_active('attributs')) {
535  // Ces valeurs servent pour remplir la table peel_commandes, mais pas pour les calculs qui se servent de la classe Product qui gère tout cela
536  $this->total_prix_attribut[$numero_ligne] = $product_object->format_prices($product_object->configuration_total_original_price_attributs_ht, $apply_vat, false, false, false);
537  $this->attribut[$numero_ligne] = $product_object->configuration_attributs_description;
538  } else {
539  $this->total_prix_attribut[$numero_ligne] = null;
540  $this->attribut[$numero_ligne] = null;
541  }
542  // Les valeurs des options ne contiennent pas les éventuelles réductions en pourcentage
543  $this->option_ht[$numero_ligne] = $product_object->format_prices($product_object->configuration_size_price_ht + $product_object->configuration_total_original_price_attributs_ht, false, false, false, false);
544  $this->option[$numero_ligne] = $product_object->format_prices($product_object->configuration_size_price_ht + $product_object->configuration_total_original_price_attributs_ht, $apply_vat, false, false, false);
545  // Total poids de la ligne
546  $this->poids[$numero_ligne] = ($product_object->poids + $product_object->configuration_overweight) * $this->quantite[$numero_ligne];
547  // Calcul du prix original avant réductions et options
548  $this->prix_cat_ht[$numero_ligne] = $product_object->get_original_price(false, check_if_module_active('reseller') && is_reseller(), false, false, true, false);
549  $this->prix_cat[$numero_ligne] = $product_object->get_original_price($apply_vat, check_if_module_active('reseller') && is_reseller(), false, false, true, false);
551  // On doit arrondir les valeurs tarifaires officielles qui sont en TTC
552  $this->prix_cat[$numero_ligne] = round($this->prix_cat[$numero_ligne], 2);
553  $this->option[$numero_ligne] = round($this->option[$numero_ligne], 2);
554  $this->ecotaxe_ttc[$numero_ligne] = round($this->ecotaxe_ttc[$numero_ligne], 2);
555  } else {
556  // On doit arrondir les valeurs tarifaires officielles qui sont en HT
557  $this->prix_cat_ht[$numero_ligne] = round($this->prix_cat_ht[$numero_ligne], 2);
558  $this->option_ht[$numero_ligne] = round($this->option_ht[$numero_ligne], 2);
559  $this->ecotaxe_ht[$numero_ligne] = round($this->ecotaxe_ht, 2);
560  }
561  // NB : on n'applique pas ici la ventilation d'un code promo en valeur sur le nouveau produit, car le calcul concerne forcément tout le panier en même temps
562  // On fait donc cela dans la fonction update
563  // On n'applique pas non plus les codes promos de réductions en pourcentage ici pour tout faire au même endroit.
564  if (!empty($this->quantite[$numero_ligne])) {
565  // La variable prix_avant_code_promo sert pour connaître le montant acheté pour savoir si on peut appliquer ou non un code promo
566  // Pour tenir compte des prix par lots, on récupère le prix pour l'ensemble des produits et on divise par la quantité
567  if (check_if_module_active('conditionnement') && !empty($this->conditionnement[$numero_ligne])) {
568  $real_stock_used = $this->conditionnement[$numero_ligne] * $this->quantite[$numero_ligne];
569  } else {
570  $real_stock_used = intval($this->quantite[$numero_ligne]);
571  }
572  $this->prix_ht_avant_code_promo[$numero_ligne] = $product_object->get_final_price($this->percent_remise_user, false, check_if_module_active('reseller') && is_reseller(), false, false, $real_stock_used, true, true, false, $this->count_products($product_object->categorie_id)) / $real_stock_used;
573  $this->prix_avant_code_promo[$numero_ligne] = $product_object->get_final_price($this->percent_remise_user, $apply_vat, check_if_module_active('reseller') && is_reseller(), false, false, $real_stock_used, true, true, false,$this->count_products($product_object->categorie_id)) / $real_stock_used;
574  }
575  $this->percent_remise_produit[$numero_ligne] = $product_object->get_all_promotions_percentage(check_if_module_active('reseller') && is_reseller(), $this->percent_remise_user, false);
576  if(!empty($product_object->on_gift) && $product_object->on_gift_points * $this->quantite[$numero_ligne] <= $max_available_gift_points) {
577  foreach(array('ecotaxe', 'ecotaxe_ht', 'prix_cat', 'prix_cat_ht', 'option', 'option_ht', 'prix_ht_avant_code_promo', 'prix_avant_code_promo', 'percent_remise_produit') as $this_property) {
578  $this_temp = &$this->$this_property;
579  $this_temp[$numero_ligne] = 0;
580  }
581  $max_available_gift_points -= $product_object->on_gift_points * $this->quantite[$numero_ligne];
582  }
583  if (check_if_module_active('conditionnement') && !empty($product_object->unit_per_pallet)) {
584  // Calcul du pourcentage de remplissage de palette pour la ligne de produit. Le champ unit_per_pallet est actif uniqument si le module conditionnement est installé.
585  $this->global_percent_pallet_filled += ($real_stock_used*100)/$product_object->unit_per_pallet;
586  }
587  unset($product_object);
588  return $max_available_gift_points;
589  }
590 
597  function delete_line($numero_ligne)
598  {
599  $attributs_list = $this->id_attribut[$numero_ligne];
600  // Avant d'effacer la ligne, on met proprement la quantité à 0 pour gérer les stocks, etc.
601  $this->change_line_data($numero_ligne, vn($this->articles[$numero_ligne]), 0, vn($this->couleurId[$numero_ligne]), vn($this->tailleId[$numero_ligne]), vb($this->email_check[$numero_ligne]), vb($this->id_attribut[$numero_ligne]), vb($this->giftlist_owners[$numero_ligne]));
602  unset($this->giftlist_owners[$numero_ligne],
603  $this->articles[$numero_ligne],
604  $this->quantite[$numero_ligne],
605  $this->poids[$numero_ligne],
606  $this->points[$numero_ligne],
607  $this->couleurId[$numero_ligne],
608  $this->tailleId[$numero_ligne],
609  $this->prix[$numero_ligne],
610  $this->prix_ht[$numero_ligne],
611  $this->prix_cat[$numero_ligne],
612  $this->prix_cat_ht[$numero_ligne],
613  $this->prix_avant_code_promo[$numero_ligne],
614  $this->prix_ht_avant_code_promo[$numero_ligne],
615  $this->total_prix[$numero_ligne],
616  $this->total_prix_ht[$numero_ligne],
617  $this->tva_percent[$numero_ligne],
618  $this->tva[$numero_ligne],
619  $this->percent_remise_produit[$numero_ligne],
620  $this->remise[$numero_ligne],
621  $this->remise_ht[$numero_ligne],
622  $this->etat_stock[$numero_ligne],
623  $this->delai_stock[$numero_ligne],
624  $this->option[$numero_ligne],
625  $this->option_ht[$numero_ligne],
626  $this->email_check[$numero_ligne],
627  $this->ecotaxe_ttc[$numero_ligne],
628  $this->ecotaxe_ht[$numero_ligne],
629  $this->reference[$numero_ligne],
630  $this->id_attribut[$numero_ligne],
631  $this->attribut[$numero_ligne],
632  $this->total_prix_attribut[$numero_ligne]);
633  // Suppression des attributs d'image existants
634  if (!empty($attributs_list)) {
635  foreach(explode("§", $attributs_list) as $attribut_infos_list) {
636  $attribut_infos = explode("|", $attribut_infos_list);
637  if (!empty($attribut_infos[2])) {
638  // si c'est un attribut de type upload ou texte libre
639  delete_uploaded_file_and_thumbs($attribut_infos[2]);
640  }
641  }
642  }
643  }
644 
652  function update_code_promo($new_code_promo = null)
653  {
654  $this->total_produit_related_to_code_promo = 0;
655  $this->total_ecotaxe_ttc_related_to_code_promo = 0;
656  if ($new_code_promo !== null && $this->code_promo != $new_code_promo) {
657  $this->code_promo = $new_code_promo;
658  $code_promo_updated = true;
659  if ($new_code_promo === '') {
660  $this->message_caddie = array("SUCCES_CODE_PROMO" => $GLOBALS['STR_YOUR_CODE_PROMO'] . ' ' . $this->code_promo . ' ' . $GLOBALS['STR_HAS_BEEN_DELETED'] . '.');
661  }
662  }
663  if (!empty($this->code_promo)) {
664  // On vérifie d'abord la validité du code promo avec les paramètres insérés en back-office
665  // On trouve le code promo si il est valide dans l'absolu
666  // Restera à voir ensuite si il est bien valide pour l'utilisateur qui veut l'utiliser
667  $sql = "SELECT *
668  FROM `peel_codes_promos`
669  WHERE " . get_filter_site_cond('codes_promos') . " AND nom='" . nohtml_real_escape_string($this->code_promo) . "' AND (nombre_prevue=0 OR compteur_utilisation<nombre_prevue) AND '" . date('Y-m-d', time()) . "' BETWEEN `date_debut` AND `date_fin` AND etat = '1'";
670  $query = query($sql);
671  $code_infos = fetch_assoc($query);
672  if(!empty($code_promo_updated) && !empty($code_infos)) {
673  $this->message_caddie = array("SUCCES_CODE_PROMO" => $GLOBALS['STR_YOUR_CODE_PROMO'] . ' ' . $code_infos['nom'] . ' ' . $GLOBALS['STR_IS_VALID'] . '.');
674  }
675  }
676  // REMARQUE si on passe ici avec $new_code_promo non vide :
677  // alors on doit absolument s'assurer que toutes les infos sur les produits et les ecotaxes sont bien à jour (exemple : nouveau produit vient d'être ajouté)
678  // et donc dans ce cas on ne doit pas traiter maintenant la réduction, mais plus tard lorsque cette fonction sera appelée via update
679  if (!empty($code_infos) && $new_code_promo === null) {
680  // On traite un code promo qui est valide et ne vient pas d'être enregistré (cf. explications ci-dessus)
681  $this->code_infos = $code_infos;
682  if (!empty($code_infos['id_categorie'])) {
683  // Si le code ne s'applique qu'à une catégorie et à ses filles
684  $code_only_for_one_cat_and_sons = true;
685  } else {
686  $code_only_for_one_cat_and_sons = false;
687  }
688  foreach ($this->articles as $numero_ligne => $product_id) {
689  // On cherche le montant par catégorie de produit pour pouvoir appliquer ensuite
690  // des codes promos avec des seuils minimum sur une catégorie donnée
691  // On fait la somme des produits en faisant attention à ce qu'un produit pourrait apparaître dans plusieurs catégories donc on peut sommer les montants
692  $found_cat = null;
693  $product_object = new Product($this->articles[$numero_ligne]);
694  $apply_code_on_this_product = $product_object->is_code_promo_applicable($code_infos['id_categorie'], $code_infos['product_filter'], $found_cat, $code_infos['cat_not_apply_code_promo']);
695  unset($product_object);
696  if($apply_code_on_this_product) {
697  // ATTENTION : la somme de $this->total_produit_related_to_code_promo n'est pas égale au total du caddie si des produits se retrouvent dans plusieurs catégories
698  $this->total_produit_related_to_code_promo += $this->prix_avant_code_promo[$numero_ligne] * $this->quantite[$numero_ligne];
699  // On calcule l'écotaxe car on doit la retirer du montant sur lequel on applique un pourcentage de réduction
700  $this->total_ecotaxe_ttc_related_to_code_promo += $this->ecotaxe_ttc[$numero_ligne] * $this->quantite[$numero_ligne];
701  }
702  }
703  if ($code_only_for_one_cat_and_sons == false || ($code_only_for_one_cat_and_sons == true && !empty($found_cat))) {
704  // Si le code s'applique à toutes les catégories OU si le code s'applique à une seule catégorie et qu'il y a au moins un article de la catégorie correspondante dans le panier
705  // On vérifie maintenant que le code est bien valide pour l'utilisateur qui veut l'utiliser
706  $sql_check_cp_use = "SELECT c.id
707  FROM peel_commandes c
708  LEFT JOIN peel_statut_paiement sp ON sp.id=c.id_statut_paiement AND " . get_filter_site_cond('statut_paiement', 'sp') . "
709  WHERE c.code_promo = '" . nohtml_real_escape_string($this->code_promo) . "' AND c.id_utilisateur ='" . intval($_SESSION['session_utilisateur']['id_utilisateur']) . "' AND " . get_filter_site_cond('commandes', 'c') . ""
710  . (!empty($this->commande_id)? " AND c.id !='" . intval($this->commande_id) . "'" : "")
711  . " AND sp.technical_code NOT IN ('cancelled','refunded')";
712  // Le code a-t-il déjà été utilisé par ce client ?
713  $q_check_cp_use = query($sql_check_cp_use);
714  if (($code_infos['nombre_prevue'] == 0 || num_rows($q_check_cp_use) < $code_infos['nombre_prevue']) && ($code_infos['nb_used_per_client'] == 0 || num_rows($q_check_cp_use) < $code_infos['nb_used_per_client'])) {
715  // Si le code promotionnel n'a pas été trouvé dans une commande antérieure pour ce client, on passe à la suite.
716  if ($code_infos['montant_min'] <= $this->total_produit_related_to_code_promo) {
717  // Le code est OK : le montant minimum du code promotionnel est bien inférieur au montant total des catégories concernées par le code_promo
718  if ($code_infos['on_type'] == 1) {
719  $this->percent_code_promo = $code_infos['remise_percent'];
720  $this->valeur_code_promo = 0;
721  } elseif ($code_infos['on_type'] == 2) {
722  $this->percent_code_promo = 0;
723  // La réduction ne peut être plus importante que le montant des produits concernés
724  $this->valeur_code_promo = min($code_infos['remise_valeur'], $this->total_produit_avant_code_promo);
725  }
726  } else {
727  // Le code n'est pas pris en compte : le montant minimum du code promotionnel est supérieur au montant total des catégories concernées par le code_promo
728  $cancel_code = true;
729  if ($this->count_products()>0) {
730  $this->message_caddie = array("ERROR_CODE_PROMO" => nl2br($GLOBALS['STR_CART_IS_NOT_ENOUGHT']));
731  }
732  }
733  } else {
734  $cancel_code = true;
735  if ($this->count_products()>0) {
736  $this->message_caddie = array("ERROR_CODE_PROMO" => nl2br($GLOBALS['STR_CODE_PROMO_USE_ONLY_ONCE']));
737  }
738  }
739  } else {
740  $cancel_code = true;
741  if ($this->count_products()>0) {
742  $this->message_caddie = array("ERROR_CODE_PROMO" => nl2br($GLOBALS['STR_CODE_PROMO_IS_NOT_FOR_THIS_CAT']));
743  }
744  }
745  } elseif (empty($code_infos)) {
746  $cancel_code = true;
747  if (!empty($this->code_promo)) {
748  $this->message_caddie = array("ERROR_CODE_PROMO" => nl2br($GLOBALS['STR_ERR_CODE_PROMO']));
749  }
750  }
751 
752  if (!empty($cancel_code)) {
753  $this->code_promo = "";
754  $this->code_infos = array();
755  $this->percent_code_promo = 0;
756  $this->valeur_code_promo = 0;
757  }
758  // On veut appliquer les X euros de réduction par le code PROMO sur le panier en ventilant sur chaque produit indépendamment
759  // Par ailleurs le pourcentage de réduction est applicable au total des produits hors ecotaxe
760  $this->total_reduction_percent_code_promo = ($this->total_produit_related_to_code_promo - $this->total_ecotaxe_ttc_related_to_code_promo) * $this->percent_code_promo / 100;
761  $this->total_reduction_code_promo = $this->valeur_code_promo + $this->total_reduction_percent_code_promo;
762  }
763 
771  function count_products($cat_id = null)
772  {
773  $total = 0;
774  if (!empty($this->quantite)) {
775  foreach ($this->quantite as $numero_ligne => $qte) {
776  if ($cat_id !== null) {
777  if(!empty($this->articles[$numero_ligne])) {
778  $product_object = new Product($this->articles[$numero_ligne]);
779  if (!empty($product_object) && $product_object->categorie_id == $cat_id) {
780  // Quantité pour la catégorie.
781  $total += abs($qte);
782  }
783  }
784  } else {
785  $total += abs($qte);
786  }
787  }
788  }
789  return $total;
790  }
791 
798  function set_paiement($payment_technical_code)
799  {
800  // On définit ce nouveau moyen de paiement
801  $this->payment_technical_code = $payment_technical_code;
802  // On lance les calculs
803  $frm = array('payment_technical_code' => $this->payment_technical_code, 'sub_total' => $this->total - $this->tarif_paiement, 'sub_total_ht' => $this->total_ht - $this->tarif_paiement_ht);
805  $this->tarif_paiement_ht = $frm['tarif_paiement_ht'];
806  if ($this->apply_vat) {
807  $this->tarif_paiement = $frm['tarif_paiement'];
808  } else {
809  $this->tarif_paiement = $this->tarif_paiement_ht;
810  }
811  $this->tva_tarif_paiement = $this->tarif_paiement - $this->tarif_paiement_ht ;
812  }
813 
820  function set_zone($zoneId)
821  {
822  $zoneId = intval($zoneId);
823  $sql = "SELECT nom_" . $_SESSION['session_langue'] . " AS nom, tva, on_franco, technical_code
824  FROM peel_zones z
825  WHERE id = '" . intval($zoneId) . "' AND " . get_filter_site_cond('zones', 'z') . "";
826  $query = query($sql);
827  if ($Zone = fetch_assoc($query)) {
828  if ($zoneId != $this->zoneId) {
829  // On initialise le type de port à blank car on a changé de zone ou de pays
830  $this->type = "";
831  $this->typeId = "";
832  }
833  $this->zone = $Zone['nom'];
834  $this->zone_technical_code = $Zone['technical_code'];
835  $this->zoneTva = $Zone['tva'];
836  $this->zoneFranco = $Zone['on_franco'];
837  $this->zoneId = $zoneId;
838  }
839  }
840 
847  function set_type($typeId)
848  {
849  $typeId = intval($typeId);
850  $type_name = get_delivery_type_name($typeId);
851  if ($type_name !== false) {
852  // On définit le type de port seulement si trouvé en BDD
853  $this->typeId = $typeId;
854  $this->type = $type_name;
855  } else {
856  $this->typeId = '';
857  $this->type = '';
858  }
859  }
860 
868  function update($percent_remise_user = null)
869  {
870  static $update_in_process;
871  // Evite les boucles infinies
872  if(!empty($update_in_process)) {
873  $skip_add_products = true;
874  }
875  $update_in_process = true;
876  if ($percent_remise_user !== null) {
877  $this->percent_remise_user = $percent_remise_user;
878  }
879  $this->apply_vat = ($this->zoneTva && !is_user_tva_intracom_for_no_vat() && !check_if_module_active('micro_entreprise'));
880  $max_available_gift_points = intval(vn($_SESSION['session_utilisateur']['points']));
881  // ETAPE 0 :
882  // On met d'abord à jour toutes les lignes et notamment les quantités si la gestion de stock est activée et qu'un stock vient de disparaitre depuis le dernier update du caddie
883  foreach ($this->articles as $numero_ligne => $product_id) {
884  $max_available_gift_points = $this->update_line($numero_ligne, $max_available_gift_points);
885  }
886  // INITIALISATION : On enlève tous les produits non valides
887  // c'est-à-dire ceux dont l'identifiant n'est pas numérique ou dont la quantité est < 1
888  foreach ($this->quantite as $numero_ligne => $qte) {
889  if ($qte < 1) {
890  // Attention ici normalement on nettoie si la quantité commandée est < à 1
891  unset($this->giftlist_owners[$numero_ligne]);
892  unset($this->articles[$numero_ligne]);
893  unset($this->quantite[$numero_ligne]);
894  unset($this->poids[$numero_ligne]);
895  unset($this->points[$numero_ligne]);
896  unset($this->couleurId[$numero_ligne]);
897  unset($this->tailleId[$numero_ligne]);
898  unset($this->prix_avant_code_promo[$numero_ligne]);
899  unset($this->prix_ht_avant_code_promo[$numero_ligne]);
900  unset($this->prix[$numero_ligne]);
901  unset($this->prix_ht[$numero_ligne]);
902  unset($this->prix_cat[$numero_ligne]);
903  unset($this->prix_cat_ht[$numero_ligne]);
904  unset($this->total_prix[$numero_ligne]);
905  unset($this->total_prix_ht[$numero_ligne]);
906  unset($this->tva_percent[$numero_ligne]);
907  unset($this->tva[$numero_ligne]);
908  unset($this->percent_remise_produit[$numero_ligne]);
909  unset($this->remise[$numero_ligne]);
910  unset($this->remise_ht[$numero_ligne]);
911  unset($this->etat_stock[$numero_ligne]);
912  unset($this->delai_stock[$numero_ligne]);
913  unset($this->option[$numero_ligne]);
914  unset($this->option_ht[$numero_ligne]);
915  unset($this->email_check[$numero_ligne]);
916  unset($this->ecotaxe_ttc[$numero_ligne]);
917  unset($this->ecotaxe_ht[$numero_ligne]);
918  unset($this->reference[$numero_ligne]);
919  unset($this->id_attribut[$numero_ligne]);
920  unset($this->attribut[$numero_ligne]);
921  unset($this->total_prix_attribut[$numero_ligne]);
922  }
923  }
924 
925  $this->avoir_user = max(vn($_SESSION['session_utilisateur']['avoir']), 0);
926  $this->global_percent_pallet_filled = 0;
927  // ETAPE 1 : On calcule les totaux avant réduction
928  foreach ($this->articles as $numero_ligne => $product_id) {
929  $this->total_ecotaxe_ttc += $this->ecotaxe_ttc[$numero_ligne] * $this->quantite[$numero_ligne];
930  $this->total_ecotaxe_ht += $this->ecotaxe_ht[$numero_ligne] * $this->quantite[$numero_ligne];
931  if (check_if_module_active('conditionnement') && !empty($this->conditionnement[$numero_ligne])) {
932  $real_stock_used = $this->conditionnement[$numero_ligne] * $this->quantite[$numero_ligne];
933  } else {
934  $real_stock_used = intval($this->quantite[$numero_ligne]);
935  }
936  $this->total_produit_avant_code_promo += $this->prix_avant_code_promo[$numero_ligne] * $real_stock_used;
937  }
938  // ETAPE 2 : maintenant qu'on connait le montant total avant réduction pour les produits et chaque catégorie de produits,
939  // on vérifie si le code promotionnel est toujours actif après un changement de montant total du caddie.
940  $this->update_code_promo();
941 
942  if (empty($this->code_infos) && !empty($GLOBALS['site_parameters']['cart_offer_products_for_each_lot_count'])) {
943  // L'exonération de produits en fonction du nombre ajouté au panier est active. Il faut mettre à 0 le montant des produits les moins chères si les conditions sont réunis pour le faire :
944  // Sur N produits achetés, le moins cher des N est offert. Cette opération est cumulable : pour 2*N produits / 2 offerts, etc.
945  // On commence par calculer le nombre de produits à offrir, puis on regarde les moins chers du caddie en tenant compte des quantités dans le panier.
946  $free_cost_cart_nb_product = floor($this->count_products()/$GLOBALS['site_parameters']['cart_offer_products_for_each_lot_count']);
947  if(!empty($free_cost_cart_nb_product)) {
948  // Récupération des prix de tous les produits dans le caddie
949  foreach($this->articles as $numero_ligne => $product_id) {
950  $this_quantity = $this->quantite[$numero_ligne];
951  while($this_quantity--) {
952  $prices_offered_array[] = $this->prix_avant_code_promo[$numero_ligne];
953  }
954  }
955  // Récupération des $free_cost_cart_nb_product produits les moins chers. La fonction sort réinitialise les clés.
956  sort($prices_offered_array);
957  foreach($prices_offered_array as $this_item => $this_price) {
958  if($this_item>=$free_cost_cart_nb_product) {
959  // Le tableau est trié dans l'ordre, on conserve les $free_cost_cart_nb_product dans le tableau
960  unset($prices_offered_array[$this_item]);
961  }
962  }
963  }
964  }
965  // Recalcul des produits en appliquant correctement les ventilations des codes promos
966  foreach ($this->articles as $numero_ligne => $product_id) {
967  $promotion_ventile_ttc = 0;
968  // Gestion du code promo
969  if (!empty($this->total_produit_related_to_code_promo) && !empty($this->code_infos)) {
970  $found_cat = null;
971  $product_object = new Product($this->articles[$numero_ligne]);
972  $apply_code_on_this_product = $product_object->is_code_promo_applicable($this->code_infos['id_categorie'], $this->code_infos['product_filter'], $found_cat, $this->code_infos['cat_not_apply_code_promo']);
973  unset($product_object);
974  if ($apply_code_on_this_product) {
975  // Panier au montant non nul et code promo s'appliquant au total du panier ou à une catégorie et ses filles qui concernent au moins un produit du panier
976  $promotion_ventile_ttc = $this->total_reduction_code_promo * ($this->prix_avant_code_promo[$numero_ligne] * $this->quantite[$numero_ligne]) / $this->total_produit_related_to_code_promo;
977  }
978  } elseif (!empty($prices_offered_array)) {
979  // On calcule le nombre de produits offerts au prix unitaire correspondant à la ligne en cours, et on les prend en compte tant que le décompte prévu n'est pas atteint
980  // Attention : il peut y avoir plusieurs produits dans le panier avec le même prix, d'où le raisonnement par prix et non pas par produit
981  $this_quantity_offered = 0;
982  while(!empty($prices_offered_array) && in_array($this->prix_avant_code_promo[$numero_ligne], $prices_offered_array)) {
983  $this_quantity_offered++;
984  unset($prices_offered_array[array_search($this->prix_avant_code_promo[$numero_ligne], $prices_offered_array)]);
985  }
986  $promotion_ventile_ttc = $this->prix_avant_code_promo[$numero_ligne] * $this_quantity_offered;
987  } else {
988  // Panier au montant nul ou code promo à une catégorie non applicable au panier
989  }
990  // Le produit et l'ecotaxe ont potentiellement deux taux de TVA différents => quand on passe de HT à TTC il faut traiter l'ecotaxe à part
991  // Par ailleurs il faut arrondir les prix en TTC ou HT pour qu'ensuite l'application de quantités ne donne pas de problèmes d'arrondi
993  // On arrondit le prix TTC
994  $this->prix[$numero_ligne] = round($this->prix_avant_code_promo[$numero_ligne] - $promotion_ventile_ttc / $this->quantite[$numero_ligne], 2);
995  // On recalcule le prix HT à partir du prix TTC arrondi
996  $this->prix_ht[$numero_ligne] = ($this->prix[$numero_ligne] - $this->ecotaxe_ttc[$numero_ligne]) / (1 + $this->tva_percent[$numero_ligne] / 100) + $this->ecotaxe_ht[$numero_ligne];
997  } else {
998  // On arrondit le prix HT
999  $this->prix_ht[$numero_ligne] = round($this->prix_ht_avant_code_promo[$numero_ligne] - $promotion_ventile_ttc / $this->quantite[$numero_ligne] / (1 + $this->tva_percent[$numero_ligne] / 100), 2);
1000  // On recalcule le prix TTC à partir du prix HT arrondi
1001  $this->prix[$numero_ligne] = (($this->prix_ht[$numero_ligne] - $this->ecotaxe_ht[$numero_ligne]) * (1 + $this->tva_percent[$numero_ligne] / 100)) + $this->ecotaxe_ttc[$numero_ligne];
1002  }
1003  }
1004 
1005  // Calcul du total des lignes
1006  $this->_recalc_line_totals();
1007 
1008  // Calcul du pourcentage applicable en fonction du total des produits dans le panier
1009  if (check_if_module_active('lot') && !empty($GLOBALS['site_parameters']['global_promotion_percent_by_threshold'])) {
1010  // Tri des valeurs par ordre croissant, pour permettre la sélection du bon taux en fonction du montant total des produits
1011  asort($GLOBALS['site_parameters']['global_promotion_percent_by_threshold']);
1012  foreach ($GLOBALS['site_parameters']['global_promotion_percent_by_threshold'] as $promotion_percent => $threshold) {
1013  if ($threshold > $this->total_produit) {
1014  // Le seuil courant est strictement supérieur au total des produits => il faut sortir de la boucle. Le code promotionnel sauvegardé est celui de l'itération précedente
1015  break;
1016  }
1017  $this_global_promotion_percent_by_threshold = $promotion_percent;
1018  }
1019  // Application de réductions ventilées par ligne, quand on souhaite ne pas l'appliquer directement dans le calcul du prix d'un produit, mais dans la logique de caddie
1020  if(!empty($this_global_promotion_percent_by_threshold)) {
1021  foreach ($this->articles as $numero_ligne => $product_id) {
1022  // Gestion de la réduction
1023  $reduction_ventilee_ttc = ($this->prix[$numero_ligne] * $this->quantite[$numero_ligne])*($this_global_promotion_percent_by_threshold / 100) ;
1025  // On arrondit le prix TTC
1026  $this->prix[$numero_ligne] = round($this->prix[$numero_ligne] - $reduction_ventilee_ttc / $this->quantite[$numero_ligne], 2);
1027  // On recalcule le prix HT à partir du prix TTC arrondi
1028  $this->prix_ht[$numero_ligne] = ($this->prix[$numero_ligne] - $this->ecotaxe_ttc[$numero_ligne]) / (1 + $this->tva_percent[$numero_ligne] / 100) + $this->ecotaxe_ht[$numero_ligne];
1029  } else {
1030  // On arrondit le prix HT
1031  $this->prix_ht[$numero_ligne] = round($this->prix_ht[$numero_ligne] - $reduction_ventilee_ttc / $this->quantite[$numero_ligne] / (1 + $this->tva_percent[$numero_ligne] / 100), 2);
1032  // On recalcule le prix TTC à partir du prix HT arrondi
1033  $this->prix[$numero_ligne] = (($this->prix_ht[$numero_ligne] - $this->ecotaxe_ht[$numero_ligne]) * (1 + $this->tva_percent[$numero_ligne] / 100)) + $this->ecotaxe_ttc[$numero_ligne];
1034  }
1035  }
1036  // Calcul à nouveau du total des lignes, qui contiennent maintenant la réduction ventilée
1037  $this->_recalc_line_totals();
1038  }
1039  }
1040 
1041  // ETAPE 3 : On gère des éventuels frais supplémentaires si la commande est trop petite
1042  if(a_priv('reve') && isset($GLOBALS['site_parameters']['minimal_amount_to_order_reve'])) {
1043  $treshold_to_use = $GLOBALS['site_parameters']['minimal_amount_to_order_reve'];
1044  } else {
1045  $treshold_to_use = vn($GLOBALS['site_parameters']['minimal_amount_to_order']);
1046  }
1047  if (count($this->articles) && $this->total_produit < vn($GLOBALS['site_parameters']['small_order_overcost_limit']) && $this->total_produit >= $treshold_to_use) {
1048  $this->small_order_overcost_amount_ht = $GLOBALS['site_parameters']['small_order_overcost_amount'] / (1 + ($GLOBALS['site_parameters']['small_order_overcost_tva_percent'] / 100));
1049  if ($this->apply_vat) {
1050  $this->small_order_overcost_amount = $this->small_order_overcost_amount_ht * (1 + ($GLOBALS['site_parameters']['small_order_overcost_tva_percent'] / 100));
1051  } else {
1052  $this->small_order_overcost_amount = $this->small_order_overcost_amount_ht;
1053  }
1054  $this->tva_small_order_overcost = $this->small_order_overcost_amount - $this->small_order_overcost_amount_ht;
1055  } else {
1056  $this->small_order_overcost_amount_ht = 0;
1057  $this->small_order_overcost_amount = 0;
1058  $this->tva_small_order_overcost = 0;
1059  }
1060  // ETAPE 4 : Calcul des frais de port
1061  if (!empty($this->typeId) && !empty($this->zoneId)) {
1062  $delivery_cost_infos = get_delivery_cost_infos($this->total_poids, $this->total_produit, $this->typeId, $this->zoneId, $this->count_products());
1063  }
1064  if(!empty($GLOBALS['site_parameters']['user_offers_table_enable']) && !empty($_SESSION['session_utilisateur']['id_utilisateur'])) {
1065  foreach ($this->articles as $numero_ligne => $product_id) {
1066  $product_object = new Product($product_id, null, false, null, true, $this->apply_vat);
1067  $sql = "SELECT o.*
1068  FROM peel_offres o
1069  LEFT JOIN peel_utilisateurs_offres uo ON uo.id_utilisateur='" . intval(vn($_SESSION['session_utilisateur']['id_utilisateur'])) . "' AND o.id_offre=uo.id_offre
1070  WHERE (o.id_offre=0 OR uo.id_offre IS NOT NULL) AND o.date_limite>='" . date('Y-m-d', time()) . "' AND (" . (!empty($product_object->reference)?"(o.ref='".real_escape_string($product_object->reference)."' AND o.qnte<='".intval($this->quantite[$numero_ligne])."' AND o.seuil<='".max(floatval($this->quantite[$numero_ligne]*$product_object->prix_ht), floatval($value_total))."') OR ":"") . "(o.ref='' AND o.fournisseur IN ('".implode("','", real_escape_string($product_object->get_product_brands(true)))."') AND o.qnte<='".intval($quantity_by_brand['brand_'.$product_object->get_product_brands(false)])."' AND o.seuil<='".max(floatval($total_by_brand['brand_'.$product_object->get_product_brands(false)]), floatval($value_total))."') OR (o.ref='' AND o.fournisseur='' AND o.qnte<='".intval($quantity_total)."' AND o.seuil<='".floatval($value_total)."'))
1071  ORDER BY " . (floatval($product_object->prix_ht)>0 ? "IF(o.prix>0 AND o.remise_percent>0, LEAST(o.prix, o.remise_percent*'".floatval($product_object->prix_ht)."'), IF(o.remise_percent>0, o.remise_percent*'".floatval($product_object->prix_ht)."', o.prix))" : "o.prix") . " DESC, o.remise_percent DESC, o.port_offert DESC, o.carbo_offert DESC
1072  LIMIT 1";
1073  $query = query($sql);
1074  if(($result = fetch_object($query)) && $result->port_offert == 1) {
1075  $delivery_cost_infos = false;
1076  break;
1077  }
1078  unset($product_object);
1079  }
1080  // Fin de l'usage des informations pour peel_offer : carboglace et frais de ports ont été étudiés
1081  unset($quantity_by_brand);
1082  unset($total_by_brand);
1083  unset($quantity_total);
1084  unset($value_total);
1085  }
1086  if (!isset($delivery_cost_infos) || $delivery_cost_infos === false) {
1087  // Pas de port à calculer pour l'instant, ou pas de frais de port trouvés pour ce poids et ce total (dans ce cas, ce n'est pas ici qu'on présente une erreur au client)
1088  $delivery_cost_infos = array('cost_ht' => 0, 'tva' => 0);
1089  }
1090  if (!empty($_SESSION['session_commande']['delivery_dyforwardingcharges'])) {
1091  // Coût Livraison So Colissimo, en € TTC
1092  $this->cout_transport_ht = $_SESSION['session_commande']['delivery_dyforwardingcharges'] / (1 + $delivery_cost_infos['tva'] / 100);
1093  } else {
1094  $this->cout_transport_ht = $delivery_cost_infos['cost_ht'];
1095  }
1096  $free_delivery_vat = false;
1097  if (!empty($GLOBALS['site_parameters']['delivery_vat_free_if_product_with_no_vat'])) {
1098  // Mode d'exonération de la TVA des frais de port si un produit n'a pas de TVA.
1099  foreach ($this->articles as $numero_ligne => $product_id) {
1100  if (empty($this->tva[$numero_ligne])) {
1101  // un produit n'a pas de TVA. On exonère la TVA pour le transport
1102  $free_delivery_vat = true;
1103  }
1104  }
1105  }
1106 
1107  if ($this->apply_vat && empty($free_delivery_vat)) {
1108  $this->cout_transport = $this->cout_transport_ht * (1 + $delivery_cost_infos['tva'] / 100);
1109  } else {
1110  $this->cout_transport = $this->cout_transport_ht;
1111  }
1112  $this->tva_cout_transport = $this->cout_transport - $this->cout_transport_ht;
1113 
1114  $this->total_tva = $this->tva_total_produit + $this->tva_cout_transport + $this->tva_tarif_paiement + $this->tva_small_order_overcost;
1115  // ETAPE 5 : gestion de l'avoir
1116  // L'avoir est limité au total de la commande.
1117  // L'avoir est uniquement sur le TTC et n'affecte pas le calcul de la TVA
1118  $this->avoir = max(0, min($this->avoir_user, $this->total_produit + $this->cout_transport + $this->tarif_paiement + $this->small_order_overcost_amount));
1119  // ETAPE 6 : finalisation des totaux
1120  $this->tva_total_option = $this->total_option - $this->total_option_ht;
1121  $this->tva_total_remise = $this->total_remise - $this->total_remise_ht;
1122  $this->tva_total_ecotaxe = $this->total_ecotaxe_ttc - $this->total_ecotaxe_ht;
1123  $this->total = $this->total_produit - $this->avoir + $this->cout_transport + $this->tarif_paiement + $this->small_order_overcost_amount;
1124  $this->total_ht = $this->total_produit_ht + $this->cout_transport_ht + $this->tarif_paiement_ht + $this->small_order_overcost_amount_ht;
1125 
1126  if (!empty($this->global_percent_pallet_filled)) {
1127  // Calcul du nombre total de palette à partir du pourcentage de remplissage. 100% = 1 palette.
1128  $this->pallet_count = ceil($this->global_percent_pallet_filled/100);
1129  }
1130 
1131  if (!empty($GLOBALS['site_parameters']['save_caddie_in_cookie'])) {
1132  // ETAPE 7 : Le contenu du panier est stocké dans un cookie, pour que l'utilisateurs puisse retrouver son panier après que la session soit expiré. Le panier est chargé avec les informations du cookie dans la fonction init
1133  if (isset($_COOKIE[$GLOBALS['caddie_cookie_name']])) {
1134  // Le cookie qui contient les produits est vidé à chaque calcul du caddie, c'est plus simple que de mettre à jour ligne par ligne.
1135  unset($_COOKIE[$GLOBALS['caddie_cookie_name']]);
1136  }
1137  $product_in_caddie_cookie = array();
1138  foreach ($this->articles as $numero_ligne => $product_id) {
1139  // on ajoute le produit à la liste.
1140  $product_in_caddie_cookie[] = array('quantite'=>$this->quantite[$numero_ligne],'product_id'=>$product_id,'couleurId'=>$this->couleurId[$numero_ligne],'tailleId'=>$this->tailleId[$numero_ligne],'id_attribut'=>$this->id_attribut[$numero_ligne]);
1141  }
1142  // on crée le cookie avec 1 an de vie
1143  if($GLOBALS['site_parameters']['force_sessions_for_subdomains']){
1144  @setcookie($GLOBALS['caddie_cookie_name'], serialize($product_in_caddie_cookie), time() + 365 * 24 * 60 * 60, '/', '.'.get_site_domain());
1145  } else {
1146  @setcookie($GLOBALS['caddie_cookie_name'], serialize($product_in_caddie_cookie), time() + 365 * 24 * 60 * 60, '/');
1147  }
1148  }
1149  // FIN
1150  $update_in_process = false;
1151  // Redirection en cas de problème de stock au dernier moment lors de la commande => on redirige vers la page de caddie
1152  if(!empty($GLOBALS['quantity_wished_not_fulfilled']) && (defined('IN_STEP1') || defined('IN_STEP2') || defined('IN_STEP3'))) {
1153  redirect_and_die(get_url('caddie_affichage'));
1154  }
1155  return true;
1156  }
1157 
1163  function _recalc_line_totals() {
1164  // On initialise les montants qu'on va recalculer
1165  $this->total = $this->total_ht = 0;
1166  $this->total_quantite = 0;
1167  $this->total_produit = $this->total_produit_ht = 0;
1168  $this->total_produit_avant_code_promo = 0;
1169  $this->total_option = $this->total_option_ht = $this->tva_total_option = 0;
1170  $this->total_tva = $this->tva_total_produit = 0;
1171  $this->total_poids = $this->total_points = 0;
1172  $this->total_remise = $this->total_remise_ht = $this->tva_total_remise = 0;
1173  $this->total_ecotaxe_ttc = $this->total_ecotaxe_ht = $this->tva_total_ecotaxe = 0;
1174  // Recalcul des totaux en appliquant correctement les ventilations des codes promos
1175  foreach ($this->articles as $numero_ligne => $product_id) {
1176  // Si le module conditionnement est présent, il faut prendre en compte le conditionnement dans le calcul du prix de la ligne.
1177  if (check_if_module_active('conditionnement') && !empty($this->conditionnement[$numero_ligne])) {
1178  $this->total_prix[$numero_ligne] = $this->prix[$numero_ligne] * $this->quantite[$numero_ligne] * $this->conditionnement[$numero_ligne];
1179  $this->total_prix_ht[$numero_ligne] = $this->prix_ht[$numero_ligne] * $this->quantite[$numero_ligne] * $this->conditionnement[$numero_ligne];
1180  } else {
1181  $this->total_prix[$numero_ligne] = $this->prix[$numero_ligne] * $this->quantite[$numero_ligne];
1182  $this->total_prix_ht[$numero_ligne] = $this->prix_ht[$numero_ligne] * $this->quantite[$numero_ligne];
1183  }
1184 
1185  if ($this->apply_vat) {
1186  $this->tva[$numero_ligne] = $this->total_prix[$numero_ligne] - $this->total_prix_ht[$numero_ligne];
1187  } else {
1188  $this->tva[$numero_ligne] = 0;
1189  }
1190  // Aucune remise ne s'applique sur l'ecotaxe
1191  // => on calcule la remise sur $prix_ht_no_ecotaxe qui est le prix hors ecotaxe
1192  if (check_if_module_active('conditionnement') && !empty($this->conditionnement[$numero_ligne])) {
1193  $real_stock_used = $this->conditionnement[$numero_ligne] * $this->quantite[$numero_ligne];
1194  } else {
1195  $real_stock_used = intval($this->quantite[$numero_ligne]);
1196  }
1197 
1198  $this->remise_ht[$numero_ligne] = ($this->prix_cat_ht[$numero_ligne] + $this->option_ht[$numero_ligne] - $this->prix_ht[$numero_ligne]) * $real_stock_used;
1199  $this->remise[$numero_ligne] = ($this->prix_cat[$numero_ligne] + $this->option[$numero_ligne] - $this->prix[$numero_ligne]) * $real_stock_used;
1200  $this->total_remise += $this->remise[$numero_ligne];
1201  $this->total_remise_ht += $this->remise_ht[$numero_ligne];
1202  $this->total_quantite += $this->quantite[$numero_ligne];
1203  $this->total_produit += $this->total_prix[$numero_ligne];
1204  $this->total_produit_ht += $this->total_prix_ht[$numero_ligne];
1205  $this->total_option += $this->option[$numero_ligne] * $real_stock_used;
1206  $this->total_option_ht += $this->option_ht[$numero_ligne] * $real_stock_used;
1207  $this->tva_total_produit += $this->tva[$numero_ligne];
1208  $this->total_poids += $this->poids[$numero_ligne];
1209  if (check_if_module_active('gifts')) {
1210  $this->total_points += $this->points[$numero_ligne];
1211  }
1212  }
1213  return true;
1214  }
1215 
1222  function save_in_database(&$order_infos)
1223  {
1224  // On s'assure des montants avant leur insertion en BDD
1225  $this->update();
1226  /* Le reversement affilié est calculé sur le total HT des produits */
1227  if (check_if_module_active('affiliation') && !empty($_SESSION['session_affilie']) && is_affiliation_active($_SESSION['session_affilie'])) {
1228  $order_infos['affilie'] = 1;
1229  $order_infos['statut_affilie'] = 0;
1230  $order_infos['montant_affilie'] = $this->total_produit * $GLOBALS['site_parameters']['commission_affilie'] / 100;
1231  $order_infos['id_affilie'] = intval($_SESSION['session_affilie']);
1232  } else {
1233  $order_infos['affilie'] = 0;
1234  $order_infos['montant_affilie'] = 0;
1235  $order_infos['statut_affilie'] = 0;
1236  $order_infos['id_affilie'] = 0;
1237  }
1238  foreach(array('total_option',
1239  'total_option_ht',
1240  'tva_total_option',
1241  'total_produit',
1242  'total_produit_ht',
1243  'tva_total_produit',
1244  'code_promo',
1245  'percent_remise_user',
1246  'percent_code_promo',
1247  'valeur_code_promo',
1248  'total_remise',
1249  'total_remise_ht',
1250  'tva_total_remise',
1251  'total_tva',
1252  'cout_transport',
1253  'cout_transport_ht',
1254  'tva_cout_transport',
1255  'total_points',
1256  'total_poids',
1257  'total_ecotaxe_ttc',
1258  'total_ecotaxe_ht',
1259  'tva_total_ecotaxe',
1260  'avoir',
1261  'payment_technical_code',
1262  'apply_vat',
1263  'tarif_paiement',
1264  'tarif_paiement_ht',
1265  'tva_tarif_paiement',
1266  'zoneFranco',
1267  'pays',
1268  'zoneId',
1269  'type',
1270  'typeId',
1271  'small_order_overcost_amount',
1272  'tva_small_order_overcost') as $this_item) {
1273  $order_infos[$this_item] = $this->$this_item;
1274  }
1275  $order_infos['montant'] = $this->total;
1276  $order_infos['montant_ht'] = $this->total_ht;
1277  $order_infos['id_utilisateur'] = vb($_SESSION['session_utilisateur']['id_utilisateur']);
1278  $order_infos['id_parrain'] = vb($_SESSION['session_utilisateur']['id_parrain']);
1279  $order_infos['parrain'] = vb($_SESSION['session_utilisateur']['type']);
1280  $order_infos['devise'] = vb($_SESSION['session_devise']['code']);
1281  $order_infos['currency_rate'] = vb($_SESSION['session_devise']['conversion']);
1282  $order_infos['delivery_tracking'] = null;
1283  $order_infos['site_id'] = $GLOBALS['site_id'];
1284 
1285  $articles = array();
1286  foreach ($this->articles as $numero_ligne => $product_id) {
1287  // Attention ici normalement on nettoie si la quantité commandée est < à 1
1288  $articles[$numero_ligne]['product_id'] = $product_id;
1289  $articles[$numero_ligne]['quantite'] = $this->quantite[$numero_ligne];
1290  if (check_if_module_active('listecadeau')) {
1291  $articles[$numero_ligne]['giftlist_owners'] = $this->giftlist_owners[$numero_ligne];
1292  }
1293  $articles[$numero_ligne]['poids'] = $this->poids[$numero_ligne];
1294  $articles[$numero_ligne]['points'] = $this->points[$numero_ligne];
1295  $articles[$numero_ligne]['couleurId'] = $this->couleurId[$numero_ligne];
1296  $articles[$numero_ligne]['tailleId'] = $this->tailleId[$numero_ligne];
1297  if (check_if_module_active('conditionnement')) {
1298  $articles[$numero_ligne]['conditionnement'] = $this->conditionnement[$numero_ligne];
1299  }
1300  $articles[$numero_ligne]['prix'] = $this->prix[$numero_ligne];
1301  $articles[$numero_ligne]['prix_ht'] = $this->prix_ht[$numero_ligne];
1302  $articles[$numero_ligne]['prix_cat'] = $this->prix_cat[$numero_ligne];
1303  $articles[$numero_ligne]['prix_cat_ht'] = $this->prix_cat_ht[$numero_ligne];
1304  $articles[$numero_ligne]['total_prix'] = $this->total_prix[$numero_ligne];
1305  $articles[$numero_ligne]['total_prix_ht'] = $this->total_prix_ht[$numero_ligne];
1306  $articles[$numero_ligne]['tva_percent'] = $this->tva_percent[$numero_ligne];
1307  $articles[$numero_ligne]['tva'] = $this->tva[$numero_ligne];
1308  $articles[$numero_ligne]['percent_remise_produit'] = $this->percent_remise_produit[$numero_ligne];
1309  $articles[$numero_ligne]['remise'] = $this->remise[$numero_ligne];
1310  $articles[$numero_ligne]['remise_ht'] = $this->remise_ht[$numero_ligne];
1311  $articles[$numero_ligne]['etat_stock'] = $this->etat_stock[$numero_ligne];
1312  $articles[$numero_ligne]['delai_stock'] = $this->delai_stock[$numero_ligne];
1313  $articles[$numero_ligne]['option'] = $this->option[$numero_ligne];
1314  $articles[$numero_ligne]['option_ht'] = $this->option_ht[$numero_ligne];
1315  $articles[$numero_ligne]['email_check'] = $this->email_check[$numero_ligne];
1316  $articles[$numero_ligne]['ecotaxe_ttc'] = $this->ecotaxe_ttc[$numero_ligne];
1317  $articles[$numero_ligne]['ecotaxe_ht'] = $this->ecotaxe_ht[$numero_ligne];
1318  $articles[$numero_ligne]['reference'] = $this->reference[$numero_ligne];
1319  $articles[$numero_ligne]['attribut'] = vb($this->attribut[$numero_ligne]);
1320  $articles[$numero_ligne]['id_attribut'] = vb($this->id_attribut[$numero_ligne]);
1321  $articles[$numero_ligne]['total_prix_attribut'] = vb($this->total_prix_attribut[$numero_ligne]);
1322  }
1323  if (sha1(serialize($order_infos) . serialize($articles)) != $this->commande_hash) {
1324  // La commande n'avait jamais été créée, ou les informations de la commande sont différentes
1325  $this->commande_hash = sha1(serialize($order_infos) . serialize($articles));
1326 
1327  $order_id = create_or_update_order($order_infos, $articles);
1328 
1329  $used_gift_points = intval(vn($_SESSION['session_utilisateur']['points'])) - $this->get_available_point_for_current_line(null);
1330  if (!empty($this->commande_id) && $this->commande_id != $order_id) {
1331  // On annule la commande précédemment liée à ce caddie car on vient de créer une nouvelle commande lui correspondant
1332  // SAUF si elle est déjà payée (=> 3ème argument à false)
1333  $GLOBALS['output_create_or_update_order'] = update_order_payment_status($this->commande_id, 'cancelled', false);
1334  }
1335  // On retire les points utilisés lors de la commande.
1336  // NB : Cette gestion n'utilise pas "total_points" de peel_commandes, qui est géré ailleurs et concerne les points gagnés lors de la commande
1337  query("UPDATE peel_utilisateurs
1338  SET points=points-" . intval($used_gift_points) . "
1339  WHERE id_utilisateur='" . intval($_SESSION['session_utilisateur']['id_utilisateur']) . "' AND " . get_filter_site_cond('utilisateurs') . "");
1340  $user_infos = get_user_information($_SESSION['session_utilisateur']['id_utilisateur']);
1341  $_SESSION['session_utilisateur']['points'] = $user_infos['points'];
1342  $this->commande_id = $order_id;
1343  // Incrémentation du compteur de code promotionnel
1344  if (!empty($this->code_promo)) {
1345  query("UPDATE peel_codes_promos
1346  SET compteur_utilisation=compteur_utilisation+1
1347  WHERE nom = '" . nohtml_real_escape_string($this->code_promo) . "' AND " . get_filter_site_cond('codes_promos') . "");
1348  }
1349  }
1350  // Si le caddie correspond à une commande en cours, alors on met à jour la commande en question
1351  // Sinon, on crée la comande
1352  if (!empty($this->code_promo)) {
1353  // Si le code avait été créé spécifiquement pour être envoyé à un utilisateur, alors il est présent dans peel_utilisateurs_codes_promos auquel cas on met à jour l'info d'utilisation
1354  query("UPDATE peel_utilisateurs_codes_promos
1355  SET utilise = '1'
1356  WHERE id_utilisateur = '" . intval($_SESSION['session_utilisateur']['id_utilisateur']) . "' AND nom_code = '" . nohtml_real_escape_string($this->code_promo) . "'");
1357  }
1358  $_SESSION['session_utilisateur']['remise_percent'] = 0;
1359  $_SESSION['session_utilisateur']['id_parrain'] = 0;
1360  $_SESSION['session_utilisateur']['type'] = ''; #- Suppression du statut filleul
1361 
1362  // On met à jour l'avoir de la session client
1363  $_SESSION['session_utilisateur']['avoir'] = max($_SESSION['session_utilisateur']['avoir'] - $_SESSION['session_caddie']->avoir, 0);
1364  // Annule la remise en % du client, supprimer ces lignes si vous souhaitez que les remises client soient permanentes
1365  query("UPDATE peel_utilisateurs
1366  SET remise_percent = '0', avoir = GREATEST(0, avoir-'" . nohtml_real_escape_string($_SESSION['session_caddie']->avoir) . "')
1367  WHERE id_utilisateur = '" . intval($_SESSION['session_utilisateur']['id_utilisateur']) . "' AND " . get_filter_site_cond('utilisateurs') . "");
1368 
1369  // si il y a des commandes de cadeau on envoie un email
1370  if (!empty($this->giftlist_owners[0]) && check_if_module_active('listecadeau')) {
1371  email_ordered_cadeaux($this->commande_id, $order_infos, $this->giftlist_owners[0]);
1372  }
1373  return $this->commande_id;
1374  }
1375 }
1376 
$ecotaxe_ht
Definition: Caddie.php:82
Caddie($percent_remise_user)
Caddie::Caddie()
Definition: Caddie.php:179
$total_option_ht
Definition: Caddie.php:119
get_delivery_cost_infos($total_weight, $total_price, $type_id=null, $zone_id=null, $nb_product=1)
Calcul des frais de livraison Si type_id est vide, on récupère les tarifs en excluant les tarifs=0 qu...
Definition: order.php:1199
$code_promo
Definition: Caddie.php:123
$remise
Definition: Caddie.php:66
$code_infos
Definition: Caddie.php:131
$commande_hash
Definition: Caddie.php:166
if(!empty($GLOBALS['site_parameters']['order_specific_field_titles'])) if(check_if_module_active('socolissimo')&&!empty($_REQUEST)&&!empty($_REQUEST['PUDOFOID'])&&!empty($_REQUEST['CEEMAIL'])&&!empty($_REQUEST['SIGNATURE'])&&!empty($_REQUEST['ORDERID'])) elseif(!empty($_POST)) elseif(check_if_module_active('socolissimo')&&!empty($_SESSION['session_commande']['is_socolissimo_order'])) foreach(array('bill'=> 1, 'ship'=> 2) as $address_type=> $session_commande_address_id) $frm['societe1']
$percent_remise_produit
Definition: Caddie.php:64
$tva
Definition: Caddie.php:62
$tarif_paiement
Definition: Caddie.php:149
$result
$zone_technical_code
Definition: Caddie.php:142
$percent_remise_user
Definition: Caddie.php:125
get_user_information($user_id=null, $get_full_infos=false)
Chargement des détails de l'utilisateur.
Definition: user.php:906
$couleurId
Definition: Caddie.php:40
get_delivery_type_name($id)
get_delivery_type_name()
Definition: order.php:1109
$percent_code_promo
Definition: Caddie.php:126
is_user_tva_intracom_for_no_vat($user_id=null)
is_user_tva_intracom_for_no_vat()
Definition: user.php:959
$avoir_user
Definition: Caddie.php:135
init($load_from_caddie_cookie_if_available=false, $erase_caddie_cookie=true)
Initialise le caddie.
Definition: Caddie.php:193
update_line($numero_ligne, $max_available_gift_points)
On recalcule les informations d'une ligne.
Definition: Caddie.php:478
$total_produit
Definition: Caddie.php:97
$pallet_count
Definition: Caddie.php:170
$total_ecotaxe_ht
Definition: Caddie.php:156
change_lines_data(&$line_infos)
Caddie::change_lines_data()
Definition: Caddie.php:377
update($percent_remise_user=null)
Cette méthode doit toujours être appelée après la modification (ou un ensemble de modifications) du c...
Definition: Caddie.php:868
save_in_database(&$order_infos)
Enregistre la commande dans la base.
Definition: Caddie.php:1222
redirect_and_die($url, $permanent_redirection=false, $avoid_loop=false)
Redirige vers l'URL demandée et arrête le programme.
Definition: fonctions.php:1551
$global_percent_pallet_filled
Definition: Caddie.php:171
static html_entity_decode_if_needed($string)
String::html_entity_decode_if_needed()
Definition: String.php:533
$prix
Definition: Caddie.php:44
$total_ht
Definition: Caddie.php:94
set_paiement($payment_technical_code)
Traitement du moyen de paiement.
Definition: Caddie.php:798
update_code_promo($new_code_promo=null)
Appeler cette fonction avec $new_code_promo="CODE" pour l'appliquer, $new_code_promo="" pour supprime...
Definition: Caddie.php:652
$total_prix_attribut
Definition: Caddie.php:86
$total_points
Definition: Caddie.php:108
nohtml_real_escape_string($value, $allowed_tags=null)
Protège les données pour insertion dans MySQL ET supprime les tags HTML pour protéger de toute sorte ...
Definition: database.php:400
$total_produit_avant_code_promo
Definition: Caddie.php:100
count_products($cat_id=null)
Renvoie le nombre d'articles dans le caddie (toujours positif)
Definition: Caddie.php:771
$delivery_orderid
Definition: Caddie.php:162
$cout_transport_ht
Definition: Caddie.php:111
$total_poids
Definition: Caddie.php:106
get_current_user_promotion_percentage()
Calcule la réduction générale applicable à un utilisateur et garde la valeur en session pour accélére...
Definition: user.php:939
$tva_tarif_paiement
Definition: Caddie.php:153
if(empty($_GET['id'])) if(!empty($GLOBALS['site_parameters']['allow_multiple_product_url_with_category'])) $product_object
$valeur_code_promo
Definition: Caddie.php:127
get_float_from_user_input($string, $from_currency_rate=1)
Transforme tout nombre formaté en un float au format PHP Exemples : 12 004,34 ou 12,324.50.
Definition: format.php:196
$zoneId
Definition: Caddie.php:139
$giftlist_owners
Definition: Caddie.php:30
real_escape_string($value)
real_escape_string()
Definition: database.php:374
affiche_erreur_caddie()
affiche_erreur_caddie()
Definition: Caddie.php:298
$articles
Definition: Caddie.php:32
$prix_ht_avant_code_promo
Definition: Caddie.php:54
$tarif_paiement_ht
Definition: Caddie.php:151
$zoneTva
Definition: Caddie.php:140
$prix_avant_code_promo
Definition: Caddie.php:52
$total_quantite
Definition: Caddie.php:95
$option
Definition: Caddie.php:74
get_filter_site_cond($table_technical_code, $table_alias=null, $use_strict_rights_if_in_admin=false, $specific_site_id=null, $exclude_public_items=false, $admin_force_multisite_if_allowed=false)
Retourne la condition SQL permettant de filtrer les données pour une table.
Definition: fonctions.php:4643
if(!defined('IN_PEEL')) display_prices_with_taxes_active()
display_prices_with_taxes_active()
Definition: fonctions.php:23
query($query, $die_if_error=false, $database_object=null, $silent_if_error=false, $security_sql_filter=true)
The query() function is meant to be called anywhere you want to make a query.
Definition: database.php:158
create_or_update_order(&$order_infos, &$articles_array)
Crée ou modifie une commande en base de données, ainsi que les produits commandés.
Definition: order.php:483
$poids
Definition: Caddie.php:36
$attribut
Definition: Caddie.php:84
vb(&$var, $default=null)
Variable blanche if $var n'est pas défini, retourne $default, sinon retourne $var.
Definition: format.php:97
if(strlen($date2)== '10') if($type== 'users-by-age'&&a_priv('admin_users', true)) elseif($type== 'forums-count'&&a_priv('admin_content', true)) elseif($type== 'forums-categories'&&a_priv('admin_content', true)) elseif($type== 'users-count'&&a_priv('admin_users', true)) elseif($type== 'product-categories'&&a_priv('admin_products', true)) elseif($type== 'users-by-sex'&&a_priv('admin_users', true)) elseif($type== 'users-by-country'&&a_priv('admin_users', true)) elseif($type== 'sales'&&a_priv('admin_sales', true))
Definition: chart-data.php:160
num_rows($query_result)
num_rows()
Definition: database.php:321
$id_attribut
Definition: Caddie.php:85
$option_ht
Definition: Caddie.php:76
delete_uploaded_file_and_thumbs($filename)
delete_uploaded_file_and_thumbs()
Definition: fonctions.php:3417
$total_prix_ht
Definition: Caddie.php:58
fetch_object($query_result)
fetch_object()
Definition: database.php:302
$total_ecotaxe_ttc_related_to_code_promo
Definition: Caddie.php:99
$avoir
Definition: Caddie.php:134
$cout_transport
Definition: Caddie.php:110
$zoneFranco
Definition: Caddie.php:141
get_available_point_for_current_line($this_line)
Caddie::get_available_point_for_current_line()
Definition: Caddie.php:455
$tva_cout_transport
Definition: Caddie.php:112
$tva_percent
Definition: Caddie.php:60
fetch_assoc($query_result)
fetch_assoc()
Definition: database.php:283
$points
Definition: Caddie.php:38
set_type($typeId)
Définition du type de port.
Definition: Caddie.php:847
$ecotaxe_ttc
Definition: Caddie.php:80
change_line_data($numero_ligne, $product_id, $quantity_wished, $couleur_id, $taille_id, $email_check, $liste_attribut, $listcadeaux_owner=null, $do_update_line=true)
On met à jour une ligne de produit, en connaissant déjà son numéro.
Definition: Caddie.php:405
$prix_cat_ht
Definition: Caddie.php:50
$delai_stock
Definition: Caddie.php:72
$prix_ht
Definition: Caddie.php:46
$tva_total_remise
Definition: Caddie.php:116
$GLOBALS['page_columns_count']
$commande_id
Definition: Caddie.php:165
delete_line($numero_ligne)
Enlève un produit du caddie.
Definition: Caddie.php:597
$total_tva
Definition: Caddie.php:104
$prix_cat
Definition: Caddie.php:48
$remise_ht
Definition: Caddie.php:68
vn(&$var, $default=0)
Variable nulle if $var n'est pas défini, retourne $default, sinon retourne $var.
Definition: format.php:110
$email_check
Definition: Caddie.php:78
$tva_total_option
Definition: Caddie.php:120
$total_produit_related_to_code_promo
Definition: Caddie.php:98
a_priv($requested_priv, $demo_allowed=false, $site_configuration_modification=false, $user_id=null)
Renvoie true si l'utilisateur de la session a le privilège $requested_priv ou un droit supérieur Des ...
Definition: user.php:63
$total_ecotaxe_ttc
Definition: Caddie.php:155
$total_option
Definition: Caddie.php:118
$quantite
Definition: Caddie.php:34
$reference
Definition: Caddie.php:88
$payment_technical_code
Definition: Caddie.php:147
$apply_vat
Definition: Caddie.php:145
$typeId
Definition: Caddie.php:144
$tva_total_produit
Definition: Caddie.php:103
_recalc_line_totals()
Recalcul des totaux en appliquant correctement les ventilations des codes promos. ...
Definition: Caddie.php:1163
$tva_total_ecotaxe
Definition: Caddie.php:157
$total
Definition: Caddie.php:92
$total_prix
Definition: Caddie.php:56
$conditionnement
Definition: Caddie.php:169
$total_reduction_percent_code_promo
Definition: Caddie.php:129
static substr($string, $start, $length=null)
Returns the portion of string specified by the start and length parameters.
Definition: String.php:112
check_if_module_active($module_name, $specific_file_name=null)
Renvoie si un module est présent et activé ou non - Peut être appelé avant ou après le chargement d'u...
$total_reduction_code_promo
Definition: Caddie.php:128
get_site_domain($return_only_domains=false, $domain=null, $strip_subdomain=true)
Récupère le nom de domaine du site sans http:// et sans sous-domaine.
Definition: fonctions.php:3632
$total_remise
Definition: Caddie.php:114
$etat_stock
Definition: Caddie.php:70
$message_caddie
Definition: Caddie.php:159
$total_produit_ht
Definition: Caddie.php:102
add_product(&$product_object, $added_quantity_wished, $email_check, $listcadeaux_owner=null, $custom_product_reference=null)
On ajoute un nouveau produit dans le panier.
Definition: Caddie.php:322
$total_remise_ht
Definition: Caddie.php:115
update_order_payment_status($order_id, $status_or_is_payment_validated, $allow_update_paid_orders=true, $statut_livraison_new=null, $delivery_tracking=null, $no_stock_decrement_already_done=false, $payment_technical_code=null)
Met à jour le status de paiement et/ou de livraison d'une commande, et gère les stocks suivant le sta...
Definition: order.php:178
set_zone($zoneId)
Définition de la zone d'expédition.
Definition: Caddie.php:820
$tailleId
Definition: Caddie.php:42
if(defined('IN_PEEL_ADMIN')||IN_INSTALLATION) $_SESSION['session_langue']

This documentation for Open ecommerce PEEL Shopping and PEEL.fr has been generated by Doxygen on Thu Oct 15 2015 14:29:56 - Peel ecommerce is a product of Agence web Advisto SAS. All rights reserved.