Completed
Push — master ( 9d3fbd...af269e )
by Michael
09:48
created

class/oledrion_reductions.php (2 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * ****************************************************************************
4
 * oledrion - MODULE FOR XOOPS
5
 * Copyright (c) Hervé Thouzard of Instant Zero (http://www.instant-zero.com)
6
 *
7
 * You may not change or alter any portion of this comment or credits
8
 * of supporting developers from this source code or any supporting source code
9
 * which is considered copyrighted (c) material of the original comment or credit authors.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 *
14
 * @copyright       Hervé Thouzard of Instant Zero (http://www.instant-zero.com)
15
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
16
 * @package         oledrion
17
 * @author          Hervé Thouzard of Instant Zero (http://www.instant-zero.com)
18
 *
19
 * Version :
20
 * ****************************************************************************
21
 */
22
23
/**
24
 * Calcul du panier et de ses réductions en fonction des règles de remises
25
 * Cette classe ne gère pas de fichier (elle sert uniquement aux calculs)
26
 *
27
 * Détail des tableaux :
28
 * categoriesProductsCount => Nombre de produits par catégorie
29
 * [clé] = Id Catégorie, [valeur] = Nombre de produits
30
 *
31
 * categoriesProductsQuantities => Quantités de produits par catégorie
32
 * [clé] = Id Catégorie, [valeur] = Quantité de produits
33
 *
34
 * totalProductsQuantities => Quantité totale de tous les produits
35
 *
36
 * associatedManufacturers => Contient la liste des ID uniques de produits
37
 * [clé] = Id Produit, [valeur] = Id produit
38
 *
39
 * associatedVendors => Contient la liste des vendeurs de produits
40
 * [clé] = Id Vendeur, [valeur] = Id Vendeur
41
 *
42
 * associatedAttributesPerProduct => Contient les attributs de chaque produit
43
 * [clé] = Id Produit, [valeurS] = Tous les attributs du produit sous la forme d'objets de type Attributs
44
 *
45
 * associatedCategories => Contient la liste des ID de catégories
46
 * [clé] = Id Catégorie, [valeur] = Id Catégorie
47
 *
48
 * totalAmountBeforeDiscounts => Montant total de la commande avant les réductions
49
 *
50
 * associatedManufacturersPerProduct => Contient la liste des ID des fabricants par produit
51
 * [clé] = Id produit, [valeur] = array(Ids des fabricants)
52
 *
53
 * Les 3 tableaux suivants évoluent ensuite comme ceci :
54
 * associatedManufacturers => Tableau d'objets de type Fabricants
55
 * [clé] = id Fabricant [valeur] = Fabricant sous la forme d'un objet
56
 *
57
 * associatedVendors => Tableau d'ojets de type Vendeurs
58
 * [clé] = Id Vendeur [valeur] = Vendeur sous la forme d'un objet
59
 *
60
 * associatedCategories => Tableau d'objets de type Categories
61
 * [clé] = Id Catégorie [valeur] = Catéagorie sous la forme d'un objet
62
 *
63
 */
64
class Oledrion_reductions
65
{
66
    // Ne contient que la liste des règles actives au moment du calcul
67
    private $allActiveRules = array();
68
69
    // Nombre de produits par catégorie
70
    private $categoriesProductsCount = array();
71
72
    // Quantité de produits par catégorie
73
    private $categoriesProductsQuantities = array();
74
75
    /**
76
     * le caddy en mémoire
77
     *  $cart['number'] = Indice du produit
78
     *  $cart['id'] = Identifiant du produit
79
     *  $cart['qty'] = Quantité voulue
80
     *  $cart['product'] = L'objet produit correspondant au panier
81
     */
82
    private $cart = array();
83
84
    /**
85
     * Le caddy pour le template. Consulter les détails du caddy dans la métode ComputeCart
86
     */
87
    private $cartForTemplate = array();
88
89
    /**
90
     * Les règles à appliquer à la fin, sur l'intégralité du panier
91
     */
92
    private $rulesForTheWhole = array();
93
94
    // Le total des quantités de produits avant les réductions
95
    private $totalProductsQuantities = 0;
96
    // Montant total de la commande avant les réductions
97
    private $totalAmountBeforeDiscounts = 0;
98
99
    // Handlers vers les tables du module
100
    private $handlers;
101
102
    // Les fabricants associés aux produits du panier
103
    private $associatedManufacturers = array();
104
105
    // Les vendeur associés aux produits du panier
106
    private $associatedVendors = array();
107
108
    // Les catégories associées aux produits du panier
109
    private $associatedCategories = array();
110
111
    // Fabricants associés par produit du panier
112
    private $associatedManufacturersPerProduct = array();
113
114
    // Attributs par produit du panier
115
    private $associatedAttributesPerProduct = array();
116
117
    /**
118
     * Chargement des handlers et des règles actives
119
     */
120
    public function __construct()
121
    {
122
        $this->initHandlers();
123
        $this->loadAllActiveRules();
124
    }
125
126
    /**
127
     * Chargement des handlers
128
     */
129
    private function initHandlers()
130
    {
131
        $this->handlers = OledrionHandler::getInstance();
132
    }
133
134
    /**
135
     * Chargement de toutes les règles actives de réductions (sans date définie ou avec une période correspondante à aujourd'hui)
136
     */
137
    public function loadAllActiveRules()
138
    {
139
        $critere  = new CriteriaCompo();
140
        $critere1 = new CriteriaCompo();
141
        $critere1->add(new Criteria('disc_date_from', 0, '='));
142
        $critere1->add(new Criteria('disc_date_to', 0, '='));
143
        $critere->add($critere1);
144
145
        $critere2 = new CriteriaCompo();
146
        $critere2->add(new Criteria('disc_date_from', time(), '<='));
147
        $critere2->add(new Criteria('disc_date_to', time(), '>='));
148
        $critere->add($critere2, 'OR');
149
150
        $this->allActiveRules = $this->handlers->h_oledrion_discounts->getObjects($critere);
151
    }
152
153
    /**
154
     * Calcul des quantités de produits par catégorie et du nombre de produits par catégorie
155
     *
156
     * @param oledrion_products $product
157
     * @param integer           $quantity
158
     */
159
    public function computePerCategories(Oledrion_products $product, $quantity)
160
    {
161
        // Nombre de produits par catégories
162 View Code Duplication
        if (isset($this->categoriesProductsCount[$product->product_cid])) {
163
            ++$this->categoriesProductsCount[$product->product_cid];
164
        } else {
165
            $this->categoriesProductsCount[$product->product_cid] = 1;
166
        }
167
168
        // Mise à jour des quantités par catégories
169 View Code Duplication
        if (isset($this->categoriesProductsQuantities[$product->product_cid])) {
170
            $this->categoriesProductsQuantities[$product->product_cid] += $quantity;
171
        } else {
172
            $this->categoriesProductsQuantities[$product->product_cid] = $quantity;
173
        }
174
        $this->totalProductsQuantities += $quantity;
175
        // Quantité totale de tous les produits
176
    }
177
178
    /**
179
     * Ajoute à un tableau interne, le fabricant associé à un produit
180
     *
181
     * @param oledrion_products $product
182
     */
183
    private function addAssociatedManufacturers(Oledrion_products $product)
184
    {
185
        if (!isset($this->associatedManufacturers[$product->product_id])) {
186
            $this->associatedManufacturers[$product->product_id] = $product->product_id;
187
        }
188
    }
189
190
    /**
191
     * Recherche des attributs associés à chaque produit
192
     *
193
     * @param oledrion_products $product
194
     * @param attray            $attributes
195
     * @since 2.3
196
     */
197
    private function addAssociatedAttributes(Oledrion_products $product, $attributes)
198
    {
199
        if (!isset($this->associatedAttributesPerProduct[$product->product_id])) {
200
            $this->associatedAttributesPerProduct[$product->product_id] = $product->getProductsAttributesList($attributes);
201
        }
202
    }
203
204
    /**
205
     * Ajoute à un tableau interne, le vendeur associé à un produit
206
     *
207
     * @param oledrion_products $product
208
     */
209
    private function addAssociatedVendors(Oledrion_products $product)
210
    {
211
        if (!isset($this->associatedVendors[$product->product_vendor_id])) {
212
            $this->associatedVendors[$product->product_vendor_id] = $product->product_vendor_id;
213
        }
214
    }
215
216
    /**
217
     * Ajoute à un tableau interne, la catégorie associée à un produit
218
     *
219
     * @param oledrion_products $product
220
     */
221
    private function addAssociatedCategories(Oledrion_products $product)
222
    {
223
        if (!isset($this->associatedCategories[$product->product_cid])) {
224
            $this->associatedCategories[$product->product_cid] = $product->product_cid;
225
        }
226
    }
227
228
    /**
229
     * Charge les fabricants associés aux produits du panier
230
     */
231
    private function loadAssociatedManufacturers()
232
    {
233
        if (count($this->associatedManufacturers) > 0) {
234
            sort($this->associatedManufacturers);
235
            $productsIds                   = $this->associatedManufacturers;
236
            $this->associatedManufacturers = array();
237
            // au cas où cela échouerait
238
            $productsManufacturers = $manufacturersIds = array();
239
            $productsManufacturers = $this->handlers->h_oledrion_productsmanu->getFromProductsIds($productsIds);
240
            if (count($productsManufacturers) > 0) {
241
                foreach ($productsManufacturers as $productManufacturer) {
242
                    if (!isset($manufacturersIds[$productManufacturer->pm_manu_id])) {
243
                        $manufacturersIds[$productManufacturer->pm_manu_id] = $productManufacturer->pm_manu_id;
244
                    }
245
                    $this->associatedManufacturersPerProduct[$productManufacturer->pm_product_id][] = $productManufacturer->pm_manu_id;
246
                }
247
                if (count($manufacturersIds) > 0) {
248
                    sort($manufacturersIds);
249
                    $this->associatedManufacturers = $this->handlers->h_oledrion_manufacturer->getManufacturersFromIds($manufacturersIds);
250
                }
251
            }
252
        }
253
    }
254
255
    /**
256
     * Charge la liste des vendeurs associés aux produits
257
     */
258
    private function loadAssociatedVendors()
259
    {
260
        if (count($this->associatedVendors) > 0) {
261
            sort($this->associatedVendors);
262
            $ids                     = $this->associatedVendors;
263
            $this->associatedVendors = $this->handlers->h_oledrion_vendors->getVendorsFromIds($ids);
264
        }
265
    }
266
267
    /**
268
     * Charge les catégories associées aux produits du panier
269
     */
270
    private function loadAssociatedCategories()
271
    {
272
        if (count($this->associatedCategories) > 0) {
273
            sort($this->associatedCategories);
274
            $ids                        = $this->associatedCategories;
275
            $this->associatedCategories = $this->handlers->h_oledrion_cat->getCategoriesFromIds($ids);
276
        }
277
    }
278
279
    /**
280
     * Recherche les fabricants, catégories et vendeurs associés à chaque produit
281
     */
282
    public function loadElementsAssociatedToProducts()
283
    {
284
        $this->loadAssociatedManufacturers();
285
        $this->loadAssociatedVendors();
286
        $this->loadAssociatedCategories();
287
    }
288
289
    /**
290
     * Recherche les (objets) produits associés à chaque produit du panier (et lance le calcul des quantités)
291
     */
292
    public function loadProductsAssociatedToCart()
293
    {
294
        $newCart = array();
295
        foreach ($this->cart as $cartProduct) {
296
            $data               = array();
297
            $data['id']         = $cartProduct['id'];
298
            $data['number']     = $cartProduct['number'];
299
            $data['qty']        = $cartProduct['qty'];
300
            $data['attributes'] = $cartProduct['attributes'];
301
302
            $product = null;
303
            $product = $this->handlers->h_oledrion_products->get($data['id']);
304
            if (!is_object($product)) {
305
                trigger_error(_OLEDRION_ERROR9);
306
                continue;
307
                // Pour éviter le cas de la suppression d'un produit (dans l'admin) alors qu'un client l'a toujours dans son panier (et donc en session)
308
            }
309
            $data['product'] = $product;
310
            // Mise à jour des calculs par catégorie
311
            $this->computePerCategories($product, $data['qty']);
312
            // Recherche des éléments associés à chaque produit
313
            $this->addAssociatedManufacturers($product);
314
            $this->addAssociatedVendors($product);
315
            $this->addAssociatedAttributes($product, $data['attributes']);
316
            $this->addAssociatedCategories($product);
317
318
            // Calcul du total de la commande avant réductions
319 View Code Duplication
            if ((float)$product->getVar('product_discount_price', 'n') > 0) {
320
                $ht = (float)$product->getVar('product_discount_price', 'n');
321
            } else {
322
                $ht = (float)$product->getVar('product_price', 'n');
323
            }
324
            // S'il y a des options, on rajoute leur montant
325 View Code Duplication
            if (is_array($data['attributes']) && count($data['attributes']) > 0) {
326
                $ht += $this->handlers->h_oledrion_attributes->getProductOptionsPrice($data['attributes'], $product->getVar('product_vat_id'));
327
            }
328
329
            $this->totalAmountBeforeDiscounts += ($data['qty'] * $ht);
330
331
            $newCart[] = $data;
332
        }
333
        $this->loadElementsAssociatedToProducts();
334
        $this->cart = $newCart;
335
    }
336
337
    /**
338
     * Calcul du montant HT auquel on applique un pourcentage de réduction
339
     *
340
     * @param  float   $price    Le prix auquel appliquer la réduction
341
     * @param  integer $discount Le pourcentage de réduction
342
     * @return float   Le montant réduit
343
     */
344
    private function getDiscountedPrice($price, $discount)
345
    {
346
        return (float)($price - ($price * ($discount / 100)));
347
    }
348
349
    /**
350
     * Remise à zéro des membres internes
351
     */
352
    private function initializePrivateData()
353
    {
354
        $this->totalProductsQuantities           = 0;
355
        $this->totalAmountBeforeDiscounts        = 0;
356
        $this->rulesForTheWhole                  = array();
357
        $this->cartForTemplate                   = array();
358
        $this->associatedManufacturers           = array();
359
        $this->associatedVendors                 = array();
360
        $this->associatedCategories              = array();
361
        $this->associatedManufacturersPerProduct = array();
362
        $this->associatedAttributesPerProduct    = array();
363
    }
364
365
    /**
366
     * Calcul de la facture en fonction du panier
367
     * Contenu du panier en session :
368
     *
369
     *  $datas['number'] = Indice du produit dans le panier
370
     *  $datas['id'] = Identifiant du produit dans la base
371
     *  $datas['qty'] = Quantité voulue
372
     *  $datas['attributes'] = Attributs produit array('attr_id' => id attribut, 'values' => array(valueId1, valueId2 ...))
373
     *
374
     * En variable privé, le panier (dans $cart) contient la même chose + un objet 'oledrion_products' dans la clé 'product'
375
     *
376
     * @param array   $cartForTemplate      Contenu du caddy à passer au template (en fait la liste des produits)
377
     * @param         boolean               emptyCart Indique si le panier est vide ou pas
378
     * @param float   $shippingAmount       Montant des frais de port
379
     * @param float   $commandAmount        Montant HT de la commande
380
     * @param float   $vatAmount            Montant de la TVA
381
     * @param string  $goOn                 Adresse vers laquelle renvoyer le visiteur après qu'il ait ajouté un produit dans son panier (cela correspond en fait à la catégorie du dernier produit ajouté dans le panier)
382
     * @param float   $commandAmountTTC     Montant TTC de la commande
383
     * @param array   $discountsDescription Descriptions des remises GLOBALES appliquées (et pas les remises par produit !)
384
     * @param integer $discountsCount       Le nombre TOTAL de réductions appliquées (individuellement ou sur la globalité du panier)
385
     *                                      B.R. @param array $checkoutAttributes
386
     * TODO: Passer les paramètres sous forme d'objet
387
     * @return bool
388
     */
389
390
    // B.R. Added: $checkoutAttributes
391
    public function computeCart(
0 ignored issues
show
computeCart uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
computeCart uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
392
        &$cartForTemplate,
393
        &$emptyCart,
394
        &$shippingAmount,
395
        &$commandAmount,
396
        &$vatAmount,
397
        &$goOn,
398
        &$commandAmountTTC,
399
        &$discountsDescription,
400
        &$discountsCount,
401
        &$checkoutAttributes)
402
    {
403
        $emptyCart      = false;
404
        $goOn           = '';
405
        $vats           = array();
406
        $cpt            = 0;
407
        $discountsCount = 0;
408
        $this->cart     = isset($_SESSION[OledrionOledrion_caddyHandler::CADDY_NAME]) ? $_SESSION[OledrionOledrion_caddyHandler::CADDY_NAME] : array();
409
        $cartCount      = count($this->cart);
410
        if ($cartCount == 0) {
411
            $emptyCart = true;
412
413
            return true;
414
        }
415
416
        // Réinitialisation des données privées
417
        $this->initializePrivateData();
418
        // Chargement des objets produits associés aux produits du panier et calcul des quantités par catégorie
419
        $this->loadProductsAssociatedToCart();
420
        // Chargement des TVA
421
        if (!isset($_POST['cmd_country']) || empty($_POST['cmd_country'])) {
422
            $_POST['cmd_country'] = OLEDRION_DEFAULT_COUNTRY;
423
        }
424
        $vats              = $this->handlers->h_oledrion_vat->getCountryVats($_POST['cmd_country']);
425
        $oledrion_Currency = &Oledrion_Currency::getInstance();
426
        $caddyCount        = count($this->cart);
427
428
        // Initialisation des totaux généraux (ht, tva et frais de port)
429
        $totalHT = $totalVAT = $totalShipping = 0.0;
430
431
        // Boucle sur tous les produits et sur chacune des règles pour calculer le prix du produit (et ses frais de port) et voir si on doit y appliquer une réduction
432
        foreach ($this->cart as $cartProduct) {
433
            if ((float)$cartProduct['product']->getVar('product_discount_price', 'n') > 0) {
434
                $ht = (float)$cartProduct['product']->getVar('product_discount_price', 'n');
435
            } else {
436
                $ht = (float)$cartProduct['product']->getVar('product_price', 'n');
437
            }
438
            // S'il y a des options, on rajoute leur montant
439
            $productAttributes = array();
440 View Code Duplication
            if (is_array($cartProduct['attributes']) && count($cartProduct['attributes']) > 0) {
441
                $ht += $this->handlers->h_oledrion_attributes->getProductOptionsPrice($cartProduct['attributes'], $cartProduct['product']->getVar('product_vat_id'), $productAttributes);
442
            }
443
444
            $discountedPrice = $ht;
445
            $quantity        = (int)$cartProduct['qty'];
446
447
            if (OledrionUtility::getModuleOption('shipping_quantity')) {
448
                $discountedShipping = (float)($cartProduct['product']->getVar('product_shipping_price', 'n') * $quantity);
449
            } else {
450
                $discountedShipping = (float)$cartProduct['product']->getVar('product_shipping_price', 'n');
451
            }
452
            $totalPrice = 0.0;
453
            $reduction  = '';
454
455
            // B.R. Start
456
            // If any product in cart does not skip optional checkout step, need to perform
457
            if ($cartProduct['product']->getVar('skip_packing', 'n') == 0) {
458
                $checkoutAttributes['skip_packing'] = 0;
459
            }
460
            if ($cartProduct['product']->getVar('skip_location', 'n') == 0) {
461
                $checkoutAttributes['skip_location'] = 0;
462
            }
463
            if ($cartProduct['product']->getVar('skip_delivery', 'n') == 0) {
464
                $checkoutAttributes['skip_delivery'] = 0;
465
            }
466
            // B.R. End
467
468
            ++$cpt;
469
            if ($cpt == $caddyCount) {
470
                // On arrive sur le dernier produit
471
                $category = null;
472
                $category = $this->handlers->h_oledrion_cat->get($cartProduct['product']->getVar('product_cid'));
473
                if (is_object($category)) {
474
                    $goOn = $category->getLink();
475
                }
476
            }
477
478
            // Boucle sur les règles
479
            foreach ($this->allActiveRules as $rule) {
480
                $applyRule = false;
481
                if (($rule->disc_group != 0 && OledrionUtility::isMemberOfGroup($rule->disc_group))
482
                    || $rule->disc_group == 0) {
483
                    if (($rule->disc_cat_cid != 0
484
                         && $cartProduct['product']->getVar('product_cid') == $rule->disc_cat_cid)
485
                        || $rule->disc_cat_cid == 0) {
486
                        if (($rule->disc_vendor_id != 0
487
                             && $cartProduct['product']->getVar('disc_vendor_id') == $rule->disc_vendor_id)
488
                            || $rule->disc_vendor_id == 0) {
489
                            if (($rule->disc_product_id != 0
490
                                 && $cartProduct['product']->getVar('product_id') == $rule->disc_product_id)
491
                                || $rule->disc_product_id == 0) {
492
                                // Dans quel cas appliquer la réduction ?
493
                                switch ($rule->disc_price_case) {
494
                                    case OLEDRION_DISCOUNT_PRICE_CASE_ALL:
495
                                        // Dans tous les cas
496
                                        $applyRule = true;
497
                                        break;
498
                                    case OLEDRION_DISCOUNT_PRICE_CASE_FIRST_BUY:
499
                                        // Si c'est le premier achat de l'utilisateur sur le site
500
                                        if ($this->handlers->h_oledrion_commands->isFirstCommand()) {
501
                                            $applyRule = true;
502
                                        }
503
                                        break;
504
                                    case OLEDRION_DISCOUNT_PRICE_CASE_PRODUCT_NEVER:
505
                                        // Si le produit n'a jamais été acheté par le client
506
                                        if (!$this->handlers->h_oledrion_commands->productAlreadyBought(0, $cartProduct['product']->getVar('product_id'))) {
507
                                            $applyRule = true;
508
                                        }
509
                                        break;
510
                                    case OLEDRION_DISCOUNT_PRICE_CASE_QTY_IS:
511
                                        // Si la quantité de produit est ... à ...
512
                                        switch ($rule->disc_price_case_qty_cond) {
513
                                            case OLEDRION_DISCOUNT_PRICE_QTY_COND1:
514
                                                // >
515
                                                if ($cartProduct['qty'] > $rule->disc_price_case_qty_value) {
516
                                                    $applyRule = true;
517
                                                }
518
                                                break;
519
                                            case OLEDRION_DISCOUNT_PRICE_QTY_COND2:
520
                                                // >=
521
                                                if ($cartProduct['qty'] >= $rule->disc_price_case_qty_value) {
522
                                                    $applyRule = true;
523
                                                }
524
                                                break;
525
                                            case OLEDRION_DISCOUNT_PRICE_QTY_COND3:
526
                                                // <
527
                                                if ($cartProduct['qty'] < $rule->disc_price_case_qty_value) {
528
                                                    $applyRule = true;
529
                                                }
530
                                                break;
531
                                            case OLEDRION_DISCOUNT_PRICE_QTY_COND4:
532
                                                // <=
533
                                                if ($cartProduct['qty'] <= $rule->disc_price_case_qty_value) {
534
                                                    $applyRule = true;
535
                                                }
536
                                                break;
537
                                            case OLEDRION_DISCOUNT_PRICE_QTY_COND5:
538
                                                // ==
539
                                                if ($cartProduct['qty'] == $rule->disc_price_case_qty_value) {
540
                                                    $applyRule = true;
541
                                                }
542
                                                break;
543
                                        }
544
                                }
545
                            }
546
                        }
547
                    }
548
                }
549
                if ($applyRule) {
550
                    // Il faut appliquer la règle
551
                    // On calcule le nouveau prix ht du produit
552
                    switch ($rule->disc_price_type) {
553
                        case OLEDRION_DISCOUNT_PRICE_TYPE1:
554
                            // Montant dégressif selon les quantités
555
                            if ($quantity >= $rule->disc_price_degress_l1qty1
556
                                && $quantity <= $rule->disc_price_degress_l1qty2) {
557
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l1total', 'n');
558
                            }
559
                            if ($quantity >= $rule->disc_price_degress_l2qty1
560
                                && $quantity <= $rule->disc_price_degress_l2qty2) {
561
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l2total', 'n');
562
                            }
563
                            if ($quantity >= $rule->disc_price_degress_l3qty1
564
                                && $quantity <= $rule->disc_price_degress_l3qty2) {
565
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l3total', 'n');
566
                            }
567
                            if ($quantity >= $rule->disc_price_degress_l4qty1
568
                                && $quantity <= $rule->disc_price_degress_l4qty2) {
569
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l4total', 'n');
570
                            }
571
                            if ($quantity >= $rule->disc_price_degress_l5qty1
572
                                && $quantity <= $rule->disc_price_degress_l5qty2) {
573
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l5total', 'n');
574
                            }
575
                            $reduction = $rule->disc_description;
576
                            ++$discountsCount;
577
                            break;
578
579
                        case OLEDRION_DISCOUNT_PRICE_TYPE2:
580
                            // D'un montant ou d'un pourcentage
581
                            if ($rule->disc_price_amount_on == OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_PRODUCT) {
582
                                // Réduction sur le produit
583
                                if ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_PERCENT) {
584
                                    // Réduction en pourcentage
585
                                    $discountedPrice = $this->getDiscountedPrice($discountedPrice, $rule->getVar('disc_price_amount_amount', 'n'));
586
                                } elseif ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_MONEY) {
587
                                    // Réduction d'un montant en euros
588
                                    $discountedPrice -= (float)$rule->getVar('disc_price_amount_amount', 'n');
589
                                }
590
591
                                // Pas de montants négatifs
592
                                OledrionUtility::doNotAcceptNegativeAmounts($discountedPrice);
593
                                $reduction = $rule->disc_description;
594
                                ++$discountsCount;
595
                            } elseif ($rule->disc_price_amount_on == OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_CART) {
596
                                // Règle à appliquer sur le panier
597
                                if (!isset($this->rulesForTheWhole[$rule->disc_id])) {
598
                                    $this->rulesForTheWhole[$rule->disc_id] = $rule;
599
                                }
600
                            }
601
                            break;
602
                    }
603
604
                    // On passe au montant des frais de port
605
                    switch ($rule->disc_shipping_type) {
606
                        case OLEDRION_DISCOUNT_SHIPPING_TYPE1:
607
                            // A payer dans leur intégralité, rien à faire
608
                            break;
609
                        case OLEDRION_DISCOUNT_SHIPPING_TYPE2:
610
                            // Totalement gratuits si le client commande plus de X euros d'achat
611
                            if ($this->totalAmountBeforeDiscounts > $rule->disc_shipping_free_morethan) {
612
                                $discountedShipping = 0.0;
613
                            }
614
                            break;
615
                        case OLEDRION_DISCOUNT_SHIPPING_TYPE3:
616
                            // Frais de port réduits de X euros si la commande est > x
617
                            if ($this->totalAmountBeforeDiscounts > $rule->disc_shipping_reduce_cartamount) {
618
                                $discountedShipping -= (float)$rule->getVar('disc_shipping_reduce_amount', 'n');
619
                            }
620
                            // Pas de montants négatifs
621
                            OledrionUtility::doNotAcceptNegativeAmounts($discountedShipping);
622
                            break;
623
                        case OLEDRION_DISCOUNT_SHIPPING_TYPE4:
624
                            // Frais de port dégressifs
625
                            if ($quantity >= $rule->disc_shipping_degress_l1qty1
626
                                && $quantity <= $rule->disc_shipping_degress_l1qty2) {
627
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l1total', 'n');
628
                            }
629
                            if ($quantity >= $rule->disc_shipping_degress_l2qty1
630
                                && $quantity <= $rule->disc_shipping_degress_l2qty2) {
631
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l2total', 'n');
632
                            }
633
                            if ($quantity >= $rule->disc_shipping_degress_l3qty1
634
                                && $quantity <= $rule->disc_shipping_degress_l3qty2) {
635
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l3total', 'n');
636
                            }
637
                            if ($quantity >= $rule->disc_shipping_degress_l4qty1
638
                                && $quantity <= $rule->disc_shipping_degress_l4qty2) {
639
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l4total', 'n');
640
                            }
641
                            if ($quantity >= $rule->disc_shipping_degress_l5qty1
642
                                && $quantity <= $rule->disc_shipping_degress_l5qty2) {
643
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l5total', 'n');
644
                            }
645
                            break;
646
                    }    // Sélection du type de réduction sur les frais de port
647
                }    // Il faut appliquer la règle de réduction
648
            }// Boucle sur les réductions
649
650
            // Calcul de la TVA du produit
651
            $vatId = $cartProduct['product']->getVar('product_vat_id');
652
            if (is_array($vats) && isset($vats[$vatId])) {
653
                $vatRate   = (float)$vats[$vatId]->getVar('vat_rate', 'n');
654
                $vatAmount = OledrionUtility::getVAT($discountedPrice * $quantity, $vatRate);
655
            } else {
656
                $vatRate   = 0.0;
657
                $vatAmount = 0.0;
658
            }
659
660
            // Calcul du TTC du produit ((ht * qte) + tva + frais de port)
661
            $totalPrice = (float)(($discountedPrice * $quantity) + $vatAmount + $discountedShipping);
662
663
            // Les totaux généraux
664
            $totalHT       += ($discountedPrice * $quantity);
665
            $totalVAT      += $vatAmount;
666
            $totalShipping += $discountedShipping;
667
668
            // Recherche des éléments associés au produit
669
            $associatedVendor      = $associatedCategory = $associatedManufacturers = array();
670
            $manufacturersJoinList = '';
671
            // Le vendeur
672
            if (isset($this->associatedVendors[$cartProduct['product']->product_vendor_id])) {
673
                $associatedVendor = $this->associatedVendors[$cartProduct['product']->product_vendor_id]->toArray();
674
            }
675
676
            // La catégorie
677
            if (isset($this->associatedCategories[$cartProduct['product']->product_cid])) {
678
                $associatedCategory = $this->associatedCategories[$cartProduct['product']->product_cid]->toArray();
679
            }
680
681
            // Les fabricants
682
            $product_id = $cartProduct['product']->product_id;
683
            if (isset($this->associatedManufacturersPerProduct[$product_id])) {
684
                // Recherche de la liste des fabricants associés à ce produit
685
                $manufacturers     = $this->associatedManufacturersPerProduct[$product_id];
686
                $manufacturersList = array();
687
                foreach ($manufacturers as $manufacturer_id) {
688
                    if (isset($this->associatedManufacturers[$manufacturer_id])) {
689
                        $associatedManufacturers[] = $this->associatedManufacturers[$manufacturer_id]->toArray();
690
                    }
691
                    $manufacturersList[] = $this->associatedManufacturers[$manufacturer_id]->manu_commercialname . ' ' . $this->associatedManufacturers[$manufacturer_id]->manu_name;
692
                }
693
                $manufacturersJoinList = implode(OLEDRION_STRING_TO_JOIN_MANUFACTURERS, $manufacturersList);
694
            }
695
            $productTemplate                = array();
696
            $productTemplate                = $cartProduct['product']->toArray();
697
            $productTemplate['attributes']  = $productAttributes;
698
            $productTemplate['number']      = $cartProduct['number'];
699
            $productTemplate['id']          = $cartProduct['id'];
700
            $productTemplate['product_qty'] = $cartProduct['qty'];
701
702
            $productTemplate['unitBasePrice'] = $ht;
703
            // Prix unitaire HT SANS réduction
704
            $productTemplate['discountedPrice'] = $discountedPrice;
705
            // Prix unitaire HT AVEC réduction
706
            $productTemplate['discountedPriceWithQuantity'] = $discountedPrice * $quantity;
707
            // Prix HT AVEC réduction et la quantité
708
            // Les même prix mais formatés
709
            $productTemplate['unitBasePriceFormated'] = $oledrion_Currency->amountForDisplay($ht);
710
            // Prix unitaire HT SANS réduction
711
            $productTemplate['discountedPriceFormated'] = $oledrion_Currency->amountForDisplay($discountedPrice);
712
            // Prix unitaire HT AVEC réduction
713
            $productTemplate['discountedPriceWithQuantityFormated'] = $oledrion_Currency->amountForDisplay($discountedPrice * $quantity);
714
            // Prix HT AVEC réduction et la quantité
715
716
            // Add by voltan
717
            $productTemplate['discountedPriceFormatedOrg'] = $oledrion_Currency->amountForDisplay($ht - $discountedPrice);
718
            $productTemplate['discountedPriceOrg']         = $ht - $discountedPrice;
719
720
            $productTemplate['vatRate']            = $oledrion_Currency->amountInCurrency($vatRate);
721
            $productTemplate['vatAmount']          = $vatAmount;
722
            $productTemplate['normalShipping']     = $cartProduct['product']->getVar('product_shipping_price', 'n');
723
            $productTemplate['discountedShipping'] = $discountedShipping;
724
            $productTemplate['totalPrice']         = $totalPrice;
725
            $productTemplate['reduction']          = $reduction;
726
            $productTemplate['templateProduct']    = $cartProduct['product']->toArray();
727
728
            $productTemplate['vatAmountFormated']          = $oledrion_Currency->amountInCurrency($vatAmount);
729
            $productTemplate['normalShippingFormated']     = $oledrion_Currency->amountForDisplay($cartProduct['product']->getVar('product_shipping_price', 'n'));
730
            $productTemplate['discountedShippingFormated'] = $oledrion_Currency->amountForDisplay($discountedShipping);
731
            $productTemplate['totalPriceFormated']         = $oledrion_Currency->amountInCurrency($totalPrice);
732
            $productTemplate['templateCategory']           = $associatedCategory;
733
            $productTemplate['templateVendor']             = $associatedVendor;
734
            $productTemplate['templateManufacturers']      = $associatedManufacturers;
735
            $productTemplate['manufacturersJoinList']      = $manufacturersJoinList;
736
            $this->cartForTemplate[]                       = $productTemplate;
737
        }// foreach sur les produits du panier
738
739
        // Traitement des règles générales s'il y en a
740
        if (count($this->rulesForTheWhole) > 0) {
741
            // $discountsDescription
742
            foreach ($this->rulesForTheWhole as $rule) {
743
                switch ($rule->disc_price_type) {
744
                    case OLEDRION_DISCOUNT_PRICE_TYPE2:
745
                        // D'un montant ou d'un pourcentage
746
                        if ($rule->disc_price_amount_on == OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_CART) {
747
                            // Règle à appliquer sur le panier
748
                            if ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_PERCENT) {
749
                                // Réduction en pourcentage
750
                                $totalHT  = $this->getDiscountedPrice($totalHT, $rule->getVar('disc_price_amount_amount'));
751
                                $totalVAT = $this->getDiscountedPrice($totalVAT, $rule->getVar('disc_price_amount_amount'));
752
                            } elseif ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_MONEY) {
753
                                // Réduction d'un montant en euros
754
                                $totalHT  -= (float)$rule->getVar('disc_price_amount_amount');
755
                                $totalVAT -= (float)$rule->getVar('disc_price_amount_amount');
756
                            }
757
758
                            // Pas de montants négatifs
759
                            OledrionUtility::doNotAcceptNegativeAmounts($totalHT);
760
                            OledrionUtility::doNotAcceptNegativeAmounts($totalVAT);
761
                            $discountsDescription[] = $rule->disc_description;
762
                            ++$discountsCount;
763
                        }// Règle à appliquer sur le panier
764
                        break;
765
                }    // Switch
766
            }    // Foreach
767
        }// S'il y a des règles globales
768
        // Les totaux "renvoyés" à l'appelant
769
        $shippingAmount = $totalShipping;
770
        $commandAmount  = $totalHT;
771
772
        $vatAmount        = $totalVAT;
773
        $commandAmountTTC = $totalHT + $totalVAT + $totalShipping;
774
775
        $cartForTemplate = $this->cartForTemplate;
776
777
        return true;
778
    }
779
}
780