shop; } if (Context::getContext()->customer->id) { if ($id_address_delivery == 0 && (int)$this->id_address_delivery) { // The $id_address_delivery is null, use the cart delivery address $id_address_delivery = $this->id_address_delivery; } elseif ($id_address_delivery == 0) { // The $id_address_delivery is null, get the default customer address $id_address_delivery = (int)Address::getFirstCustomerAddressId((int)Context::getContext()->customer->id); } elseif (!Customer::customerHasAddress(Context::getContext()->customer->id, $id_address_delivery)) { // The $id_address_delivery must be linked with customer $id_address_delivery = 0; } } $quantity = (int)$quantity; $id_product = (int)$id_product; $id_product_attribute = (int)$id_product_attribute; $product = new Product($id_product, false, Configuration::get('PS_LANG_DEFAULT'), $shop->id); if ($id_product_attribute) { $combination = new Combination((int)$id_product_attribute); if ($combination->id_product != $id_product) { return false; } } if (!empty($id_product_attribute)) { $minimal_quantity = (int)Attribute::getAttributeMinimalQty($id_product_attribute); } else { $minimal_quantity = (int)$product->minimal_quantity; } if (!Validate::isLoadedObject($product)) { die(Tools::displayError()); } if (isset(self::$_nbProducts[$this->id])) { unset(self::$_nbProducts[$this->id]); } if (isset(self::$_totalWeight[$this->id])) { unset(self::$_totalWeight[$this->id]); } Hook::exec('actionBeforeCartUpdateQty', array( 'cart' => $this, 'product' => $product, 'id_product_attribute' => $id_product_attribute, 'id_customization' => $id_customization, 'quantity' => $quantity, 'operator' => $operator, 'id_address_delivery' => $id_address_delivery, 'shop' => $shop, 'auto_add_cart_rule' => $auto_add_cart_rule, 'id_configurator' => $id_configurator )); if ((int)$quantity <= 0) { return $this->deleteProduct($id_product, $id_product_attribute, (int)$id_customization, 0, $auto_add_cart_rule, $id_configurator); } elseif (!$product->available_for_order || (Configuration::get('PS_CATALOG_MODE') && !defined('_PS_ADMIN_DIR_'))) { return false; } else { $result = $this->containsProduct($id_product, $id_product_attribute, (int)$id_customization, (int)$id_address_delivery, $id_configurator); if ($result) { if ($operator == 'up') { $sql = 'SELECT stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity FROM '._DB_PREFIX_.'product p '.Product::sqlStock('p', $id_product_attribute, true, $shop).' WHERE p.id_product = '.$id_product; $result2 = Db::getInstance()->getRow($sql); $product_qty = (int)$result2['quantity']; if (Pack::isPack($id_product)) { $product_qty = Pack::getQuantity($id_product, $id_product_attribute); } $new_qty = (int)$result['quantity'] + (int)$quantity; $qty = '+ '.(int)$quantity; if (!Product::isAvailableWhenOutOfStock((int)$result2['out_of_stock'])) { if ($new_qty > $product_qty) { return false; } } } elseif ($operator == 'down') { $qty = '- '.(int)$quantity; $new_qty = (int)$result['quantity'] - (int)$quantity; if ($new_qty < $minimal_quantity && $minimal_quantity > 1) { return -1; } } else { return false; } if ($new_qty <= 0) { return $this->deleteProduct((int)$id_product, (int)$id_product_attribute, (int)$id_customization, 0, $auto_add_cart_rule, $id_configurator); } elseif ($new_qty < $minimal_quantity) { return -1; } else { Db::getInstance()->execute(' UPDATE `'._DB_PREFIX_.'cart_product` SET `quantity` = `quantity` '.$qty.', `date_add` = NOW() WHERE `id_product` = '.(int)$id_product. (!empty($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').' AND `id_cart` = '.(int)$this->id.(Configuration::get('PS_ALLOW_MULTISHIPPING') && $this->isMultiAddressDelivery() ? ' AND `id_address_delivery` = '.(int)$id_address_delivery : '').' AND `id_configurator` = '.(int)$id_configurator.' LIMIT 1' ); } } elseif ($operator == 'up') { $sql = 'SELECT stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity FROM '._DB_PREFIX_.'product p '.Product::sqlStock('p', $id_product_attribute, true, $shop).' WHERE p.id_product = '.$id_product; $result2 = Db::getInstance()->getRow($sql); if (Pack::isPack($id_product)) { $result2['quantity'] = Pack::getQuantity($id_product, $id_product_attribute); } if (!Product::isAvailableWhenOutOfStock((int)$result2['out_of_stock'])) { if ((int)$quantity > $result2['quantity']) { return false; } } if ((int)$quantity < $minimal_quantity) { return -1; } $result_add = Db::getInstance()->insert('cart_product', array( 'id_product' => (int)$id_product, 'id_product_attribute' => (int)$id_product_attribute, 'id_cart' => (int)$this->id, 'id_address_delivery' => (int)$id_address_delivery, 'id_shop' => $shop->id, 'quantity' => (int)$quantity, 'date_add' => date('Y-m-d H:i:s'), 'id_configurator' => (int)$id_configurator )); if (!$result_add) { return false; } } } $this->_products = $this->getProducts(true); $this->update(); $context = Context::getContext()->cloneContext(); $context->cart = $this; Cache::clean('getContextualValue_*'); if ($auto_add_cart_rule) { CartRule::autoAddToCart($context); } if ($product->customizable) { return $this->_updateCustomizationQuantity((int)$quantity, (int)$id_customization, (int)$id_product, (int)$id_product_attribute, (int)$id_address_delivery, $operator); } else { return true; } } /* * module: antadisconfigurator * date: 2017-06-27 12:10:05 * version: 0.1 */ public function getProducts($refresh = false, $id_product = false, $id_country = null) { if (!$this->id) { return array(); } if ($this->_products !== null && !$refresh) { if (is_int($id_product)) { foreach ($this->_products as $product) { if ($product['id_product'] == $id_product) { return array($product); } } return array(); } return $this->_products; } $sql = new DbQuery(); $sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, cp.id_configurator, pl.`name`, p.`is_virtual`, pl.`description_short`, pl.`available_now`, pl.`available_later`, product_shop.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`, product_shop.`available_for_order`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`, stock.`quantity` AS quantity_available, p.`width`, p.`height`, p.`depth`, stock.`out_of_stock`, p.`weight`, p.`date_add`, p.`date_upd`, IFNULL(stock.quantity, 0) as quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category, CONCAT(LPAD(cp.`id_product`, 10, 0), LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0), IFNULL(cp.`id_address_delivery`, 0)) AS unique_id, cp.id_address_delivery, product_shop.advanced_stock_management, ps.product_supplier_reference supplier_reference'); $sql->from('cart_product', 'cp'); $sql->leftJoin('product', 'p', 'p.`id_product` = cp.`id_product`'); $sql->innerJoin('product_shop', 'product_shop', '(product_shop.`id_shop` = cp.`id_shop` AND product_shop.`id_product` = p.`id_product`)'); $sql->leftJoin('product_lang', 'pl', ' p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$this->id_lang.Shop::addSqlRestrictionOnLang('pl', 'cp.id_shop') ); $sql->leftJoin('category_lang', 'cl', ' product_shop.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$this->id_lang.Shop::addSqlRestrictionOnLang('cl', 'cp.id_shop') ); $sql->leftJoin('product_supplier', 'ps', 'ps.`id_product` = cp.`id_product` AND ps.`id_product_attribute` = cp.`id_product_attribute` AND ps.`id_supplier` = p.`id_supplier`'); $sql->join(Product::sqlStock('cp', 'cp')); $sql->where('cp.`id_cart` = '.(int)$this->id); if ($id_product) { $sql->where('cp.`id_product` = '.(int)$id_product); } $sql->where('p.`id_product` IS NOT NULL'); $sql->orderBy('cp.`date_add`, cp.`id_product`, cp.`id_product_attribute` ASC'); if (Customization::isFeatureActive()) { $sql->select('cu.`id_customization`, cu.`quantity` AS customization_quantity'); $sql->leftJoin('customization', 'cu', 'p.`id_product` = cu.`id_product` AND cp.`id_product_attribute` = cu.`id_product_attribute` AND cu.`id_cart` = '.(int)$this->id); $sql->groupBy('cp.`id_product_attribute`, cp.`id_product`, cp.`id_shop`'); } else { $sql->select('NULL AS customization_quantity, NULL AS id_customization'); } if (Combination::isFeatureActive()) { $sql->select(' product_attribute_shop.`price` AS price_attribute, product_attribute_shop.`ecotax` AS ecotax_attr, IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference, (p.`weight`+ pa.`weight`) weight_attribute, IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13, IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc, IFNULL(product_attribute_shop.`minimal_quantity`, product_shop.`minimal_quantity`) as minimal_quantity, IF(product_attribute_shop.wholesale_price > 0, product_attribute_shop.wholesale_price, product_shop.`wholesale_price`) wholesale_price '); $sql->leftJoin('product_attribute', 'pa', 'pa.`id_product_attribute` = cp.`id_product_attribute`'); $sql->leftJoin('product_attribute_shop', 'product_attribute_shop', '(product_attribute_shop.`id_shop` = cp.`id_shop` AND product_attribute_shop.`id_product_attribute` = pa.`id_product_attribute`)'); } else { $sql->select( 'p.`reference` AS reference, p.`ean13`, p.`upc` AS upc, product_shop.`minimal_quantity` AS minimal_quantity, product_shop.`wholesale_price` wholesale_price' ); } $sql->select('image_shop.`id_image` id_image, il.`legend`'); $sql->leftJoin('image_shop', 'image_shop', 'image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$this->id_shop); $sql->leftJoin('image_lang', 'il', 'il.`id_image` = image_shop.`id_image` AND il.`id_lang` = '.(int)$this->id_lang); $result = Db::getInstance()->executeS($sql); $products_ids = array(); $pa_ids = array(); if ($result) { foreach ($result as $key => $row) { $products_ids[] = $row['id_product']; $pa_ids[] = $row['id_product_attribute']; $specific_price = SpecificPrice::getSpecificPrice($row['id_product'], $this->id_shop, $this->id_currency, $id_country, $this->id_shop_group, $row['cart_quantity'], $row['id_product_attribute'], $this->id_customer, $this->id); if ($specific_price) { $reduction_type_row = array('reduction_type' => $specific_price['reduction_type']); } else { $reduction_type_row = array('reduction_type' => 0); } $result[$key] = array_merge($row, $reduction_type_row); } } Product::cacheProductsFeatures($products_ids); Cart::cacheSomeAttributesLists($pa_ids, $this->id_lang); $this->_products = array(); if (empty($result)) { return array(); } $ecotax_rate = (float)Tax::getProductEcotaxRate($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); $apply_eco_tax = Product::$_taxCalculationMethod == PS_TAX_INC && (int)Configuration::get('PS_TAX'); $cart_shop_context = Context::getContext()->cloneContext(); foreach ($result as &$row) { if (isset($row['id_configurator']) && $row['id_configurator'] > 0) { $row['configurator_opt'] = ConfiguratorStorage::getOptProductFlatten($row['id_configurator']); } if (isset($row['ecotax_attr']) && $row['ecotax_attr'] > 0) { $row['ecotax'] = (float)$row['ecotax_attr']; } $row['stock_quantity'] = (int)$row['quantity']; $row['quantity'] = (int)$row['cart_quantity']; if (isset($row['id_product_attribute']) && (int)$row['id_product_attribute'] && isset($row['weight_attribute'])) { $row['weight'] = (float)$row['weight_attribute']; } if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice') { $address_id = (int)$this->id_address_invoice; } else { $address_id = (int)$row['id_address_delivery']; } if (!Address::addressExists($address_id)) { $address_id = null; } if ($cart_shop_context->shop->id != $row['id_shop']) { $cart_shop_context->shop = new Shop((int)$row['id_shop']); } $address = Address::initialize($address_id, true); $id_tax_rules_group = Product::getIdTaxRulesGroupByIdProduct((int)$row['id_product'], $cart_shop_context); $tax_calculator = TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator(); $row['price_without_reduction'] = Product::getPriceStatic( (int)$row['id_product'], true, isset($row['id_product_attribute']) ? (int)$row['id_product_attribute'] : null, 6, null, false, false, $row['cart_quantity'], false, (int)$this->id_customer ? (int)$this->id_customer : null, (int)$this->id, $address_id, $specific_price_output, true, true, $cart_shop_context, true, $row['id_configurator'] ); $row['price_with_reduction'] = Product::getPriceStatic( (int)$row['id_product'], true, isset($row['id_product_attribute']) ? (int)$row['id_product_attribute'] : null, 6, null, false, true, $row['cart_quantity'], false, (int)$this->id_customer ? (int)$this->id_customer : null, (int)$this->id, $address_id, $specific_price_output, true, true, $cart_shop_context, true, $row['id_configurator'] ); $row['price'] = $row['price_with_reduction_without_tax'] = Product::getPriceStatic( (int)$row['id_product'], false, isset($row['id_product_attribute']) ? (int)$row['id_product_attribute'] : null, 6, null, false, true, $row['cart_quantity'], false, (int)$this->id_customer ? (int)$this->id_customer : null, (int)$this->id, $address_id, $specific_price_output, true, true, $cart_shop_context, true, $row['id_configurator'] ); switch (Configuration::get('PS_ROUND_TYPE')) { case Order::ROUND_TOTAL: $row['total'] = $row['price_with_reduction_without_tax'] * (int)$row['cart_quantity']; $row['total_wt'] = $row['price_with_reduction'] * (int)$row['cart_quantity']; break; case Order::ROUND_LINE: $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'] * (int)$row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_); $row['total_wt'] = Tools::ps_round($row['price_with_reduction'] * (int)$row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_); break; case Order::ROUND_ITEM: default: $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'], _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity']; $row['total_wt'] = Tools::ps_round($row['price_with_reduction'], _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity']; break; } $row['price_wt'] = $row['price_with_reduction']; $row['description_short'] = Tools::nl2br($row['description_short']); if ($row['id_product_attribute']) { $row2 = Image::getBestImageAttribute($row['id_shop'], $this->id_lang, $row['id_product'], $row['id_product_attribute']); if ($row2) { $row = array_merge($row, $row2); } } $row['reduction_applies'] = ($specific_price_output && (float)$specific_price_output['reduction']); $row['quantity_discount_applies'] = ($specific_price_output && $row['cart_quantity'] >= (int)$specific_price_output['from_quantity']); $row['id_image'] = Product::defineProductImage($row, $this->id_lang); $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']); $row['features'] = Product::getFeaturesStatic((int)$row['id_product']); if (array_key_exists($row['id_product_attribute'].'-'.$this->id_lang, self::$_attributesLists)) { $row = array_merge($row, self::$_attributesLists[$row['id_product_attribute'].'-'.$this->id_lang]); } $row = Product::getTaxesInformations($row, $cart_shop_context); $this->_products[] = $row; } return $this->_products; } /* * module: antadisconfigurator * date: 2017-06-27 12:10:05 * version: 0.1 */ public function deleteProduct($id_product, $id_product_attribute = null, $id_customization = null, $id_address_delivery = 0, $auto_add_cart_rule = true, $id_configurator = null) { if (isset(self::$_nbProducts[$this->id])) { unset(self::$_nbProducts[$this->id]); } if (isset(self::$_totalWeight[$this->id])) { unset(self::$_totalWeight[$this->id]); } if ((int)$id_customization) { $product_total_quantity = (int)Db::getInstance()->getValue( 'SELECT `quantity` FROM `'._DB_PREFIX_.'cart_product` WHERE `id_product` = '.(int)$id_product.' AND `id_cart` = '.(int)$this->id.' AND `id_product_attribute` = '.(int)$id_product_attribute); $customization_quantity = (int)Db::getInstance()->getValue(' SELECT `quantity` FROM `'._DB_PREFIX_.'customization` WHERE `id_cart` = '.(int)$this->id.' AND `id_product` = '.(int)$id_product.' AND `id_product_attribute` = '.(int)$id_product_attribute.' '.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : '')); if (!$this->_deleteCustomization((int)$id_customization, (int)$id_product, (int)$id_product_attribute, (int)$id_address_delivery)) { return false; } $this->_products = $this->getProducts(true); return ($customization_quantity == $product_total_quantity && $this->deleteProduct((int)$id_product, (int)$id_product_attribute, null, (int)$id_address_delivery, true, $id_configurator)); } $result = Db::getInstance()->getRow(' SELECT SUM(`quantity`) AS \'quantity\' FROM `'._DB_PREFIX_.'customization` WHERE `id_cart` = '.(int)$this->id.' AND `id_product` = '.(int)$id_product.' AND `id_product_attribute` = '.(int)$id_product_attribute); if ($result === false) { return false; } if (Db::getInstance()->NumRows() && (int)$result['quantity']) { return Db::getInstance()->execute(' UPDATE `'._DB_PREFIX_.'cart_product` SET `quantity` = '.(int)$result['quantity'].' WHERE `id_cart` = '.(int)$this->id.' AND `id_product` = '.(int)$id_product. ($id_configurator != null ? ' AND `id_configurator` = '.(int)$id_configurator : ''). ($id_product_attribute != null ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '') ); } $result = Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'cart_product` WHERE `id_product` = '.(int)$id_product. ($id_configurator != null ? ' AND `id_configurator` = '.(int)$id_configurator : '').' '.(!is_null($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').' AND `id_cart` = '.(int)$this->id.' '.((int)$id_address_delivery ? 'AND `id_address_delivery` = '.(int)$id_address_delivery : '')); if ($result) { $return = $this->update(); $this->_products = $this->getProducts(true); CartRule::autoRemoveFromCart(); if ($auto_add_cart_rule) { CartRule::autoAddToCart(); } return $return; } return false; } /* * module: antadisconfigurator * date: 2017-06-27 12:10:05 * version: 0.1 */ public function containsProduct($id_product, $id_product_attribute = 0, $id_customization = 0, $id_address_delivery = 0, $id_configurator = null) { $sql = 'SELECT cp.`quantity` FROM `'._DB_PREFIX_.'cart_product` cp'; if ($id_customization) { $sql .= ' LEFT JOIN `'._DB_PREFIX_.'customization` c ON ( c.`id_product` = cp.`id_product` AND c.`id_product_attribute` = cp.`id_product_attribute` )'; } $sql .= ' WHERE cp.`id_product` = '.(int)$id_product.' AND cp.`id_product_attribute` = '.(int)$id_product_attribute.' AND cp.`id_cart` = '.(int)$this->id; if (Configuration::get('PS_ALLOW_MULTISHIPPING') && $this->isMultiAddressDelivery()) { $sql .= ' AND cp.`id_address_delivery` = '.(int)$id_address_delivery; } if ($id_customization) { $sql .= ' AND c.`id_customization` = '.(int)$id_customization; } if ($id_configurator !== null) { $sql .= ' AND cp.`id_configurator` = '.(int)$id_configurator; } return Db::getInstance()->getRow($sql); } /* * module: antadisconfigurator * date: 2017-06-27 12:10:05 * version: 0.1 */ public function getSummaryDetails($id_lang = null, $refresh = false) { $context = Context::getContext(); if (!$id_lang) { $id_lang = $context->language->id; } $delivery = new Address((int)$this->id_address_delivery); $invoice = new Address((int)$this->id_address_invoice); $formatted_addresses = array( 'delivery' => AddressFormat::getFormattedLayoutData($delivery), 'invoice' => AddressFormat::getFormattedLayoutData($invoice) ); $base_total_tax_inc = $this->getOrderTotal(true); $base_total_tax_exc = $this->getOrderTotal(false); $total_tax = $base_total_tax_inc - $base_total_tax_exc; if ($total_tax < 0) { $total_tax = 0; } $currency = new Currency($this->id_currency); $products = $this->getProducts($refresh); foreach ($products as $key => &$product) { $null = null; $product['price_without_quantity_discount'] = Product::getPriceStatic( $product['id_product'], !Product::getTaxCalculationMethod(), $product['id_product_attribute'], 6, null, false, false, 1, //quantity false, //force_associated_tax null, //id_customer $this->id,//id_cart null, //id_address $null, //specific_price_output true, //with_ecotax true, //use_group_reduction null, //context true, //use_customer_price $product['id_configurator'] //configurator id ); if ($product['reduction_type'] == 'amount') { $reduction = (!Product::getTaxCalculationMethod() ? (float)$product['price_wt'] : (float)$product['price']) - (float)$product['price_without_quantity_discount']; $product['reduction_formatted'] = Tools::displayPrice($reduction); } } $gift_products = array(); $cart_rules = $this->getCartRules(); $total_shipping = $this->getTotalShippingCost(); $total_shipping_tax_exc = $this->getTotalShippingCost(null, false); $total_products_wt = $this->getOrderTotal(true, Cart::ONLY_PRODUCTS); $total_products = $this->getOrderTotal(false, Cart::ONLY_PRODUCTS); $total_discounts = $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS); $total_discounts_tax_exc = $this->getOrderTotal(false, Cart::ONLY_DISCOUNTS); foreach ($cart_rules as &$cart_rule) { if ($cart_rule['free_shipping'] && (empty($cart_rule['code']) || preg_match('/^'.CartRule::BO_ORDER_CODE_PREFIX.'[0-9]+/', $cart_rule['code']))) { $cart_rule['value_real'] -= $total_shipping; $cart_rule['value_tax_exc'] -= $total_shipping_tax_exc; $cart_rule['value_real'] = Tools::ps_round($cart_rule['value_real'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $cart_rule['value_tax_exc'] = Tools::ps_round($cart_rule['value_tax_exc'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); if ($total_discounts > $cart_rule['value_real']) { $total_discounts -= $total_shipping; } if ($total_discounts_tax_exc > $cart_rule['value_tax_exc']) { $total_discounts_tax_exc -= $total_shipping_tax_exc; } $total_shipping = 0; $total_shipping_tax_exc = 0; } if ($cart_rule['gift_product']) { foreach ($products as $key => &$product) { if (empty($product['gift']) && $product['id_product'] == $cart_rule['gift_product'] && $product['id_product_attribute'] == $cart_rule['gift_product_attribute']) { $total_products_wt = Tools::ps_round($total_products_wt - $product['price_wt'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $total_products = Tools::ps_round($total_products - $product['price'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $total_discounts = Tools::ps_round($total_discounts - $product['price_wt'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $total_discounts_tax_exc = Tools::ps_round($total_discounts_tax_exc - $product['price'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $cart_rule['value_real'] = Tools::ps_round($cart_rule['value_real'] - $product['price_wt'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $cart_rule['value_tax_exc'] = Tools::ps_round($cart_rule['value_tax_exc'] - $product['price'], (int)$context->currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $product['total_wt'] = Tools::ps_round($product['total_wt'] - $product['price_wt'], (int)$currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $product['total'] = Tools::ps_round($product['total'] - $product['price'], (int)$currency->decimals * _PS_PRICE_COMPUTE_PRECISION_); $product['cart_quantity']--; if (!$product['cart_quantity']) { unset($products[$key]); } $gift_product = $product; $gift_product['cart_quantity'] = 1; $gift_product['price'] = 0; $gift_product['price_wt'] = 0; $gift_product['total_wt'] = 0; $gift_product['total'] = 0; $gift_product['gift'] = true; $gift_products[] = $gift_product; break; // One gift product per cart rule } } } } foreach ($cart_rules as $key => &$cart_rule) { if (((float)$cart_rule['value_real'] == 0 && (int)$cart_rule['free_shipping'] == 0)) { unset($cart_rules[$key]); } } $summary = array( 'delivery' => $delivery, 'delivery_state' => State::getNameById($delivery->id_state), 'invoice' => $invoice, 'invoice_state' => State::getNameById($invoice->id_state), 'formattedAddresses' => $formatted_addresses, 'products' => array_values($products), 'gift_products' => $gift_products, 'discounts' => array_values($cart_rules), 'is_virtual_cart' => (int)$this->isVirtualCart(), 'total_discounts' => $total_discounts, 'total_discounts_tax_exc' => $total_discounts_tax_exc, 'total_wrapping' => $this->getOrderTotal(true, Cart::ONLY_WRAPPING), 'total_wrapping_tax_exc' => $this->getOrderTotal(false, Cart::ONLY_WRAPPING), 'total_shipping' => $total_shipping, 'total_shipping_tax_exc' => $total_shipping_tax_exc, 'total_products_wt' => $total_products_wt, 'total_products' => $total_products, 'total_price' => $base_total_tax_inc, 'total_tax' => $total_tax, 'total_price_without_tax' => $base_total_tax_exc, 'is_multi_address_delivery' => $this->isMultiAddressDelivery() || ((int)Tools::getValue('multi-shipping') == 1), 'free_ship' =>!$total_shipping && !count($this->getDeliveryAddressesWithoutCarriers(true, $errors)), 'carrier' => new Carrier($this->id_carrier, $id_lang), ); $hook = Hook::exec('actionCartSummary', $summary, null, true); if (is_array($hook)) { $summary = array_merge($summary, array_shift($hook)); } return $summary; } /** * This function returns the total cart amount * * Possible values for $type: * Cart::ONLY_PRODUCTS * Cart::ONLY_DISCOUNTS * Cart::BOTH * Cart::BOTH_WITHOUT_SHIPPING * Cart::ONLY_SHIPPING * Cart::ONLY_WRAPPING * Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING * Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING * * @param bool $withTaxes With or without taxes * @param int $type Total type * @param bool $use_cache Allow using cache of the method CartRule::getContextualValue * @return float Order total */ /* * module: antadisconfigurator * date: 2017-06-27 12:10:05 * version: 0.1 */ public function getOrderTotal($with_taxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true) { $address_factory = Adapter_ServiceLocator::get('Adapter_AddressFactory'); $price_calculator = Adapter_ServiceLocator::get('Adapter_ProductPriceCalculator'); $configuration = Adapter_ServiceLocator::get('Core_Business_ConfigurationInterface'); $ps_tax_address_type = $configuration->get('PS_TAX_ADDRESS_TYPE'); $ps_use_ecotax = $configuration->get('PS_USE_ECOTAX'); $ps_round_type = $configuration->get('PS_ROUND_TYPE'); $ps_ecotax_tax_rules_group_id = $configuration->get('PS_ECOTAX_TAX_RULES_GROUP_ID'); $compute_precision = $configuration->get('_PS_PRICE_COMPUTE_PRECISION_'); if (!$this->id) { return 0; } $type = (int)$type; $array_type = array( Cart::ONLY_PRODUCTS, Cart::ONLY_DISCOUNTS, Cart::BOTH, Cart::BOTH_WITHOUT_SHIPPING, Cart::ONLY_SHIPPING, Cart::ONLY_WRAPPING, Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, ); $virtual_context = Context::getContext()->cloneContext(); $virtual_context->cart = $this; if (!in_array($type, $array_type)) { die(Tools::displayError()); } $with_shipping = in_array($type, array(Cart::BOTH, Cart::ONLY_SHIPPING)); if ($type == Cart::ONLY_DISCOUNTS && !CartRule::isFeatureActive()) { return 0; } $virtual = $this->isVirtualCart(); if ($virtual && $type == Cart::ONLY_SHIPPING) { return 0; } if ($virtual && $type == Cart::BOTH) { $type = Cart::BOTH_WITHOUT_SHIPPING; } if ($with_shipping || $type == Cart::ONLY_DISCOUNTS) { if (is_null($products) && is_null($id_carrier)) { $shipping_fees = $this->getTotalShippingCost(null, (bool)$with_taxes); } else { $shipping_fees = $this->getPackageShippingCost((int)$id_carrier, (bool)$with_taxes, null, $products); } } else { $shipping_fees = 0; } if ($type == Cart::ONLY_SHIPPING) { return $shipping_fees; } if ($type == Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING) { $type = Cart::ONLY_PRODUCTS; } $param_product = true; if (is_null($products)) { $param_product = false; $products = $this->getProducts(); } if ($type == Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING) { foreach ($products as $key => $product) { if ($product['is_virtual']) { unset($products[$key]); } } $type = Cart::ONLY_PRODUCTS; } $order_total = 0; if (Tax::excludeTaxeOption()) { $with_taxes = false; } $products_total = array(); $ecotax_total = 0; foreach ($products as $product) { if ($virtual_context->shop->id != $product['id_shop']) { $virtual_context->shop = new Shop((int)$product['id_shop']); } if ($ps_tax_address_type == 'id_address_invoice') { $id_address = (int)$this->id_address_invoice; } else { $id_address = (int)$product['id_address_delivery']; } // Get delivery address of the product from the cart if (!$address_factory->addressExists($id_address)) { $id_address = null; } $null = null; $price = $price_calculator->getProductPrice( (int)$product['id_product'], $with_taxes, (int)$product['id_product_attribute'], 6, null, false, true, $product['cart_quantity'], false, (int)$this->id_customer ? (int)$this->id_customer : null, (int)$this->id, $id_address, $null, $ps_use_ecotax, true, $virtual_context, true, $product['id_configurator'] ); $address = $address_factory->findOrCreate($id_address, true); if ($with_taxes) { $id_tax_rules_group = Product::getIdTaxRulesGroupByIdProduct((int)$product['id_product'], $virtual_context); $tax_calculator = TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator(); } else { $id_tax_rules_group = 0; } if (in_array($ps_round_type, array(Order::ROUND_ITEM, Order::ROUND_LINE))) { if (!isset($products_total[$id_tax_rules_group])) { $products_total[$id_tax_rules_group] = 0; } } elseif (!isset($products_total[$id_tax_rules_group.'_'.$id_address])) { $products_total[$id_tax_rules_group.'_'.$id_address] = 0; } // Configurator impact $flatrate = true; $impact = 0; if ($product['id_configurator'] != 0) { $impact = Product::getConfiguratorSelectedPriceTotal($product['id_product'], $product['id_configurator']); } switch ($ps_round_type) { case Order::ROUND_TOTAL: $product_price = $price * (int)$product['cart_quantity']; if ($product['id_configurator'] != 0 && $flatrate == true) { $product_price+= $impact; } $products_total[$id_tax_rules_group.'_'.$id_address] += $product_price; break; case Order::ROUND_LINE: $product_price = $price * $product['cart_quantity']; if ($product['id_configurator'] != 0 && $flatrate == true) { $product_price+= $impact; } $products_total[$id_tax_rules_group] += Tools::ps_round($product_price, $compute_precision); break; case Order::ROUND_ITEM: default: $product_price = $price; $product_price = Tools::ps_round($product_price, $compute_precision) * (int)$product['cart_quantity']; if ($product['id_configurator'] != 0 && $flatrate == true) { $product_price+= $impact; } $products_total[$id_tax_rules_group] += $product_price; break; } } foreach ($products_total as $key => $price) { $order_total += $price; } $order_total_products = $order_total; if ($type == Cart::ONLY_DISCOUNTS) { $order_total = 0; } $wrapping_fees = 0; $include_gift_wrapping = (!$configuration->get('PS_ATCP_SHIPWRAP') || $type !== Cart::ONLY_PRODUCTS); if ($this->gift && $include_gift_wrapping) { $wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), $compute_precision), Currency::getCurrencyInstance((int)$this->id_currency)); } if ($type == Cart::ONLY_WRAPPING) { return $wrapping_fees; } $order_total_discount = 0; $order_shipping_discount = 0; if (!in_array($type, array(Cart::ONLY_SHIPPING, Cart::ONLY_PRODUCTS)) && CartRule::isFeatureActive()) { if ($with_shipping || $type == Cart::ONLY_DISCOUNTS) { $cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL); } else { $cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_REDUCTION); foreach ($this->getCartRules(CartRule::FILTER_ACTION_GIFT) as $tmp_cart_rule) { $flag = false; foreach ($cart_rules as $cart_rule) { if ($tmp_cart_rule['id_cart_rule'] == $cart_rule['id_cart_rule']) { $flag = true; } } if (!$flag) { $cart_rules[] = $tmp_cart_rule; } } } $id_address_delivery = 0; if (isset($products[0])) { $id_address_delivery = (is_null($products) ? $this->id_address_delivery : $products[0]['id_address_delivery']); } $package = array('id_carrier' => $id_carrier, 'id_address' => $id_address_delivery, 'products' => $products); $flag = false; foreach ($cart_rules as $cart_rule) { if (($with_shipping || $type == Cart::ONLY_DISCOUNTS) && $cart_rule['obj']->free_shipping && !$flag) { $order_shipping_discount = (float)Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, ($param_product ? $package : null), $use_cache), $compute_precision); $flag = true; } if ((int)$cart_rule['obj']->gift_product) { $in_order = false; if (is_null($products)) { $in_order = true; } else { foreach ($products as $product) { if ($cart_rule['obj']->gift_product == $product['id_product'] && $cart_rule['obj']->gift_product_attribute == $product['id_product_attribute']) { $in_order = true; } } } if ($in_order) { $order_total_discount += $cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_GIFT, $package, $use_cache); } } if ($cart_rule['obj']->reduction_percent > 0 || $cart_rule['obj']->reduction_amount > 0) { $order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_REDUCTION, $package, $use_cache), $compute_precision); } } $order_total_discount = min(Tools::ps_round($order_total_discount, 2), (float)$order_total_products) + (float)$order_shipping_discount; $order_total -= $order_total_discount; } if ($type == Cart::BOTH) { $order_total += $shipping_fees + $wrapping_fees; } if ($order_total < 0 && $type != Cart::ONLY_DISCOUNTS) { return 0; } if ($type == Cart::ONLY_DISCOUNTS) { return $order_total_discount; } return Tools::ps_round((float)$order_total, $compute_precision); } }