Passed
Push — master ( e643a0...1f75e2 )
by Michael
03:19
created

Reductions::computeCart()   F

Complexity

Conditions 91
Paths > 20000

Size

Total Lines 406
Code Lines 222

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 222
dl 0
loc 406
rs 0
c 0
b 0
f 0
cc 91
nc 765394954
nop 10

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace XoopsModules\Oledrion;
4
5
/**
6
 * ****************************************************************************
7
 * oledrion - MODULE FOR XOOPS
8
 * Copyright (c) Hervé Thouzard of Instant Zero (http://www.instant-zero.com)
9
 *
10
 * You may not change or alter any portion of this comment or credits
11
 * of supporting developers from this source code or any supporting source code
12
 * which is considered copyrighted (c) material of the original comment or credit authors.
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
 *
17
 * @copyright       Hervé Thouzard of Instant Zero (http://www.instant-zero.com)
18
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
19
 * @author          Hervé Thouzard of Instant Zero (http://www.instant-zero.com)
20
 *
21
 * Version :
22
 * ****************************************************************************
23
 */
24
25
/**
26
 * Calcul du panier et de ses réductions en fonction des règles de remises
27
 * Cette classe ne gère pas de fichier (elle sert uniquement aux calculs)
28
 *
29
 * Détail des tableaux :
30
 * categoriesProductsCount => Nombre de produits par catégorie
31
 * [clé] = Id Catégorie, [valeur] = Nombre de produits
32
 *
33
 * categoriesProductsQuantities => Quantités de produits par catégorie
34
 * [clé] = Id Catégorie, [valeur] = Quantité de produits
35
 *
36
 * totalProductsQuantities => Quantité totale de tous les produits
37
 *
38
 * associatedManufacturers => Contient la liste des ID uniques de produits
39
 * [clé] = Id Produit, [valeur] = Id produit
40
 *
41
 * associatedVendors => Contient la liste des vendeurs de produits
42
 * [clé] = Id Vendeur, [valeur] = Id Vendeur
43
 *
44
 * associatedAttributesPerProduct => Contient les attributs de chaque produit
45
 * [clé] = Id Produit, [valeurS] = Tous les attributs du produit sous la forme d'objets de type Attributs
46
 *
47
 * associatedCategories => Contient la liste des ID de catégories
48
 * [clé] = Id Catégorie, [valeur] = Id Catégorie
49
 *
50
 * totalAmountBeforeDiscounts => Montant total de la commande avant les réductions
51
 *
52
 * associatedManufacturersPerProduct => Contient la liste des ID des fabricants par produit
53
 * [clé] = Id produit, [valeur] = array(Ids des fabricants)
54
 *
55
 * Les 3 tableaux suivants évoluent ensuite comme ceci :
56
 * associatedManufacturers => Tableau d'objets de type Fabricants
57
 * [clé] = id Fabricant [valeur] = Fabricant sous la forme d'un objet
58
 *
59
 * associatedVendors => Tableau d'ojets de type Vendeurs
60
 * [clé] = Id Vendeur [valeur] = Vendeur sous la forme d'un objet
61
 *
62
 * associatedCategories => Tableau d'objets de type Categories
63
 * [clé] = Id Catégorie [valeur] = Catéagorie sous la forme d'un objet
64
 */
65
66
use XoopsModules\Oledrion;
67
68
/**
69
 * Class Reductions
70
 */
71
class Reductions
72
{
73
    // Ne contient que la liste des règles actives au moment du calcul
74
    private $allActiveRules = [];
75
76
    // Nombre de produits par catégorie
77
    private $categoriesProductsCount = [];
78
79
    // Quantité de produits par catégorie
80
    private $categoriesProductsQuantities = [];
81
82
    /**
83
     * le caddy en mémoire
84
     *  $cart['number'] = Indice du produit
85
     *  $cart['id'] = Identifiant du produit
86
     *  $cart['qty'] = Quantité voulue
87
     *  $cart['product'] = L'objet produit correspondant au panier
88
     */
89
    private $cart = [];
90
91
    /**
92
     * Le caddy pour le template. Consulter les détails du caddy dans la métode ComputeCart
93
     */
94
    private $cartForTemplate = [];
95
96
    /**
97
     * Les règles à appliquer à la fin, sur l'intégralité du panier
98
     */
99
    private $rulesForTheWhole = [];
100
101
    // Le total des quantités de produits avant les réductions
102
    private $totalProductsQuantities = 0;
103
    // Montant total de la commande avant les réductions
104
    private $totalAmountBeforeDiscounts = 0;
105
106
    // Handlers vers les tables du module
107
    //    private $handlers;
108
109
    // Les fabricants associés aux produits du panier
110
    private $associatedManufacturers = [];
111
112
    // Les vendeur associés aux produits du panier
113
    private $associatedVendors = [];
114
115
    // Les catégories associées aux produits du panier
116
    private $associatedCategories = [];
117
118
    // Fabricants associés par produit du panier
119
    private $associatedManufacturersPerProduct = [];
120
121
    // Attributs par produit du panier
122
    private $associatedAttributesPerProduct = [];
123
124
    /**
125
     * Chargement des handlers et des règles actives
126
     */
127
    public function __construct()
128
    {
129
        $this->initHandlers();
130
        $this->loadAllActiveRules();
131
    }
132
133
    /**
134
     * Chargement des handlers
135
     */
136
    private function initHandlers()
137
    {
138
        //        $this->handlers = HandlerManager::getInstance();
139
    }
140
141
    /**
142
     * Chargement de toutes les règles actives de réductions (sans date définie ou avec une période correspondante à aujourd'hui)
143
     */
144
    public function loadAllActiveRules()
145
    {
146
        global $xoopsDB;
147
        require_once dirname(__DIR__) . '/include/common.php';
148
        $critere  = new \CriteriaCompo();
0 ignored issues
show
Bug introduced by
The type CriteriaCompo was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
149
        $critere1 = new \CriteriaCompo();
150
        $critere1->add(new \Criteria('disc_date_from', 0, '='));
0 ignored issues
show
Bug introduced by
The type Criteria was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
151
        $critere1->add(new \Criteria('disc_date_to', 0, '='));
152
        $critere->add($critere1);
153
154
        $critere2 = new \CriteriaCompo();
155
        $critere2->add(new \Criteria('disc_date_from', time(), '<='));
156
        $critere2->add(new \Criteria('disc_date_to', time(), '>='));
157
        $critere->add($critere2, 'OR');
158
159
        //        $this->allActiveRules = $this->handlers->h_oledrion_discounts->getObjects($critere);
160
        //        $this->allActiveRules = $this->handlers->DiscountsHandler->getObjects($critere);
161
        $discountsHandler     = new Oledrion\DiscountsHandler($xoopsDB);
162
        $this->allActiveRules = $discountsHandler->getObjects($critere);
163
    }
164
165
    /**
166
     * Calcul des quantités de produits par catégorie et du nombre de produits par catégorie
167
     *
168
     * @param Products $product
169
     * @param int      $quantity
170
     */
171
    public function computePerCategories(Products $product, $quantity)
172
    {
173
        // Nombre de produits par catégories
174
        if (isset($this->categoriesProductsCount[$product->product_cid])) {
0 ignored issues
show
Bug Best Practice introduced by
The property product_cid does not exist on XoopsModules\Oledrion\Products. Since you implemented __get, consider adding a @property annotation.
Loading history...
175
            ++$this->categoriesProductsCount[$product->product_cid];
176
        } else {
177
            $this->categoriesProductsCount[$product->product_cid] = 1;
178
        }
179
180
        // Mise à jour des quantités par catégories
181
        if (isset($this->categoriesProductsQuantities[$product->product_cid])) {
182
            $this->categoriesProductsQuantities[$product->product_cid] += $quantity;
183
        } else {
184
            $this->categoriesProductsQuantities[$product->product_cid] = $quantity;
185
        }
186
        $this->totalProductsQuantities += $quantity;
187
        // Quantité totale de tous les produits
188
    }
189
190
    /**
191
     * Ajoute à un tableau interne, le fabricant associé à un produit
192
     *
193
     * @param Products $product
194
     */
195
    private function addAssociatedManufacturers(Products $product)
196
    {
197
        if (!isset($this->associatedManufacturers[$product->product_id])) {
0 ignored issues
show
Bug Best Practice introduced by
The property product_id does not exist on XoopsModules\Oledrion\Products. Since you implemented __get, consider adding a @property annotation.
Loading history...
198
            $this->associatedManufacturers[$product->product_id] = $product->product_id;
199
        }
200
    }
201
202
    /**
203
     * Recherche des attributs associés à chaque produit
204
     *
205
     * @param Products $product
206
     * @param array    $attributes
207
     * @since 2.3
208
     */
209
    private function addAssociatedAttributes(Products $product, $attributes)
210
    {
211
        if (!isset($this->associatedAttributesPerProduct[$product->product_id])) {
0 ignored issues
show
Bug Best Practice introduced by
The property product_id does not exist on XoopsModules\Oledrion\Products. Since you implemented __get, consider adding a @property annotation.
Loading history...
212
            $this->associatedAttributesPerProduct[$product->product_id] = $product->getProductsAttributesList($attributes);
213
        }
214
    }
215
216
    /**
217
     * Ajoute à un tableau interne, le vendeur associé à un produit
218
     *
219
     * @param Products $product
220
     */
221
    private function addAssociatedVendors(Products $product)
222
    {
223
        if (!isset($this->associatedVendors[$product->product_vendor_id])) {
0 ignored issues
show
Bug Best Practice introduced by
The property product_vendor_id does not exist on XoopsModules\Oledrion\Products. Since you implemented __get, consider adding a @property annotation.
Loading history...
224
            $this->associatedVendors[$product->product_vendor_id] = $product->product_vendor_id;
225
        }
226
    }
227
228
    /**
229
     * Ajoute à un tableau interne, la catégorie associée à un produit
230
     *
231
     * @param Products $product
232
     */
233
    private function addAssociatedCategories(Products $product)
234
    {
235
        if (!isset($this->associatedCategories[$product->product_cid])) {
0 ignored issues
show
Bug Best Practice introduced by
The property product_cid does not exist on XoopsModules\Oledrion\Products. Since you implemented __get, consider adding a @property annotation.
Loading history...
236
            $this->associatedCategories[$product->product_cid] = $product->product_cid;
237
        }
238
    }
239
240
    /**
241
     * Charge les fabricants associés aux produits du panier
242
     */
243
    private function loadAssociatedManufacturers()
244
    {
245
        if (count($this->associatedManufacturers) > 0) {
246
            $db                  = \XoopsDatabaseFactory::getDatabaseConnection();
0 ignored issues
show
Bug introduced by
The type XoopsDatabaseFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
247
            $manufacturerHandler = new Oledrion\ManufacturerHandler($db);
248
            $productsmanuHandler = new Oledrion\ProductsmanuHandler($db);
249
            sort($this->associatedManufacturers);
250
            $productsIds                   = $this->associatedManufacturers;
251
            $this->associatedManufacturers = [];
252
            // au cas où cela échouerait
253
            $productsManufacturers = $manufacturersIds = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $productsManufacturers is dead and can be removed.
Loading history...
254
            $productsManufacturers = $productsmanuHandler->getFromProductsIds($productsIds);
255
            if (count($productsManufacturers) > 0) {
256
                foreach ($productsManufacturers as $productManufacturer) {
257
                    if (!isset($manufacturersIds[$productManufacturer->pm_manu_id])) {
258
                        $manufacturersIds[$productManufacturer->pm_manu_id] = $productManufacturer->pm_manu_id;
259
                    }
260
                    $this->associatedManufacturersPerProduct[$productManufacturer->pm_product_id][] = $productManufacturer->pm_manu_id;
261
                }
262
                if (count($manufacturersIds) > 0) {
263
                    sort($manufacturersIds);
264
                    $this->associatedManufacturers = $manufacturerHandler->getManufacturersFromIds($manufacturersIds);
265
                }
266
            }
267
        }
268
    }
269
270
    /**
271
     * Charge la liste des vendeurs associés aux produits
272
     */
273
    private function loadAssociatedVendors()
274
    {
275
        if (count($this->associatedVendors) > 0) {
276
            $db             = \XoopsDatabaseFactory::getDatabaseConnection();
277
            $vendorsHandler = new Oledrion\VendorsHandler($db);
278
279
            sort($this->associatedVendors);
280
            $ids                     = $this->associatedVendors;
281
            $this->associatedVendors = $vendorsHandler->getVendorsFromIds($ids);
282
        }
283
    }
284
285
    /**
286
     * Charge les catégories associées aux produits du panier
287
     */
288
    private function loadAssociatedCategories()
289
    {
290
        if (count($this->associatedCategories) > 0) {
291
            sort($this->associatedCategories);
292
            $ids = $this->associatedCategories;
293
            //mb            $this->associatedCategories = $this->handlers->h_oledrion_cat->getCategoriesFromIds($ids);
294
            $db                         = \XoopsDatabaseFactory::getDatabaseConnection();
295
            $categoryHandler            = new Oledrion\CategoryHandler($db);
296
            $this->associatedCategories = $categoryHandler->getCategoriesFromIds($ids);
297
        }
298
    }
299
300
    /**
301
     * Recherche les fabricants, catégories et vendeurs associés à chaque produit
302
     */
303
    public function loadElementsAssociatedToProducts()
304
    {
305
        $this->loadAssociatedManufacturers();
306
        $this->loadAssociatedVendors();
307
        $this->loadAssociatedCategories();
308
    }
309
310
    /**
311
     * Recherche les (objets) produits associés à chaque produit du panier (et lance le calcul des quantités)
312
     */
313
    public function loadProductsAssociatedToCart()
314
    {
315
        $newCart           = [];
316
        $db                = \XoopsDatabaseFactory::getDatabaseConnection();
317
        $productsHandler   = new Oledrion\ProductsHandler($db);
318
        $attributesHandler = new Oledrion\AttributesHandler($db);
319
        foreach ($this->cart as $cartProduct) {
320
            $data               = [];
321
            $data['id']         = $cartProduct['id'];
322
            $data['number']     = $cartProduct['number'];
323
            $data['qty']        = $cartProduct['qty'];
324
            $data['attributes'] = $cartProduct['attributes'];
325
326
            $product = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $product is dead and can be removed.
Loading history...
327
            $product = $productsHandler->get($data['id']);
328
            if (!is_object($product)) {
329
                trigger_error(_OLEDRION_ERROR9);
330
                continue;
331
                // 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)
332
            }
333
            $data['product'] = $product;
334
            // Mise à jour des calculs par catégorie
335
            $this->computePerCategories($product, $data['qty']);
336
            // Recherche des éléments associés à chaque produit
337
            $this->addAssociatedManufacturers($product);
338
            $this->addAssociatedVendors($product);
339
            $this->addAssociatedAttributes($product, $data['attributes']);
340
            $this->addAssociatedCategories($product);
341
342
            // Calcul du total de la commande avant réductions
343
            if ((float)$product->getVar('product_discount_price', 'n') > 0) {
344
                $ht = (float)$product->getVar('product_discount_price', 'n');
345
            } else {
346
                $ht = (float)$product->getVar('product_price', 'n');
347
            }
348
            // S'il y a des options, on rajoute leur montant
349
            if (is_array($data['attributes']) && count($data['attributes']) > 0) {
350
                $ht += $attributesHandler->getProductOptionsPrice($data['attributes'], $product->getVar('product_vat_id'));
351
            }
352
353
            $this->totalAmountBeforeDiscounts += ($data['qty'] * $ht);
354
355
            $newCart[] = $data;
356
        }
357
        $this->loadElementsAssociatedToProducts();
358
        $this->cart = $newCart;
359
    }
360
361
    /**
362
     * Calcul du montant HT auquel on applique un pourcentage de réduction
363
     *
364
     * @param  float $price    Le prix auquel appliquer la réduction
365
     * @param int    $discount Le pourcentage de réduction
366
     * @return float   Le montant réduit
367
     */
368
    private function getDiscountedPrice($price, $discount)
369
    {
370
        return ($price - ($price * ($discount / 100)));
371
    }
372
373
    /**
374
     * Remise à zéro des membres internes
375
     */
376
    private function initializePrivateData()
377
    {
378
        $this->totalProductsQuantities           = 0;
379
        $this->totalAmountBeforeDiscounts        = 0;
380
        $this->rulesForTheWhole                  = [];
381
        $this->cartForTemplate                   = [];
382
        $this->associatedManufacturers           = [];
383
        $this->associatedVendors                 = [];
384
        $this->associatedCategories              = [];
385
        $this->associatedManufacturersPerProduct = [];
386
        $this->associatedAttributesPerProduct    = [];
387
    }
388
389
    /**
390
     * Calcul de la facture en fonction du panier
391
     * Contenu du panier en session :
392
     *
393
     *  $datas['number'] = Indice du produit dans le panier
394
     *  $datas['id'] = Identifiant du produit dans la base
395
     *  $datas['qty'] = Quantité voulue
396
     *  $datas['attributes'] = Attributs produit array('attr_id' => id attribut, 'values' => array(valueId1, valueId2 ...))
397
     *
398
     * En variable privé, le panier (dans $cart) contient la même chose + un objet 'oledrion_products' dans la clé 'product'
399
     *
400
     * @param array  $cartForTemplate       Contenu du caddy à passer au template (en fait la liste des produits)
401
     * @param bool               emptyCart Indique si le panier est vide ou pas
0 ignored issues
show
Bug introduced by
The type XoopsModules\Oledrion\emptyCart was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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