Issues (608)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/Reductions.php (13 issues)

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
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
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
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
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
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
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
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
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