Reductions::getDiscountedPrice()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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();
149
        $critere1 = new \CriteriaCompo();
150
        $critere1->add(new \Criteria('disc_date_from', 0, '='));
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();
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
     * @param mixed  $emptyCart
412
     * @param mixed  $checkoutAttributes
413
     * @return bool
414
     */
415
416
    // B.R. Added: $checkoutAttributes
417
    public function computeCart(
418
        &$cartForTemplate,
419
        &$emptyCart,
420
        &$shippingAmount,
421
        &$commandAmount,
422
        &$vatAmount,
423
        &$goOn,
424
        &$commandAmountTTC,
425
        &$discountsDescription,
426
        &$discountsCount,
427
        &$checkoutAttributes)// B.R.
428
429
    {
430
        $emptyCart      = false;
431
        $goOn           = '';
432
        $vats           = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $vats is dead and can be removed.
Loading history...
433
        $cpt            = 0;
434
        $discountsCount = 0;
435
        $this->cart     = isset($_SESSION[Oledrion\CaddyHandler::CADDY_NAME]) ? $_SESSION[Oledrion\CaddyHandler::CADDY_NAME] : [];
436
        $cartCount      = count($this->cart);
437
        if (0 == $cartCount) {
438
            $emptyCart = true;
439
440
            return true;
441
        }
442
        $db                = \XoopsDatabaseFactory::getDatabaseConnection();
443
        $commandsHandler   = new Oledrion\CommandsHandler($db);
444
        $attributesHandler = new Oledrion\AttributesHandler($db);
445
        $categoryHandler   = new Oledrion\CategoryHandler($db);
446
447
        // Réinitialisation des données privées
448
        $this->initializePrivateData();
449
        // Chargement des objets produits associés aux produits du panier et calcul des quantités par catégorie
450
        $this->loadProductsAssociatedToCart();
451
        // Chargement des TVA
452
        if (!isset($_POST['cmd_country']) || empty($_POST['cmd_country'])) {
453
            $_POST['cmd_country'] = OLEDRION_DEFAULT_COUNTRY;
454
        }
455
        $vatHandler       = new Oledrion\VatHandler($db);
456
        $vats             = $vatHandler->getCountryVats($_POST['cmd_country']);
457
        $oledrionCurrency = Oledrion\Currency::getInstance();
458
        $caddyCount       = count($this->cart);
459
460
        // Initialisation des totaux généraux (ht, tva et frais de port)
461
        $totalHT = $totalVAT = $totalShipping = 0.0;
462
463
        // 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
464
        foreach ($this->cart as $cartProduct) {
465
            if ((float)$cartProduct['product']->getVar('product_discount_price', 'n') > 0) {
466
                $ht = (float)$cartProduct['product']->getVar('product_discount_price', 'n');
467
            } else {
468
                $ht = (float)$cartProduct['product']->getVar('product_price', 'n');
469
            }
470
            // S'il y a des options, on rajoute leur montant
471
            $productAttributes = [];
472
            if (is_array($cartProduct['attributes']) && count($cartProduct['attributes']) > 0) {
473
                $ht += $attributesHandler->getProductOptionsPrice($cartProduct['attributes'], $cartProduct['product']->getVar('product_vat_id'), $productAttributes);
474
            }
475
476
            $discountedPrice = $ht;
477
            $quantity        = (int)$cartProduct['qty'];
478
479
            if (Oledrion\Utility::getModuleOption('shipping_quantity')) {
480
                $discountedShipping = (float)($cartProduct['product']->getVar('product_shipping_price', 'n') * $quantity);
481
            } else {
482
                $discountedShipping = (float)$cartProduct['product']->getVar('product_shipping_price', 'n');
483
            }
484
            $totalPrice = 0.0;
0 ignored issues
show
Unused Code introduced by
The assignment to $totalPrice is dead and can be removed.
Loading history...
485
            $reduction  = '';
486
487
            // B.R. Start
488
            // If any product in cart does not skip optional checkout step, need to perform
489
            if (0 == $cartProduct['product']->getVar('skip_packing', 'n')) {
490
                $checkoutAttributes['skip_packing'] = 0;
491
            }
492
            if (0 == $cartProduct['product']->getVar('skip_location', 'n')) {
493
                $checkoutAttributes['skip_location'] = 0;
494
            }
495
            if (0 == $cartProduct['product']->getVar('skip_delivery', 'n')) {
496
                $checkoutAttributes['skip_delivery'] = 0;
497
            }
498
            // B.R. End
499
500
            ++$cpt;
501
            if ($cpt == $caddyCount) {
502
                // On arrive sur le dernier produit
503
                $category = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $category is dead and can be removed.
Loading history...
504
                //mb                $category = $this->handlers->h_oledrion_cat->get($cartProduct['product']->getVar('product_cid'));
505
                $category = $categoryHandler->get($cartProduct['product']->getVar('product_cid'));
506
                if (is_object($category)) {
507
                    $goOn = $category->getLink();
0 ignored issues
show
Bug introduced by
The method getLink() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Oledrion\Products or XoopsModules\Oledrion\Manufacturer or XoopsModules\Oledrion\Category or XoopsModules\Oledrion\Lists. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

507
                    /** @scrutinizer ignore-call */ 
508
                    $goOn = $category->getLink();
Loading history...
508
                }
509
            }
510
511
            // Boucle sur les règles
512
            foreach ($this->allActiveRules as $rule) {
513
                $applyRule = false;
514
                if (0 == $rule->disc_group || (0 != $rule->disc_group && Oledrion\Utility::isMemberOfGroup($rule->disc_group))) {
515
                    if (0 == $rule->disc_cat_cid || (0 != $rule->disc_cat_cid && $cartProduct['product']->getVar('product_cid') == $rule->disc_cat_cid)) {
516
                        if (0 == $rule->disc_vendor_id || (0 != $rule->disc_vendor_id && $cartProduct['product']->getVar('disc_vendor_id') == $rule->disc_vendor_id)) {
517
                            if (0 == $rule->disc_product_id || (0 != $rule->disc_product_id && $cartProduct['product']->getVar('product_id') == $rule->disc_product_id)) {
518
                                // Dans quel cas appliquer la réduction ?
519
                                switch ($rule->disc_price_case) {
520
                                    case Constants::OLEDRION_DISCOUNT_PRICE_CASE_ALL:
521
                                        // Dans tous les cas
522
523
                                        $applyRule = true;
524
525
                                        break;
526
                                    case Constants::OLEDRION_DISCOUNT_PRICE_CASE_FIRST_BUY:
527
                                        // Si c'est le premier achat de l'utilisateur sur le site
528
529
                                        if ($commandsHandler->isFirstCommand()) {
530
                                            $applyRule = true;
531
                                        }
532
533
                                        break;
534
                                    case Constants::OLEDRION_DISCOUNT_PRICE_CASE_PRODUCT_NEVER:
535
                                        // Si le produit n'a jamais été acheté par le client
536
537
                                        if (!$commandsHandler->productAlreadyBought(0, $cartProduct['product']->getVar('product_id'))) {
538
                                            $applyRule = true;
539
                                        }
540
541
                                        break;
542
                                    case Constants::OLEDRION_DISCOUNT_PRICE_CASE_QTY_IS:
543
                                        // Si la quantité de produit est ... à ...
544
545
                                        switch ($rule->disc_price_case_qty_cond) {
546
                                            case Constants::OLEDRION_DISCOUNT_PRICE_QTY_COND1:
547
                                                // >
548
549
                                                if ($cartProduct['qty'] > $rule->disc_price_case_qty_value) {
550
                                                    $applyRule = true;
551
                                                }
552
553
                                                break;
554
                                            case Constants::OLEDRION_DISCOUNT_PRICE_QTY_COND2:
555
                                                // >=
556
557
                                                if ($cartProduct['qty'] >= $rule->disc_price_case_qty_value) {
558
                                                    $applyRule = true;
559
                                                }
560
561
                                                break;
562
                                            case Constants::OLEDRION_DISCOUNT_PRICE_QTY_COND3:
563
                                                // <
564
565
                                                if ($cartProduct['qty'] < $rule->disc_price_case_qty_value) {
566
                                                    $applyRule = true;
567
                                                }
568
569
                                                break;
570
                                            case Constants::OLEDRION_DISCOUNT_PRICE_QTY_COND4:
571
                                                // <=
572
573
                                                if ($cartProduct['qty'] <= $rule->disc_price_case_qty_value) {
574
                                                    $applyRule = true;
575
                                                }
576
577
                                                break;
578
                                            case Constants::OLEDRION_DISCOUNT_PRICE_QTY_COND5:
579
                                                // ==
580
581
                                                if ($cartProduct['qty'] == $rule->disc_price_case_qty_value) {
582
                                                    $applyRule = true;
583
                                                }
584
585
                                                break;
586
                                        }
587
                                }
588
                            }
589
                        }
590
                    }
591
                }
592
                if ($applyRule) {
593
                    // Il faut appliquer la règle
594
                    // On calcule le nouveau prix ht du produit
595
                    switch ($rule->disc_price_type) {
596
                        case Constants::OLEDRION_DISCOUNT_PRICE_TYPE1:
597
                            // Montant dégressif selon les quantités
598
599
                            if ($quantity >= $rule->disc_price_degress_l1qty1 && $quantity <= $rule->disc_price_degress_l1qty2) {
600
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l1total', 'n');
601
                            }
602
                            if ($quantity >= $rule->disc_price_degress_l2qty1 && $quantity <= $rule->disc_price_degress_l2qty2) {
603
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l2total', 'n');
604
                            }
605
                            if ($quantity >= $rule->disc_price_degress_l3qty1 && $quantity <= $rule->disc_price_degress_l3qty2) {
606
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l3total', 'n');
607
                            }
608
                            if ($quantity >= $rule->disc_price_degress_l4qty1 && $quantity <= $rule->disc_price_degress_l4qty2) {
609
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l4total', 'n');
610
                            }
611
                            if ($quantity >= $rule->disc_price_degress_l5qty1 && $quantity <= $rule->disc_price_degress_l5qty2) {
612
                                $discountedPrice = (float)$rule->getVar('disc_price_degress_l5total', 'n');
613
                            }
614
                            $reduction = $rule->disc_description;
615
                            ++$discountsCount;
616
617
                            break;
618
                        case Constants::OLEDRION_DISCOUNT_PRICE_TYPE2:
619
                            // D'un montant ou d'un pourcentage
620
621
                            if (Constants::OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_PRODUCT == $rule->disc_price_amount_on) {
622
                                // Réduction sur le produit
623
                                if (Constants::OLEDRION_DISCOUNT_PRICE_REDUCE_PERCENT == $rule->disc_price_amount_type) {
624
                                    // Réduction en pourcentage
625
                                    $discountedPrice = $this->getDiscountedPrice($discountedPrice, $rule->getVar('disc_price_amount_amount', 'n'));
626
                                } elseif (Constants::OLEDRION_DISCOUNT_PRICE_REDUCE_MONEY == $rule->disc_price_amount_type) {
627
                                    // Réduction d'un montant en euros
628
                                    $discountedPrice -= (float)$rule->getVar('disc_price_amount_amount', 'n');
629
                                }
630
631
                                // Pas de montants négatifs
632
                                Oledrion\Utility::doNotAcceptNegativeAmounts($discountedPrice);
633
                                $reduction = $rule->disc_description;
634
                                ++$discountsCount;
635
                            } elseif (Constants::OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_CART == $rule->disc_price_amount_on) {
636
                                // Règle à appliquer sur le panier
637
                                if (!isset($this->rulesForTheWhole[$rule->disc_id])) {
638
                                    $this->rulesForTheWhole[$rule->disc_id] = $rule;
639
                                }
640
                            }
641
642
                            break;
643
                    }
644
645
                    // On passe au montant des frais de port
646
                    switch ($rule->disc_shipping_type) {
647
                        case Constants::OLEDRION_DISCOUNT_SHIPPING_TYPE1:
648
                            // A payer dans leur intégralité, rien à faire
649
650
                            break;
651
                        case Constants::OLEDRION_DISCOUNT_SHIPPING_TYPE2:
652
                            // Totalement gratuits si le client commande plus de X euros d'achat
653
654
                            if ($this->totalAmountBeforeDiscounts > $rule->disc_shipping_free_morethan) {
655
                                $discountedShipping = 0.0;
656
                            }
657
658
                            break;
659
                        case Constants::OLEDRION_DISCOUNT_SHIPPING_TYPE3:
660
                            // Frais de port réduits de X euros si la commande est > x
661
662
                            if ($this->totalAmountBeforeDiscounts > $rule->disc_shipping_reduce_cartamount) {
663
                                $discountedShipping -= (float)$rule->getVar('disc_shipping_reduce_amount', 'n');
664
                            }
665
                            // Pas de montants négatifs
666
                            Oledrion\Utility::doNotAcceptNegativeAmounts($discountedShipping);
667
668
                            break;
669
                        case Constants::OLEDRION_DISCOUNT_SHIPPING_TYPE4:
670
                            // Frais de port dégressifs
671
672
                            if ($quantity >= $rule->disc_shipping_degress_l1qty1 && $quantity <= $rule->disc_shipping_degress_l1qty2) {
673
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l1total', 'n');
674
                            }
675
                            if ($quantity >= $rule->disc_shipping_degress_l2qty1 && $quantity <= $rule->disc_shipping_degress_l2qty2) {
676
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l2total', 'n');
677
                            }
678
                            if ($quantity >= $rule->disc_shipping_degress_l3qty1 && $quantity <= $rule->disc_shipping_degress_l3qty2) {
679
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l3total', 'n');
680
                            }
681
                            if ($quantity >= $rule->disc_shipping_degress_l4qty1 && $quantity <= $rule->disc_shipping_degress_l4qty2) {
682
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l4total', 'n');
683
                            }
684
                            if ($quantity >= $rule->disc_shipping_degress_l5qty1 && $quantity <= $rule->disc_shipping_degress_l5qty2) {
685
                                $discountedShipping = (float)$rule->getVar('disc_shipping_degress_l5total', 'n');
686
                            }
687
688
                            break;
689
                    }    // Sélection du type de réduction sur les frais de port
690
                }    // Il faut appliquer la règle de réduction
691
            }// Boucle sur les réductions
692
693
            // Calcul de la TVA du produit
694
            $vatId = $cartProduct['product']->getVar('product_vat_id');
695
            if (is_array($vats) && isset($vats[$vatId])) {
696
                $vatRate   = (float)$vats[$vatId]->getVar('vat_rate', 'n');
697
                $vatAmount = Oledrion\Utility::getVAT($discountedPrice * $quantity, $vatRate);
698
            } else {
699
                $vatRate   = 0.0;
700
                $vatAmount = 0.0;
701
            }
702
703
            // Calcul du TTC du produit ((ht * qte) + tva + frais de port)
704
            $totalPrice = (($discountedPrice * $quantity) + $vatAmount + $discountedShipping);
705
706
            // Les totaux généraux
707
            $totalHT       += ($discountedPrice * $quantity);
708
            $totalVAT      += $vatAmount;
709
            $totalShipping += $discountedShipping;
710
711
            // Recherche des éléments associés au produit
712
            $associatedVendor      = $associatedCategory = $associatedManufacturers = [];
713
            $manufacturersJoinList = '';
714
            // Le vendeur
715
            if (isset($this->associatedVendors[$cartProduct['product']->product_vendor_id])) {
716
                $associatedVendor = $this->associatedVendors[$cartProduct['product']->product_vendor_id]->toArray();
717
            }
718
719
            // La catégorie
720
            if (isset($this->associatedCategories[$cartProduct['product']->product_cid])) {
721
                $associatedCategory = $this->associatedCategories[$cartProduct['product']->product_cid]->toArray();
722
            }
723
724
            // Les fabricants
725
            $product_id = $cartProduct['product']->product_id;
726
            if (isset($this->associatedManufacturersPerProduct[$product_id])) {
727
                // Recherche de la liste des fabricants associés à ce produit
728
                $manufacturers     = $this->associatedManufacturersPerProduct[$product_id];
729
                $manufacturersList = [];
730
                foreach ($manufacturers as $manufacturer_id) {
731
                    if (isset($this->associatedManufacturers[$manufacturer_id])) {
732
                        $associatedManufacturers[] = $this->associatedManufacturers[$manufacturer_id]->toArray();
733
                    }
734
                    $manufacturersList[] = $this->associatedManufacturers[$manufacturer_id]->manu_commercialname . ' ' . $this->associatedManufacturers[$manufacturer_id]->manu_name;
735
                }
736
                $manufacturersJoinList = implode(OLEDRION_STRING_TO_JOIN_MANUFACTURERS, $manufacturersList);
737
            }
738
            $productTemplate                = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $productTemplate is dead and can be removed.
Loading history...
739
            $productTemplate                = $cartProduct['product']->toArray();
740
            $productTemplate['attributes']  = $productAttributes;
741
            $productTemplate['number']      = $cartProduct['number'];
742
            $productTemplate['id']          = $cartProduct['id'];
743
            $productTemplate['product_qty'] = $cartProduct['qty'];
744
745
            $productTemplate['unitBasePrice'] = $ht;
746
            // Prix unitaire HT SANS réduction
747
            $productTemplate['discountedPrice'] = $discountedPrice;
748
            // Prix unitaire HT AVEC réduction
749
            $productTemplate['discountedPriceWithQuantity'] = $discountedPrice * $quantity;
750
            // Prix HT AVEC réduction et la quantité
751
            // Les même prix mais formatés
752
            $productTemplate['unitBasePriceFormated'] = $oledrionCurrency->amountForDisplay($ht);
753
            // Prix unitaire HT SANS réduction
754
            $productTemplate['discountedPriceFormated'] = $oledrionCurrency->amountForDisplay($discountedPrice);
755
            // Prix unitaire HT AVEC réduction
756
            $productTemplate['discountedPriceWithQuantityFormated'] = $oledrionCurrency->amountForDisplay($discountedPrice * $quantity);
757
            // Prix HT AVEC réduction et la quantité
758
759
            // Add by voltan
760
            $productTemplate['discountedPriceFormatedOrg'] = $oledrionCurrency->amountForDisplay($ht - $discountedPrice);
761
            $productTemplate['discountedPriceOrg']         = $ht - $discountedPrice;
762
763
            $productTemplate['vatRate']            = $oledrionCurrency->amountInCurrency($vatRate);
764
            $productTemplate['vatAmount']          = $vatAmount;
765
            $productTemplate['normalShipping']     = $cartProduct['product']->getVar('product_shipping_price', 'n');
766
            $productTemplate['discountedShipping'] = $discountedShipping;
767
            $productTemplate['totalPrice']         = $totalPrice;
768
            $productTemplate['reduction']          = $reduction;
769
            $productTemplate['templateProduct']    = $cartProduct['product']->toArray();
770
771
            $productTemplate['vatAmountFormated']          = $oledrionCurrency->amountInCurrency($vatAmount);
772
            $productTemplate['normalShippingFormated']     = $oledrionCurrency->amountForDisplay($cartProduct['product']->getVar('product_shipping_price', 'n'));
773
            $productTemplate['discountedShippingFormated'] = $oledrionCurrency->amountForDisplay($discountedShipping);
774
            $productTemplate['totalPriceFormated']         = $oledrionCurrency->amountForDisplay($totalPrice);
775
            $productTemplate['templateCategory']           = $associatedCategory;
776
            $productTemplate['templateVendor']             = $associatedVendor;
777
            $productTemplate['templateManufacturers']      = $associatedManufacturers;
778
            $productTemplate['manufacturersJoinList']      = $manufacturersJoinList;
779
            $this->cartForTemplate[]                       = $productTemplate;
780
        }// foreach sur les produits du panier
781
782
        // Traitement des règles générales s'il y en a
783
        if (count($this->rulesForTheWhole) > 0) {
784
            // $discountsDescription
785
            foreach ($this->rulesForTheWhole as $rule) {
786
                switch ($rule->disc_price_type) {
787
                    case Constants::OLEDRION_DISCOUNT_PRICE_TYPE2:
788
                        // D'un montant ou d'un pourcentage
789
790
                        if (Constants::OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_CART == $rule->disc_price_amount_on) {
791
                            // Règle à appliquer sur le panier
792
                            if (Constants::OLEDRION_DISCOUNT_PRICE_REDUCE_PERCENT == $rule->disc_price_amount_type) {
793
                                // Réduction en pourcentage
794
                                $totalHT  = $this->getDiscountedPrice($totalHT, $rule->getVar('disc_price_amount_amount'));
795
                                $totalVAT = $this->getDiscountedPrice($totalVAT, $rule->getVar('disc_price_amount_amount'));
796
                            } elseif (Constants::OLEDRION_DISCOUNT_PRICE_REDUCE_MONEY == $rule->disc_price_amount_type) {
797
                                // Réduction d'un montant en euros
798
                                $totalHT  -= (float)$rule->getVar('disc_price_amount_amount');
799
                                $totalVAT -= (float)$rule->getVar('disc_price_amount_amount');
800
                            }
801
802
                            // Pas de montants négatifs
803
                            Oledrion\Utility::doNotAcceptNegativeAmounts($totalHT);
804
                            Oledrion\Utility::doNotAcceptNegativeAmounts($totalVAT);
805
                            $discountsDescription[] = $rule->disc_description;
806
                            ++$discountsCount;
807
                        }// Règle à appliquer sur le panier
808
809
                        break;
810
                }    // Switch
811
            }    // Foreach
812
        }// S'il y a des règles globales
813
        // Les totaux "renvoyés" à l'appelant
814
        $shippingAmount = $totalShipping;
815
        $commandAmount  = $totalHT;
816
817
        $vatAmount        = $totalVAT;
818
        $commandAmountTTC = $totalHT + $totalVAT + $totalShipping;
819
820
        $cartForTemplate = $this->cartForTemplate;
821
822
        return true;
823
    }
824
}
825