2016-07-07 15:33:38 +02:00

848 lines
28 KiB
PHP

<?php
/*
* 2007-2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2014 PrestaShop SA
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class Cart extends CartCore
{
/**
* @Override Antadis
* Adding Check minimum amount user cart rules to assign if carriers is free
*/
public function getDeliveryOptionList(Country $default_country = null, $flush = false)
{
static $cache = null;
if ($cache !== null && !$flush)
return $cache;
$delivery_option_list = array();
$carriers_price = array();
$carrier_collection = array();
$package_list = $this->getPackageList();
// Foreach addresses
foreach ($package_list as $id_address => $packages)
{
// Initialize vars
$delivery_option_list[$id_address] = array();
$carriers_price[$id_address] = array();
$common_carriers = null;
$best_price_carriers = array();
$best_grade_carriers = array();
$carriers_instance = array();
// Get country
if ($id_address)
{
$address = new Address($id_address);
$country = new Country($address->id_country);
}
else
$country = $default_country;
// Foreach packages, get the carriers with best price, best position and best grade
foreach ($packages as $id_package => $package)
{
// No carriers available
if (count($package['carrier_list']) == 1 && current($package['carrier_list']) == 0)
{
$cache = array();
return $cache;
}
$carriers_price[$id_address][$id_package] = array();
// Get all common carriers for each packages to the same address
if (is_null($common_carriers))
$common_carriers = $package['carrier_list'];
else
$common_carriers = array_intersect($common_carriers, $package['carrier_list']);
$best_price = null;
$best_price_carrier = null;
$best_grade = null;
$best_grade_carrier = null;
// Foreach carriers of the package, calculate his price, check if it the best price, position and grade
foreach ($package['carrier_list'] as $id_carrier)
{
if (!isset($carriers_instance[$id_carrier]))
$carriers_instance[$id_carrier] = new Carrier($id_carrier);
$price_with_tax = $this->getPackageShippingCost($id_carrier, true, $country, $package['product_list']);
$price_without_tax = $this->getPackageShippingCost($id_carrier, false, $country, $package['product_list']);
if (is_null($best_price) || $price_with_tax < $best_price)
{
$best_price = $price_with_tax;
$best_price_carrier = $id_carrier;
}
$carriers_price[$id_address][$id_package][$id_carrier] = array(
'without_tax' => $price_without_tax,
'with_tax' => $price_with_tax);
$grade = $carriers_instance[$id_carrier]->grade;
if (is_null($best_grade) || $grade > $best_grade)
{
$best_grade = $grade;
$best_grade_carrier = $id_carrier;
}
}
$best_price_carriers[$id_package] = $best_price_carrier;
$best_grade_carriers[$id_package] = $best_grade_carrier;
}
// Reset $best_price_carrier, it's now an array
$best_price_carrier = array();
$key = '';
// Get the delivery option with the lower price
foreach ($best_price_carriers as $id_package => $id_carrier)
{
$key .= $id_carrier.',';
if (!isset($best_price_carrier[$id_carrier]))
$best_price_carrier[$id_carrier] = array(
'price_with_tax' => 0,
'price_without_tax' => 0,
'package_list' => array(),
'product_list' => array(),
);
$best_price_carrier[$id_carrier]['price_with_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['with_tax'];
$best_price_carrier[$id_carrier]['price_without_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['without_tax'];
$best_price_carrier[$id_carrier]['package_list'][] = $id_package;
$best_price_carrier[$id_carrier]['product_list'] = array_merge($best_price_carrier[$id_carrier]['product_list'], $packages[$id_package]['product_list']);
$best_price_carrier[$id_carrier]['instance'] = $carriers_instance[$id_carrier];
}
// Add the delivery option with best price as best price
$delivery_option_list[$id_address][$key] = array(
'carrier_list' => $best_price_carrier,
'is_best_price' => true,
'is_best_grade' => false,
'unique_carrier' => (count($best_price_carrier) <= 1)
);
// Reset $best_grade_carrier, it's now an array
$best_grade_carrier = array();
$key = '';
// Get the delivery option with the best grade
foreach ($best_grade_carriers as $id_package => $id_carrier)
{
$key .= $id_carrier.',';
if (!isset($best_grade_carrier[$id_carrier]))
$best_grade_carrier[$id_carrier] = array(
'price_with_tax' => 0,
'price_without_tax' => 0,
'package_list' => array(),
'product_list' => array(),
);
$best_grade_carrier[$id_carrier]['price_with_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['with_tax'];
$best_grade_carrier[$id_carrier]['price_without_tax'] += $carriers_price[$id_address][$id_package][$id_carrier]['without_tax'];
$best_grade_carrier[$id_carrier]['package_list'][] = $id_package;
$best_grade_carrier[$id_carrier]['product_list'] = array_merge($best_grade_carrier[$id_carrier]['product_list'], $packages[$id_package]['product_list']);
$best_grade_carrier[$id_carrier]['instance'] = $carriers_instance[$id_carrier];
}
// Add the delivery option with best grade as best grade
if (!isset($delivery_option_list[$id_address][$key]))
$delivery_option_list[$id_address][$key] = array(
'carrier_list' => $best_grade_carrier,
'is_best_price' => false,
'unique_carrier' => (count($best_grade_carrier) <= 1)
);
$delivery_option_list[$id_address][$key]['is_best_grade'] = true;
// Get all delivery options with a unique carrier
foreach ($common_carriers as $id_carrier)
{
$key = '';
$package_list = array();
$product_list = array();
$price_with_tax = 0;
$price_without_tax = 0;
foreach ($packages as $id_package => $package)
{
$key .= $id_carrier.',';
$price_with_tax += $carriers_price[$id_address][$id_package][$id_carrier]['with_tax'];
$price_without_tax += $carriers_price[$id_address][$id_package][$id_carrier]['without_tax'];
$package_list[] = $id_package;
$product_list = array_merge($product_list, $package['product_list']);
}
if (!isset($delivery_option_list[$id_address][$key]))
$delivery_option_list[$id_address][$key] = array(
'is_best_price' => false,
'is_best_grade' => false,
'unique_carrier' => true,
'carrier_list' => array(
$id_carrier => array(
'price_with_tax' => $price_with_tax,
'price_without_tax' => $price_without_tax,
'instance' => $carriers_instance[$id_carrier],
'package_list' => $package_list,
'product_list' => $product_list,
)
)
);
else
$delivery_option_list[$id_address][$key]['unique_carrier'] = (count($delivery_option_list[$id_address][$key]['carrier_list']) <= 1);
}
}
$cart_rules = CartRule::getCustomerCartRules(Context::getContext()->cookie->id_lang, Context::getContext()->cookie->id_customer, true, true, false, $this);
/**
* @Override Antadis
* Adding Check minimum amount user cart rules to assign if carriers is free
*/
$totalWithoutShipping = floatval($this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING));
$free_carriers_rules = array();
foreach ($cart_rules as $cart_rule)
{
if ($cart_rule['free_shipping'] && $cart_rule['carrier_restriction'] && $totalWithoutShipping >= $cart_rule['minimum_amount'])
{
$cr = new CartRule((int)$cart_rule['id_cart_rule']);
if (Validate::isLoadedObject($cr))
{
$carriers = $cr->getAssociatedRestrictions('carrier', true, false);
if (is_array($carriers) && count($carriers) && isset($carriers['selected']))
foreach($carriers['selected'] as $carrier)
if (isset($carrier['id_carrier']) && $carrier['id_carrier'])
$free_carriers_rules[] = (int)$carrier['id_carrier'];
}
}
}
/**
* @End Override Antadis
*/
// For each delivery options :
// - Set the carrier list
// - Calculate the price
// - Calculate the average position
foreach ($delivery_option_list as $id_address => $delivery_option)
foreach ($delivery_option as $key => $value)
{
$total_price_with_tax = 0;
$total_price_without_tax = 0;
$position = 0;
foreach ($value['carrier_list'] as $id_carrier => $data)
{
$total_price_with_tax += $data['price_with_tax'];
$total_price_without_tax += $data['price_without_tax'];
$total_price_without_tax_with_rules = (in_array($id_carrier, $free_carriers_rules)) ? 0 : $total_price_without_tax ;
if (!isset($carrier_collection[$id_carrier]))
$carrier_collection[$id_carrier] = new Carrier($id_carrier);
$delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['instance'] = $carrier_collection[$id_carrier];
if (file_exists(_PS_SHIP_IMG_DIR_.$id_carrier.'.jpg'))
$delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['logo'] = _THEME_SHIP_DIR_.$id_carrier.'.jpg';
else
$delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['logo'] = false;
$position += $carrier_collection[$id_carrier]->position;
}
$delivery_option_list[$id_address][$key]['total_price_with_tax'] = $total_price_with_tax;
$delivery_option_list[$id_address][$key]['total_price_without_tax'] = $total_price_without_tax;
$delivery_option_list[$id_address][$key]['is_free'] = !$total_price_without_tax_with_rules ? true : false;
$delivery_option_list[$id_address][$key]['position'] = $position / count($value['carrier_list']);
}
// Sort delivery option list
foreach ($delivery_option_list as &$array)
uasort ($array, array('Cart', 'sortDeliveryOptionList'));
//echo "<pre>";var_dump($delivery_option_list);echo "</pre>";die();
$cache = $delivery_option_list;
return $delivery_option_list;
}
/**
* override to avoid without taxes trouble
*/
public function getOrderTotal($with_taxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true)
{
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,
);
// Define virtual context to prevent case where the cart is not the in the global context
$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 cart rules are not used
if ($type == Cart::ONLY_DISCOUNTS && !CartRule::isFeatureActive())
return 0;
// no shipping cost if is a cart with only virtuals products
$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, (boolean)$with_taxes);
else
$shipping_fees = $this->getPackageShippingCost($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;
foreach ($products as $product) // products refer to the cart details
{
if ($virtual_context->shop->id != $product['id_shop'])
$virtual_context->shop = new Shop((int)$product['id_shop']);
if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice')
$address_id = (int)$this->id_address_invoice;
else
$address_id = (int)$product['id_address_delivery']; // Get delivery address of the product from the cart
if (!Address::addressExists($address_id))
$address_id = null;
/**
* @Override
*
* Do not use this method with tax calculation
* Computing taxes after adding product quantities result in a price difference due to rounding.
*
* Always use TAX_INC calculation methode to do taxe calculation before adding products quantities.
*/
if ($this->_taxCalculationMethod == PS_TAX_EXC && !$with_taxes)
{
// Here taxes are computed only once the quantity has been applied to the product price
$price = Product::getPriceStatic(
(int)$product['id_product'],
false,
(int)$product['id_product_attribute'],
2,
null,
false,
true,
$product['cart_quantity'],
false,
(int)$this->id_customer ? (int)$this->id_customer : null,
(int)$this->id,
$address_id,
$null,
true,
true,
$virtual_context
);
$total_ecotax = $product['ecotax'] * (int)$product['cart_quantity'];
$total_price = $price * (int)$product['cart_quantity'];
// if ($with_taxes)
// {
// $product_tax_rate = (float)Tax::getProductTaxRate((int)$product['id_product'], (int)$address_id, $virtual_context);
// $product_eco_tax_rate = Tax::getProductEcotaxRate((int)$address_id);
// $total_price = ($total_price - $total_ecotax) * (1 + $product_tax_rate / 100);
// $total_ecotax = $total_ecotax * (1 + $product_eco_tax_rate / 100);
// $total_price = Tools::ps_round($total_price + $total_ecotax, 2);
// }
}
else
{
if ($with_taxes)
$price = Product::getPriceStatic(
(int)$product['id_product'],
true,
(int)$product['id_product_attribute'],
2,
null,
false,
true,
$product['cart_quantity'],
false,
((int)$this->id_customer ? (int)$this->id_customer : null),
(int)$this->id,
((int)$address_id ? (int)$address_id : null),
$null,
true,
true,
$virtual_context
);
else
$price = Product::getPriceStatic(
(int)$product['id_product'],
false,
(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,
((int)$address_id ? (int)$address_id : null),
$null,
true,
true,
$virtual_context
);
$total_price = Tools::ps_round($price * (int)$product['cart_quantity'], 2);
}
$order_total += $total_price;
}
$order_total_products = $order_total;
if ($type == Cart::ONLY_DISCOUNTS)
$order_total = 0;
// Wrapping Fees
$wrapping_fees = 0;
if ($this->gift)
$wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), 2), Currency::getCurrencyInstance((int)$this->id_currency));
if ($type == Cart::ONLY_WRAPPING)
return $wrapping_fees;
$order_total_discount = 0;
if (!in_array($type, array(Cart::ONLY_SHIPPING, Cart::ONLY_PRODUCTS)) && CartRule::isFeatureActive())
{
// First, retrieve the cart rules associated to this "getOrderTotal"
if ($with_shipping || $type == Cart::ONLY_DISCOUNTS)
$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL);
else
{
$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_REDUCTION);
// Cart Rules array are merged manually in order to avoid doubles
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);
// Then, calculate the contextual value for each one
foreach ($cart_rules as $cart_rule)
{
// If the cart rule offers free shipping, add the shipping cost
if (($with_shipping || $type == Cart::ONLY_DISCOUNTS) && $cart_rule['obj']->free_shipping)
$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, ($param_product ? $package : null), $use_cache), 2);
// If the cart rule is a free gift, then add the free gift value only if the gift is in this package
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 the cart rule offers a reduction, the amount is prorated (with the products in the package)
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), 2);
}
$order_total_discount = min(Tools::ps_round($order_total_discount, 2), $wrapping_fees + $order_total_products + $shipping_fees);
$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, 2);
}
/**
* override to avoid without taxes trouble
*/
public function getOrderTotalReturnBank($with_taxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true)
{
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,
);
// Define virtual context to prevent case where the cart is not the in the global context
$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 cart rules are not used
if ($type == Cart::ONLY_DISCOUNTS && !CartRule::isFeatureActive())
return 0;
// no shipping cost if is a cart with only virtuals products
$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, (boolean)$with_taxes);
else
$shipping_fees = $this->getPackageShippingCost($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;
foreach ($products as $product) // products refer to the cart details
{
if ($virtual_context->shop->id != $product['id_shop'])
$virtual_context->shop = new Shop((int)$product['id_shop']);
if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice')
$address_id = (int)$this->id_address_invoice;
else
$address_id = (int)$product['id_address_delivery']; // Get delivery address of the product from the cart
if (!Address::addressExists($address_id))
$address_id = null;
if ($this->_taxCalculationMethod == PS_TAX_EXC)
{
//error_log("BANK PS_TAX_EXC",1,"thomas@antadis.com");
// Here taxes are computed only once the quantity has been applied to the product price
$price = Product::getPriceStatic(
(int)$product['id_product'],
true,
(int)$product['id_product_attribute'],
2,
null,
false,
true,
$product['cart_quantity'],
false,
(int)$this->id_customer ? (int)$this->id_customer : null,
(int)$this->id,
$address_id,
$null,
true,
true,
$virtual_context
);
$total_ecotax = $product['ecotax'] * (int)$product['cart_quantity'];
$total_price = $price * (int)$product['cart_quantity'];
if ($with_taxes)
{
$product_tax_rate = (float)Tax::getProductTaxRate((int)$product['id_product'], (int)$address_id, $virtual_context);
$product_eco_tax_rate = Tax::getProductEcotaxRate((int)$address_id);
$total_price = ($total_price - $total_ecotax) * (1 + $product_tax_rate / 100);
$total_ecotax = $total_ecotax * (1 + $product_eco_tax_rate / 100);
$total_price = Tools::ps_round($total_price + $total_ecotax, 2);
}
}
else
{
//error_log("BANK PS_TAX_INC",1,"thomas@antadis.com");
$price = Product::getPriceStatic(
(int)$product['id_product'],
true,
(int)$product['id_product_attribute'],
2,
null,
false,
true,
$product['cart_quantity'],
false,
((int)$this->id_customer ? (int)$this->id_customer : null),
(int)$this->id,
((int)$address_id ? (int)$address_id : null),
$null,
true,
true,
$virtual_context
);
$total_price = Tools::ps_round($price * (int)$product['cart_quantity'], 2);
}
$order_total += $total_price;
}
$order_total_products = $order_total;
if ($type == Cart::ONLY_DISCOUNTS)
$order_total = 0;
// Wrapping Fees
$wrapping_fees = 0;
if ($this->gift)
$wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), 2), Currency::getCurrencyInstance((int)$this->id_currency));
if ($type == Cart::ONLY_WRAPPING)
return $wrapping_fees;
$order_total_discount = 0;
if (!in_array($type, array(Cart::ONLY_SHIPPING, Cart::ONLY_PRODUCTS)) && CartRule::isFeatureActive())
{
// First, retrieve the cart rules associated to this "getOrderTotal"
if ($with_shipping || $type == Cart::ONLY_DISCOUNTS)
$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL);
else
{
$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_REDUCTION);
// Cart Rules array are merged manually in order to avoid doubles
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);
// Then, calculate the contextual value for each one
foreach ($cart_rules as $cart_rule)
{
// If the cart rule offers free shipping, add the shipping cost
if (($with_shipping || $type == Cart::ONLY_DISCOUNTS) && $cart_rule['obj']->free_shipping)
$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, ($param_product ? $package : null), $use_cache), 2);
// If the cart rule is a free gift, then add the free gift value only if the gift is in this package
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 the cart rule offers a reduction, the amount is prorated (with the products in the package)
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), 2);
}
$order_total_discount = min(Tools::ps_round($order_total_discount, 2), $wrapping_fees + $order_total_products + $shipping_fees);
$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, 2);
}
/**
* @Adding
* @return false OR product if oosp/not available...
*/
public function checkQuantitiesMore()
{
if (Configuration::get('PS_CATALOG_MODE')) {
return false;
}
foreach ($this->getProducts() as $product) {
if (!$product['active'] || !$product['available_for_order']
|| (!$product['allow_oosp'] && $product['stock_quantity'] < $product['cart_quantity']))
{
return $product;
}
}
return false;
}
/**
* @Adding
* @return false OR $title if there's another delay
*/
public function checkProductOtherDeliveryDelai()
{
if (Configuration::get('PS_CATALOG_MODE')) {
return false;
}
$otherdelay = array();
$title = '';
$count = 0;
foreach ($this->getProducts() as $product) {
$sale = SaleCore::getSaleByIdProduct($product['id_product']);
if ($sale) {
if ($sale->otherdelay){
$otherdelay[$sale->id_privatesales] = $sale->otherdelay_title[1];
$title = $sale->otherdelay_title[1];
}
}
$count++;
}
//echo "<pre>";var_dump($otherdelay,$count,$title);echo "</pre>";die();
if ($count != count($otherdelay) && !empty($title)) {
return $title;
}
return false;
}
/**
* @Adding
* @return false OR true if cartrule already in cart
*/
public function isCartRuleAlreadyIn($id_cart_rule)
{
if (Configuration::get('PS_CATALOG_MODE')) {
return false;
}
$result = $this->getCartRules();
foreach ($result as $cartRule) {
if ((int)$cartRule['obj']->id == (int)$id_cart_rule) {
return true;
}
}
return false;
}
}