[-] 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; $in_order = true;
else else
foreach ($products as $products) 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; $in_order = true;
if ($in_order) 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 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) 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); $order_total_discount = min(Tools::ps_round($order_total_discount, 2), $wrapping_fees + $order_total_products + $shipping_fees);
+34 -19
View File
@@ -27,11 +27,15 @@
class CartRuleCore extends ObjectModel 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_ALL = 1;
const FILTER_ACTION_SHIPPING = 2; const FILTER_ACTION_SHIPPING = 2;
const FILTER_ACTION_REDUCTION = 3; const FILTER_ACTION_REDUCTION = 3;
const FILTER_ACTION_GIFT = 4; 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 $id;
public $name; public $name;
public $id_customer; public $id_customer;
@@ -356,7 +360,6 @@ class CartRuleCore extends ObjectModel
return $productRules; return $productRules;
} }
// Todo : Add shop management
/** /**
* Check if this cart rule can be applied * Check if this cart rule can be applied
* *
@@ -699,7 +702,7 @@ class CartRuleCore extends ObjectModel
* @param Context $context * @param Context $context
* @return float|int|string * @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()) if (!CartRule::isFeatureActive())
return 0; return 0;
@@ -708,6 +711,9 @@ class CartRuleCore extends ObjectModel
if (!$filter) if (!$filter)
$filter = CartRule::FILTER_ACTION_ALL; $filter = CartRule::FILTER_ACTION_ALL;
$all_products = $context->cart->getProducts();
$package_products = (is_null($package) ? $all_products : $package['products']);
$reduction_value = 0; $reduction_value = 0;
// Free shipping on selected carriers // Free shipping on selected carriers
@@ -735,9 +741,9 @@ class CartRuleCore extends ObjectModel
if ($this->reduction_percent && $this->reduction_product == 0) if ($this->reduction_percent && $this->reduction_product == 0)
{ {
// Do not give a reduction on free products! // 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) 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; $reduction_value += $order_total * $this->reduction_percent / 100;
} }
@@ -745,8 +751,7 @@ class CartRuleCore extends ObjectModel
// Discount (%) on a specific product // Discount (%) on a specific product
if ($this->reduction_percent && $this->reduction_product > 0) if ($this->reduction_percent && $this->reduction_product > 0)
{ {
$products2 = (is_null($products) ? $context->cart->getProducts() : $products); foreach ($package_products as $product)
foreach ($products2 as $product)
if ($product['id_product'] == $this->reduction_product) if ($product['id_product'] == $this->reduction_product)
$reduction_value += ($useTax ? $product['total_wt'] : $product['total']) * $this->reduction_percent / 100; $reduction_value += ($useTax ? $product['total_wt'] : $product['total']) * $this->reduction_percent / 100;
} }
@@ -756,8 +761,7 @@ class CartRuleCore extends ObjectModel
{ {
$minPrice = false; $minPrice = false;
$cheapest_product = null; $cheapest_product = null;
$products2 = $context->cart->getProducts(); foreach ($all_products as $product)
foreach ($products2 as $product)
{ {
$price = ($useTax ? $product['price_wt'] : $product['price']); $price = ($useTax ? $product['price_wt'] : $product['price']);
if ($price > 0 && ($minPrice === false || $minPrice > $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 // Check if the cheapest product is in the package
$in_package = false; $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) if ($product['id_product'].'-'.$product['id_product_attribute'] == $cheapest_product || $product['id_product'].'-0' == $cheapest_product)
$in_package = true; $in_package = true;
if ($in_package) if ($in_package)
@@ -781,9 +785,8 @@ class CartRuleCore extends ObjectModel
{ {
$selected_products_reduction = 0; $selected_products_reduction = 0;
$selected_products = $this->checkProductRestrictions($context, true); $selected_products = $this->checkProductRestrictions($context, true);
$products2 = (is_null($products) ? $context->cart->getProducts() : $products);
if (is_array($selected_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) if (in_array($product['id_product'].'-'.$product['id_product_attribute'], $selected_products)
|| in_array($product['id_product'].'-0', $selected_products)) || in_array($product['id_product'].'-0', $selected_products))
{ {
@@ -796,6 +799,10 @@ class CartRuleCore extends ObjectModel
// Discount (¤) // Discount (¤)
if ($this->reduction_amount) 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; $reduction_amount = $this->reduction_amount;
// If we need to convert the voucher value to the cart currency // If we need to convert the voucher value to the cart currency
if ($this->reduction_currency != $context->currency->id) 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 it has the same tax application that you need, then it's the right value, whatever the product!
if ($this->reduction_tax == $useTax) if ($this->reduction_tax == $useTax)
$reduction_value += $reduction_amount; $reduction_value += $prorata * $reduction_amount;
else else
{ {
if ($this->reduction_product > 0) if ($this->reduction_product > 0)
@@ -833,14 +840,15 @@ class CartRuleCore extends ObjectModel
$product_vat_rate = $product_vat_amount / $product_price_te; $product_vat_rate = $product_vat_amount / $product_price_te;
if ($this->reduction_tax && !$useTax) 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) 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 // Discount (¤) on the whole order
elseif ($this->reduction_product == 0) elseif ($this->reduction_product == 0)
{ {
// TODO : this should not use the prorata
$cart_amount_ti = $context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS); $cart_amount_ti = $context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$cart_amount_te = $context->cart->getOrderTotal(false, 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; $cart_average_vat_rate = $cart_vat_amount / $cart_amount_te;
if ($this->reduction_tax && !$useTax) 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) 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 * 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 // Free gift
if ((int)$this->gift_product && ($filter == CartRule::FILTER_ACTION_ALL || $filter == CartRule::FILTER_ACTION_GIFT)) if ((int)$this->gift_product && ($filter == CartRule::FILTER_ACTION_ALL || $filter == CartRule::FILTER_ACTION_GIFT))
{ {
$products2 = (is_null($products) ? $context->cart->getProducts() : $products); $id_address = (is_null($package) ? 0 : $package['id_address']);
foreach ($products2 as $product) foreach ($package_products as $product)
if ($product['id_product'] == $this->gift_product && $product['id_product_attribute'] == $this->gift_product_attribute) 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; return $reduction_value;
+3 -2
View File
@@ -327,9 +327,10 @@ abstract class PaymentModuleCore extends Module
$cart_rules_list = ''; $cart_rules_list = '';
foreach ($cart->getCartRules() as $cart_rule) foreach ($cart->getCartRules() as $cart_rule)
{ {
$package = array('id_address' => $order->id_address_delivery, 'products' => $order->product_list);
$values = array( $values = array(
'tax_incl' => $cart_rule['obj']->getContextualValue(true, $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, $order->product_list) '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 // If the reduction is not applicable to this order, then continue with the next one