[-] FO : added the concept of product package (multi-shipping) for the cart rules in getContextualValue()

This commit is contained in:
dMetzger
2012-05-21 14:19:54 +00:00
parent 67832fbcef
commit aaf437a3e0
3 changed files with 43 additions and 23 deletions
+6 -2
View File
@@ -1459,7 +1459,7 @@ class CartCore extends ObjectModel
$in_order = true;
else
foreach ($products as $products)
if ($cart_rule['obj']->gift_product == $product['id_product'] && ($cart_rule['obj']->gift_product_attribute == 0 || $cart_rule['obj']->gift_product_attribute = $product['id_product_attribute']))
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)
@@ -1468,7 +1468,11 @@ class CartCore extends ObjectModel
// 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, $products), 2);
{
$id_address_delivery = (is_null($products) ? $this->id_address_delivery : $products[0]['id_address_delivery']);
$package = array('id_address' => $id_address_delivery, 'products' => $products);
$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_REDUCTION, $package), 2);
}
}
$order_total_discount = min(Tools::ps_round($order_total_discount, 2), $wrapping_fees + $order_total_products + $shipping_fees);
+34 -19
View File
@@ -27,10 +27,14 @@
class CartRuleCore extends ObjectModel
{
/* Filters used when retrieving the cart rules applied to a cart of when calculating the value of a reduction */
const FILTER_ACTION_ALL = 1;
const FILTER_ACTION_SHIPPING = 2;
const FILTER_ACTION_REDUCTION = 3;
const FILTER_ACTION_GIFT = 4;
/* This variable controls that a free gift is offered only once, even when multi-shippping is activated and the same product is delivered in both addresses */
protected static $only_one_gift = array();
public $id;
public $name;
@@ -356,7 +360,6 @@ class CartRuleCore extends ObjectModel
return $productRules;
}
// Todo : Add shop management
/**
* Check if this cart rule can be applied
*
@@ -699,7 +702,7 @@ class CartRuleCore extends ObjectModel
* @param Context $context
* @return float|int|string
*/
public function getContextualValue($useTax, Context $context = null, $filter = null, $products = null)
public function getContextualValue($useTax, Context $context = null, $filter = null, $package = null)
{
if (!CartRule::isFeatureActive())
return 0;
@@ -707,6 +710,9 @@ class CartRuleCore extends ObjectModel
$context = Context::getContext();
if (!$filter)
$filter = CartRule::FILTER_ACTION_ALL;
$all_products = $context->cart->getProducts();
$package_products = (is_null($package) ? $all_products : $package['products']);
$reduction_value = 0;
@@ -735,9 +741,9 @@ class CartRuleCore extends ObjectModel
if ($this->reduction_percent && $this->reduction_product == 0)
{
// Do not give a reduction on free products!
$order_total = $context->cart->getOrderTotal($useTax, Cart::ONLY_PRODUCTS, $products);
$order_total = $context->cart->getOrderTotal($useTax, Cart::ONLY_PRODUCTS, $package_products);
foreach ($context->cart->getCartRules(CartRule::FILTER_ACTION_GIFT) as $cart_rule)
$order_total -= Tools::ps_round($cart_rule['obj']->getContextualValue($useTax, $context, CartRule::FILTER_ACTION_GIFT, $products), 2);
$order_total -= Tools::ps_round($cart_rule['obj']->getContextualValue($useTax, $context, CartRule::FILTER_ACTION_GIFT, $package_products), 2);
$reduction_value += $order_total * $this->reduction_percent / 100;
}
@@ -745,8 +751,7 @@ class CartRuleCore extends ObjectModel
// Discount (%) on a specific product
if ($this->reduction_percent && $this->reduction_product > 0)
{
$products2 = (is_null($products) ? $context->cart->getProducts() : $products);
foreach ($products2 as $product)
foreach ($package_products as $product)
if ($product['id_product'] == $this->reduction_product)
$reduction_value += ($useTax ? $product['total_wt'] : $product['total']) * $this->reduction_percent / 100;
}
@@ -756,8 +761,7 @@ class CartRuleCore extends ObjectModel
{
$minPrice = false;
$cheapest_product = null;
$products2 = $context->cart->getProducts();
foreach ($products2 as $product)
foreach ($all_products as $product)
{
$price = ($useTax ? $product['price_wt'] : $product['price']);
if ($price > 0 && ($minPrice === false || $minPrice > $price))
@@ -769,7 +773,7 @@ class CartRuleCore extends ObjectModel
// Check if the cheapest product is in the package
$in_package = false;
foreach ($products as $product)
foreach ($package_products as $product)
if ($product['id_product'].'-'.$product['id_product_attribute'] == $cheapest_product || $product['id_product'].'-0' == $cheapest_product)
$in_package = true;
if ($in_package)
@@ -781,9 +785,8 @@ class CartRuleCore extends ObjectModel
{
$selected_products_reduction = 0;
$selected_products = $this->checkProductRestrictions($context, true);
$products2 = (is_null($products) ? $context->cart->getProducts() : $products);
if (is_array($selected_products))
foreach ($products2 as $product)
foreach ($package_products as $product)
if (in_array($product['id_product'].'-'.$product['id_product_attribute'], $selected_products)
|| in_array($product['id_product'].'-0', $selected_products))
{
@@ -796,6 +799,10 @@ class CartRuleCore extends ObjectModel
// Discount (¤)
if ($this->reduction_amount)
{
$prorata = 1;
if (!is_null($package))
$prorata = $context->cart->getOrderTotal($useTax, Cart::ONLY_PRODUCTS, $package['products']) / $context->cart->getOrderTotal($useTax, Cart::ONLY_PRODUCTS);
$reduction_amount = $this->reduction_amount;
// If we need to convert the voucher value to the cart currency
if ($this->reduction_currency != $context->currency->id)
@@ -815,7 +822,7 @@ class CartRuleCore extends ObjectModel
// If it has the same tax application that you need, then it's the right value, whatever the product!
if ($this->reduction_tax == $useTax)
$reduction_value += $reduction_amount;
$reduction_value += $prorata * $reduction_amount;
else
{
if ($this->reduction_product > 0)
@@ -833,14 +840,15 @@ class CartRuleCore extends ObjectModel
$product_vat_rate = $product_vat_amount / $product_price_te;
if ($this->reduction_tax && !$useTax)
$reduction_value += $reduction_amount / (1 + $product_vat_rate);
$reduction_value += $prorata * $reduction_amount / (1 + $product_vat_rate);
elseif (!$this->reduction_tax && $useTax)
$reduction_value += $reduction_amount * (1 + $product_vat_rate);
$reduction_value += $prorata * $reduction_amount * (1 + $product_vat_rate);
}
}
// Discount (¤) on the whole order
elseif ($this->reduction_product == 0)
{
// TODO : this should not use the prorata
$cart_amount_ti = $context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$cart_amount_te = $context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
@@ -852,9 +860,9 @@ class CartRuleCore extends ObjectModel
$cart_average_vat_rate = $cart_vat_amount / $cart_amount_te;
if ($this->reduction_tax && !$useTax)
$reduction_value += $reduction_amount / (1 + $cart_average_vat_rate);
$reduction_value += $prorata * $reduction_amount / (1 + $cart_average_vat_rate);
elseif (!$this->reduction_tax && $useTax)
$reduction_value += $reduction_amount * (1 + $cart_average_vat_rate);
$reduction_value += $prorata * $reduction_amount * (1 + $cart_average_vat_rate);
}
/*
* Reduction on the cheapest or on the selection is not really meaningful and has been disabled in the backend
@@ -869,10 +877,17 @@ class CartRuleCore extends ObjectModel
// Free gift
if ((int)$this->gift_product && ($filter == CartRule::FILTER_ACTION_ALL || $filter == CartRule::FILTER_ACTION_GIFT))
{
$products2 = (is_null($products) ? $context->cart->getProducts() : $products);
foreach ($products2 as $product)
$id_address = (is_null($package) ? 0 : $package['id_address']);
foreach ($package_products as $product)
if ($product['id_product'] == $this->gift_product && $product['id_product_attribute'] == $this->gift_product_attribute)
$reduction_value += ($useTax ? $product['price_wt'] : $product['price']);
{
// The free gift coupon must be applied to one product only (needed for multi-shipping which manage multiple product lists)
if (!isset(CartRule::$only_one_gift[$this->id.'-'.$this->gift_product]) || CartRule::$only_one_gift[$this->id.'-'.$this->gift_product] == $id_address)
{
$reduction_value += ($useTax ? $product['price_wt'] : $product['price']);
CartRule::$only_one_gift[$this->id.'-'.$this->gift_product] = $id_address;
}
}
}
return $reduction_value;
+3 -2
View File
@@ -327,9 +327,10 @@ abstract class PaymentModuleCore extends Module
$cart_rules_list = '';
foreach ($cart->getCartRules() as $cart_rule)
{
$package = array('id_address' => $order->id_address_delivery, 'products' => $order->product_list);
$values = array(
'tax_incl' => $cart_rule['obj']->getContextualValue(true, $this->context, CartRule::FILTER_ACTION_ALL, $order->product_list),
'tax_excl' => $cart_rule['obj']->getContextualValue(false, $this->context, CartRule::FILTER_ACTION_ALL, $order->product_list)
'tax_incl' => $cart_rule['obj']->getContextualValue(true, $this->context, CartRule::FILTER_ACTION_ALL, $package),
'tax_excl' => $cart_rule['obj']->getContextualValue(false, $this->context, CartRule::FILTER_ACTION_ALL, $package)
);
// If the reduction is not applicable to this order, then continue with the next one