2017-08-04 12:38:59 +02:00

1014 lines
45 KiB
PHP

<?php
class Cart extends CartCore
{
/*
* module: antadisconfigurator
* date: 2017-06-27 12:10:05
* version: 0.1
*/
public function updateQty($quantity, $id_product, $id_product_attribute = null, $id_customization = false,
$operator = 'up', $id_address_delivery = 0, Shop $shop = null, $auto_add_cart_rule = true, $id_configurator = null)
{
if (!$shop) {
$shop = Context::getContext()->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;
}
switch ($ps_round_type) {
case Order::ROUND_TOTAL:
$products_total[$id_tax_rules_group.'_'.$id_address] += $price * (int)$product['cart_quantity'];
break;
case Order::ROUND_LINE:
$product_price = $price * $product['cart_quantity'];
$products_total[$id_tax_rules_group] += Tools::ps_round($product_price, $compute_precision);
break;
case Order::ROUND_ITEM:
default:
$product_price = $price;
$products_total[$id_tax_rules_group] += Tools::ps_round($product_price, $compute_precision) * (int)$product['cart_quantity'];
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);
}
}