Пример #1
0
 /**
  * Calcul de la facture en fonction du panier
  * Contenu du panier en session :
  *
  * 	$datas['number'] = Indice du produit dans le panier
  * 	$datas['id'] = Identifiant du produit dans la base
  * 	$datas['qty'] = Quantité voulue
  *  $datas['attributes'] = Attributs produit array('attr_id' => id attribut, 'values' => array(valueId1, valueId2 ...))
  *
  * En variable privé, le panier (dans $cart) contient la même chose + un objet 'oledrion_products' dans la clé 'product'
  *
  * @param array $cartForTemplate Contenu du caddy à passer au template (en fait la liste des produits)
  * @param boolean emptyCart Indique si le panier est vide ou pas
  * @param float $shippingAmount Montant des frais de port
  * @param float $commandAmount Montant HT de la commande
  * @param float $vatAmount Montant de la TVA
  * @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)
  * @param float $commandAmountTTC Montant TTC de la commande
  * @param array $discountsDescription Descriptions des remises GLOBALES appliquées (et pas les remises par produit !)
  * @param integer $discountsCount	Le nombre TOTAL de réductions appliquées (individuellement ou sur la globalité du panier)
  *
  * TODO: Passer les paramètres sous forme d'objet
  */
 function computeCart(&$cartForTemplate, &$emptyCart, &$shippingAmount, &$commandAmount, &$vatAmount, &$goOn, &$commandAmountTTC, &$discountsDescription, &$discountsCount)
 {
     $emptyCart = false;
     $goOn = '';
     $vats = array();
     $cpt = 0;
     $discountsCount = 0;
     $this->cart = isset($_SESSION[OledrionOledrion_caddyHandler::CADDY_NAME]) ? $_SESSION[OledrionOledrion_caddyHandler::CADDY_NAME] : array();
     $cartCount = count($this->cart);
     if ($cartCount == 0) {
         $emptyCart = true;
         return true;
     }
     // Réinitialisation des données privées
     $this->initializePrivateData();
     // Chargement des objets produits associés aux produits du panier et calcul des quantités par catégorie
     $this->loadProductsAssociatedToCart();
     // Chargement des TVA
     $vats = $this->handlers->h_oledrion_vat->getAllVats(new oledrion_parameters());
     $oledrion_Currency =& oledrion_Currency::getInstance();
     $caddyCount = count($this->cart);
     // Initialisation des totaux généraux (ht, tva et frais de port)
     $totalHT = $totalVAT = $totalShipping = 0.0;
     // 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
     foreach ($this->cart as $cartProduct) {
         if (floatval($cartProduct['product']->getVar('product_discount_price', 'n')) > 0) {
             $ht = floatval($cartProduct['product']->getVar('product_discount_price', 'n'));
         } else {
             $ht = floatval($cartProduct['product']->getVar('product_price', 'n'));
         }
         // S'il y a des options, on rajoute leur montant
         $productAttributes = array();
         if (is_array($cartProduct['attributes']) && count($cartProduct['attributes']) > 0) {
             $ht += $this->handlers->h_oledrion_attributes->getProductOptionsPrice($cartProduct['attributes'], $cartProduct['product']->getVar('product_vat_id'), $productAttributes);
         }
         $discountedPrice = $ht;
         $quantity = intval($cartProduct['qty']);
         if (oledrion_utils::getModuleOption('shipping_quantity')) {
             $discountedShipping = floatval($cartProduct['product']->getVar('product_shipping_price', 'n') * $quantity);
         } else {
             $discountedShipping = floatval($cartProduct['product']->getVar('product_shipping_price', 'n'));
         }
         $totalPrice = 0.0;
         $reduction = '';
         $cpt++;
         if ($cpt == $caddyCount) {
             // On arrive sur le dernier produit
             $category = null;
             $category = $this->handlers->h_oledrion_cat->get($cartProduct['product']->getVar('product_cid'));
             if (is_object($category)) {
                 $goOn = $category->getLink();
             }
         }
         // Boucle sur les règles
         foreach ($this->allActiveRules as $rule) {
             $applyRule = false;
             if ($rule->disc_group != 0 && oledrion_utils::isMemberOfGroup($rule->disc_group) || $rule->disc_group == 0) {
                 if ($rule->disc_cat_cid != 0 && $cartProduct['product']->getVar('product_cid') == $rule->disc_cat_cid || $rule->disc_cat_cid == 0) {
                     if ($rule->disc_vendor_id != 0 && $cartProduct['product']->getVar('disc_vendor_id') == $rule->disc_vendor_id || $rule->disc_vendor_id == 0) {
                         if ($rule->disc_product_id != 0 && $cartProduct['product']->getVar('product_id') == $rule->disc_product_id || $rule->disc_product_id == 0) {
                             // Dans quel cas appliquer la réduction ?
                             switch ($rule->disc_price_case) {
                                 case OLEDRION_DISCOUNT_PRICE_CASE_ALL:
                                     // Dans tous les cas
                                     $applyRule = true;
                                     break;
                                 case OLEDRION_DISCOUNT_PRICE_CASE_FIRST_BUY:
                                     // Si c'est le premier achat de l'utilisateur sur le site
                                     if ($this->handlers->h_oledrion_commands->isFirstCommand()) {
                                         $applyRule = true;
                                     }
                                     break;
                                 case OLEDRION_DISCOUNT_PRICE_CASE_PRODUCT_NEVER:
                                     // Si le produit n'a jamais été acheté par le client
                                     if (!$this->handlers->h_oledrion_commands->productAlreadyBought(0, $cartProduct['product']->getVar('product_id'))) {
                                         $applyRule = true;
                                     }
                                     break;
                                 case OLEDRION_DISCOUNT_PRICE_CASE_QTY_IS:
                                     // Si la quantité de produit est ... à ...
                                     switch ($rule->disc_price_case_qty_cond) {
                                         case OLEDRION_DISCOUNT_PRICE_QTY_COND1:
                                             // >
                                             if ($cartProduct['qty'] > $rule->disc_price_case_qty_value) {
                                                 $applyRule = true;
                                             }
                                             break;
                                         case OLEDRION_DISCOUNT_PRICE_QTY_COND2:
                                             // >=
                                             if ($cartProduct['qty'] >= $rule->disc_price_case_qty_value) {
                                                 $applyRule = true;
                                             }
                                             break;
                                         case OLEDRION_DISCOUNT_PRICE_QTY_COND3:
                                             // <
                                             if ($cartProduct['qty'] < $rule->disc_price_case_qty_value) {
                                                 $applyRule = true;
                                             }
                                             break;
                                         case OLEDRION_DISCOUNT_PRICE_QTY_COND4:
                                             // <=
                                             if ($cartProduct['qty'] <= $rule->disc_price_case_qty_value) {
                                                 $applyRule = true;
                                             }
                                             break;
                                         case OLEDRION_DISCOUNT_PRICE_QTY_COND5:
                                             // ==
                                             if ($cartProduct['qty'] == $rule->disc_price_case_qty_value) {
                                                 $applyRule = true;
                                             }
                                             break;
                                     }
                             }
                         }
                     }
                 }
             }
             if ($applyRule) {
                 // Il faut appliquer la règle
                 // On calcule le nouveau prix ht du produit
                 switch ($rule->disc_price_type) {
                     case OLEDRION_DISCOUNT_PRICE_TYPE1:
                         // Montant dégressif selon les quantités
                         if ($quantity >= $rule->disc_price_degress_l1qty1 && $quantity <= $rule->disc_price_degress_l1qty2) {
                             $discountedPrice = floatval($rule->getVar('disc_price_degress_l1total', 'n'));
                         }
                         if ($quantity >= $rule->disc_price_degress_l2qty1 && $quantity <= $rule->disc_price_degress_l2qty2) {
                             $discountedPrice = floatval($rule->getVar('disc_price_degress_l2total', 'n'));
                         }
                         if ($quantity >= $rule->disc_price_degress_l3qty1 && $quantity <= $rule->disc_price_degress_l3qty2) {
                             $discountedPrice = floatval($rule->getVar('disc_price_degress_l3total', 'n'));
                         }
                         if ($quantity >= $rule->disc_price_degress_l4qty1 && $quantity <= $rule->disc_price_degress_l4qty2) {
                             $discountedPrice = floatval($rule->getVar('disc_price_degress_l4total', 'n'));
                         }
                         if ($quantity >= $rule->disc_price_degress_l5qty1 && $quantity <= $rule->disc_price_degress_l5qty2) {
                             $discountedPrice = floatval($rule->getVar('disc_price_degress_l5total', 'n'));
                         }
                         $reduction = $rule->disc_description;
                         $discountsCount++;
                         break;
                     case OLEDRION_DISCOUNT_PRICE_TYPE2:
                         // D'un montant ou d'un pourcentage
                         if ($rule->disc_price_amount_on == OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_PRODUCT) {
                             // Réduction sur le produit
                             if ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_PERCENT) {
                                 // Réduction en pourcentage
                                 $discountedPrice = $this->getDiscountedPrice($discountedPrice, $rule->getVar('disc_price_amount_amount', 'n'));
                             } elseif ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_MONEY) {
                                 // Réduction d'un montant en euros
                                 $discountedPrice -= floatval($rule->getVar('disc_price_amount_amount', 'n'));
                             }
                             // Pas de montants négatifs
                             oledrion_utils::doNotAcceptNegativeAmounts($discountedPrice);
                             $reduction = $rule->disc_description;
                             $discountsCount++;
                         } elseif ($rule->disc_price_amount_on == OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_CART) {
                             // Règle à appliquer sur le panier
                             if (!isset($this->rulesForTheWhole[$rule->disc_id])) {
                                 $this->rulesForTheWhole[$rule->disc_id] = $rule;
                             }
                         }
                         break;
                 }
                 // On passe au montant des frais de port
                 switch ($rule->disc_shipping_type) {
                     case OLEDRION_DISCOUNT_SHIPPING_TYPE1:
                         // A payer dans leur intégralité, rien à faire
                         break;
                     case OLEDRION_DISCOUNT_SHIPPING_TYPE2:
                         // Totalement gratuits si le client commande plus de X euros d'achat
                         if ($this->totalAmountBeforeDiscounts > $rule->disc_shipping_free_morethan) {
                             $discountedShipping = 0.0;
                         }
                         break;
                     case OLEDRION_DISCOUNT_SHIPPING_TYPE3:
                         // Frais de port réduits de X euros si la commande est > x
                         if ($this->totalAmountBeforeDiscounts > $rule->disc_shipping_reduce_cartamount) {
                             $discountedShipping -= floatval($rule->getVar('disc_shipping_reduce_amount', 'n'));
                         }
                         // Pas de montants négatifs
                         oledrion_utils::doNotAcceptNegativeAmounts($discountedShipping);
                         break;
                     case OLEDRION_DISCOUNT_SHIPPING_TYPE4:
                         // Frais de port dégressifs
                         if ($quantity >= $rule->disc_shipping_degress_l1qty1 && $quantity <= $rule->disc_shipping_degress_l1qty2) {
                             $discountedShipping = floatval($rule->getVar('disc_shipping_degress_l1total', 'n'));
                         }
                         if ($quantity >= $rule->disc_shipping_degress_l2qty1 && $quantity <= $rule->disc_shipping_degress_l2qty2) {
                             $discountedShipping = floatval($rule->getVar('disc_shipping_degress_l2total', 'n'));
                         }
                         if ($quantity >= $rule->disc_shipping_degress_l3qty1 && $quantity <= $rule->disc_shipping_degress_l3qty2) {
                             $discountedShipping = floatval($rule->getVar('disc_shipping_degress_l3total', 'n'));
                         }
                         if ($quantity >= $rule->disc_shipping_degress_l4qty1 && $quantity <= $rule->disc_shipping_degress_l4qty2) {
                             $discountedShipping = floatval($rule->getVar('disc_shipping_degress_l4total', 'n'));
                         }
                         if ($quantity >= $rule->disc_shipping_degress_l5qty1 && $quantity <= $rule->disc_shipping_degress_l5qty2) {
                             $discountedShipping = floatval($rule->getVar('disc_shipping_degress_l5total', 'n'));
                         }
                         break;
                 }
                 // Sélection du type de réduction sur les frais de port
             }
             // Il faut appliquer la règle de réduction
         }
         // Boucle sur les réductions
         // Calcul de la TVA du produit
         $vatId = $cartProduct['product']->getVar('product_vat_id');
         if (is_array($vats) && isset($vats[$vatId])) {
             $vatRate = floatval($vats[$vatId]->getVar('vat_rate', 'n'));
             $vatAmount = oledrion_utils::getVAT($discountedPrice * $quantity, $vatRate);
         } else {
             $vatRate = 0.0;
             $vatAmount = 0.0;
         }
         // Calcul du TTC du produit ((ht * qte) + tva + frais de port)
         $totalPrice = floatval($discountedPrice * $quantity + $vatAmount + $discountedShipping);
         // Les totaux généraux
         $totalHT += $discountedPrice * $quantity;
         $totalVAT += $vatAmount;
         $totalShipping += $discountedShipping;
         // Recherche des éléments associés au produit
         $associatedVendor = $associatedCategory = $associatedManufacturers = array();
         $manufacturersJoinList = '';
         // Le vendeur
         if (isset($this->associatedVendors[$cartProduct['product']->product_vendor_id])) {
             $associatedVendor = $this->associatedVendors[$cartProduct['product']->product_vendor_id]->toArray();
         }
         // La catégorie
         if (isset($this->associatedCategories[$cartProduct['product']->product_cid])) {
             $associatedCategory = $this->associatedCategories[$cartProduct['product']->product_cid]->toArray();
         }
         // Les fabricants
         $product_id = $cartProduct['product']->product_id;
         if (isset($this->associatedManufacturersPerProduct[$product_id])) {
             // Recherche de la liste des fabricants associés à ce produit
             $manufacturers = $this->associatedManufacturersPerProduct[$product_id];
             $manufacturersList = array();
             foreach ($manufacturers as $manufacturer_id) {
                 if (isset($this->associatedManufacturers[$manufacturer_id])) {
                     $associatedManufacturers[] = $this->associatedManufacturers[$manufacturer_id]->toArray();
                 }
                 $manufacturersList[] = $this->associatedManufacturers[$manufacturer_id]->manu_commercialname . ' ' . $this->associatedManufacturers[$manufacturer_id]->manu_name;
             }
             $manufacturersJoinList = implode(OLEDRION_STRING_TO_JOIN_MANUFACTURERS, $manufacturersList);
         }
         $productTemplate = array();
         $productTemplate = $cartProduct['product']->toArray();
         $productTemplate['attributes'] = $productAttributes;
         $productTemplate['number'] = $cartProduct['number'];
         $productTemplate['id'] = $cartProduct['id'];
         $productTemplate['product_qty'] = $cartProduct['qty'];
         $productTemplate['unitBasePrice'] = $ht;
         // Prix unitaire HT SANS réduction
         $productTemplate['discountedPrice'] = $discountedPrice;
         // Prix unitaire HT AVEC réduction
         $productTemplate['discountedPriceWithQuantity'] = $discountedPrice * $quantity;
         // Prix HT AVEC réduction et la quantité
         // Les même prix mais formatés
         $productTemplate['unitBasePriceFormated'] = $oledrion_Currency->amountForDisplay($ht);
         // Prix unitaire HT SANS réduction
         $productTemplate['discountedPriceFormated'] = $oledrion_Currency->amountForDisplay($discountedPrice);
         // Prix unitaire HT AVEC réduction
         $productTemplate['discountedPriceWithQuantityFormated'] = $oledrion_Currency->amountForDisplay($discountedPrice * $quantity);
         // Prix HT AVEC réduction et la quantité
         $productTemplate['vatRate'] = $oledrion_Currency->amountInCurrency($vatRate);
         $productTemplate['vatAmount'] = $vatAmount;
         $productTemplate['normalShipping'] = $cartProduct['product']->getVar('product_shipping_price', 'n');
         $productTemplate['discountedShipping'] = $discountedShipping;
         $productTemplate['totalPrice'] = $totalPrice;
         $productTemplate['reduction'] = $reduction;
         $productTemplate['templateProduct'] = $cartProduct['product']->toArray();
         $productTemplate['vatAmountFormated'] = $oledrion_Currency->amountInCurrency($vatAmount);
         $productTemplate['normalShippingFormated'] = $oledrion_Currency->amountForDisplay($cartProduct['product']->getVar('product_shipping_price', 'n'));
         $productTemplate['discountedShippingFormated'] = $oledrion_Currency->amountForDisplay($discountedShipping);
         $productTemplate['totalPriceFormated'] = $oledrion_Currency->amountInCurrency($totalPrice);
         $productTemplate['templateCategory'] = $associatedCategory;
         $productTemplate['templateVendor'] = $associatedVendor;
         $productTemplate['templateManufacturers'] = $associatedManufacturers;
         $productTemplate['manufacturersJoinList'] = $manufacturersJoinList;
         $this->cartForTemplate[] = $productTemplate;
     }
     // foreach sur les produits du panier
     // Traitement des règles générales s'il y en a
     if (count($this->rulesForTheWhole) > 0) {
         // $discountsDescription
         foreach ($this->rulesForTheWhole as $rule) {
             switch ($rule->disc_price_type) {
                 case OLEDRION_DISCOUNT_PRICE_TYPE2:
                     // D'un montant ou d'un pourcentage
                     if ($rule->disc_price_amount_on == OLEDRION_DISCOUNT_PRICE_AMOUNT_ON_CART) {
                         // Règle à appliquer sur le panier
                         if ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_PERCENT) {
                             // Réduction en pourcentage
                             $totalHT = $this->getDiscountedPrice($totalHT, $rule->getVar('disc_price_amount_amount'));
                             $totalVAT = $this->getDiscountedPrice($totalVAT, $rule->getVar('disc_price_amount_amount'));
                         } elseif ($rule->disc_price_amount_type == OLEDRION_DISCOUNT_PRICE_REDUCE_MONEY) {
                             // Réduction d'un montant en euros
                             $totalHT -= floatval($rule->getVar('disc_price_amount_amount'));
                             $totalVAT -= floatval($rule->getVar('disc_price_amount_amount'));
                         }
                         // Pas de montants négatifs
                         oledrion_utils::doNotAcceptNegativeAmounts($totalHT);
                         oledrion_utils::doNotAcceptNegativeAmounts($totalVAT);
                         $discountsDescription[] = $rule->disc_description;
                         $discountsCount++;
                     }
                     // Règle à appliquer sur le panier
                     break;
             }
             // Switch
         }
         // Foreach
     }
     // S'il y a des règles globales
     // Les totaux "renvoyés" à l'appelant
     $shippingAmount = $totalShipping;
     $commandAmount = $totalHT;
     $vatAmount = $totalVAT;
     $commandAmountTTC = $totalHT + $totalVAT + $totalShipping;
     $cartForTemplate = $this->cartForTemplate;
     return true;
 }