[-] FO : fixed a great part of the cart rules with multi-shipping
This commit is contained in:
1 parent
2d57f0a704
commit
442c27830d
3 files changed
+73
-91
No files matched your search
+24
-5
@@ -1425,7 +1425,8 @@ class CartCore extends ObjectModel
|
|||||||
|
|
||||||
$order_total_discount = 0;
|
$order_total_discount = 0;
|
||||||
if ($type != Cart::ONLY_PRODUCTS && CartRule::isFeatureActive())
|
if ($type != Cart::ONLY_PRODUCTS && CartRule::isFeatureActive())
|
||||||
{
|
{
|
||||||
|
// First, retrieve the cart rules associated to this "getOrderTotal"
|
||||||
if ($with_shipping)
|
if ($with_shipping)
|
||||||
$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL);
|
$cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL);
|
||||||
else
|
else
|
||||||
@@ -1443,15 +1444,33 @@ class CartCore extends ObjectModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Then, calculate the contextual value for each one
|
||||||
foreach ($cart_rules as $cart_rule)
|
foreach ($cart_rules as $cart_rule)
|
||||||
if ($with_shipping)
|
{
|
||||||
|
// If the cart rule offers free shipping, add the shipping cost
|
||||||
|
if ($with_shipping && $cart_rule['obj']->free_shipping)
|
||||||
$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_ALL), 2);
|
$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_ALL), 2);
|
||||||
else
|
|
||||||
|
// 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)
|
||||||
{
|
{
|
||||||
$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_REDUCTION), 2);
|
$in_order = false;
|
||||||
$order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_GIFT), 2);
|
if (is_null($products))
|
||||||
|
$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']))
|
||||||
|
$in_order = true;
|
||||||
|
|
||||||
|
if ($in_order)
|
||||||
|
$order_total_discount += $cart_rule['obj']->getContextualValue($with_taxes, null, CartRule::FILTER_ACTION_GIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
$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);
|
||||||
$order_total -= $order_total_discount;
|
$order_total -= $order_total_discount;
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-8
@@ -699,7 +699,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)
|
public function getContextualValue($useTax, Context $context = null, $filter = null, $products = null)
|
||||||
{
|
{
|
||||||
if (!CartRule::isFeatureActive())
|
if (!CartRule::isFeatureActive())
|
||||||
return 0;
|
return 0;
|
||||||
@@ -735,9 +735,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);
|
$order_total = $context->cart->getOrderTotal($useTax, Cart::ONLY_PRODUCTS, $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), 2);
|
$order_total -= Tools::ps_round($cart_rule['obj']->getContextualValue($useTax, $context, CartRule::FILTER_ACTION_GIFT, $products), 2);
|
||||||
|
|
||||||
$reduction_value += $order_total * $this->reduction_percent / 100;
|
$reduction_value += $order_total * $this->reduction_percent / 100;
|
||||||
}
|
}
|
||||||
@@ -745,7 +745,8 @@ 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)
|
||||||
{
|
{
|
||||||
foreach ($context->cart->getProducts() as $product)
|
$products2 = (is_null($products) ? $context->cart->getProducts() : $products);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@@ -754,13 +755,25 @@ class CartRuleCore extends ObjectModel
|
|||||||
if ($this->reduction_percent && $this->reduction_product == -1)
|
if ($this->reduction_percent && $this->reduction_product == -1)
|
||||||
{
|
{
|
||||||
$minPrice = false;
|
$minPrice = false;
|
||||||
foreach ($context->cart->getProducts() as $product)
|
$cheapest_product = null;
|
||||||
|
$products2 = $context->cart->getProducts();
|
||||||
|
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))
|
||||||
|
{
|
||||||
$minPrice = $price;
|
$minPrice = $price;
|
||||||
|
$cheapest_product = $product['id_product'].'-'.$product['id_product_attribute'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$reduction_value += $minPrice * $this->reduction_percent / 100;
|
|
||||||
|
// Check if the cheapest product is in the package
|
||||||
|
$in_package = false;
|
||||||
|
foreach ($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)
|
||||||
|
$reduction_value += $minPrice * $this->reduction_percent / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discount (%) on the selection of products
|
// Discount (%) on the selection of products
|
||||||
@@ -768,8 +781,9 @@ 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 ($context->cart->getProducts() as $product)
|
foreach ($products2 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))
|
||||||
{
|
{
|
||||||
@@ -855,7 +869,8 @@ 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))
|
||||||
{
|
{
|
||||||
foreach ($context->cart->getProducts() as $product)
|
$products2 = (is_null($products) ? $context->cart->getProducts() : $products);
|
||||||
|
foreach ($products2 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']);
|
$reduction_value += ($useTax ? $product['price_wt'] : $product['price']);
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-78
@@ -136,15 +136,13 @@ abstract class PaymentModuleCore extends Module
|
|||||||
foreach ($cart_delivery_option as $id_address => $key_carriers)
|
foreach ($cart_delivery_option as $id_address => $key_carriers)
|
||||||
foreach ($delivery_option_list[$id_address][$key_carriers]['carrier_list'] as $id_carrier => $data)
|
foreach ($delivery_option_list[$id_address][$key_carriers]['carrier_list'] as $id_carrier => $data)
|
||||||
foreach ($data['package_list'] as $id_package)
|
foreach ($data['package_list'] as $id_package)
|
||||||
{
|
|
||||||
$package_list[$id_address][$id_package]['id_carrier'] = $id_carrier;
|
$package_list[$id_address][$id_package]['id_carrier'] = $id_carrier;
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($package_list as $id_address => $packageByAddress)
|
foreach ($package_list as $id_address => $packageByAddress)
|
||||||
foreach ($packageByAddress as $id_package => $package)
|
foreach ($packageByAddress as $id_package => $package)
|
||||||
{
|
{
|
||||||
$product_list = $package['product_list'];
|
|
||||||
$order = new Order();
|
$order = new Order();
|
||||||
|
$order->product_list = $package['product_list'];
|
||||||
|
|
||||||
$carrier = null;
|
$carrier = null;
|
||||||
if (!$cart->isVirtualCart() && isset($package['id_carrier']))
|
if (!$cart->isVirtualCart() && isset($package['id_carrier']))
|
||||||
@@ -177,27 +175,28 @@ abstract class PaymentModuleCore extends Module
|
|||||||
$order->conversion_rate = $currency->conversion_rate;
|
$order->conversion_rate = $currency->conversion_rate;
|
||||||
$amount_paid = !$dont_touch_amount ? Tools::ps_round((float)$amount_paid, 2) : $amount_paid;
|
$amount_paid = !$dont_touch_amount ? Tools::ps_round((float)$amount_paid, 2) : $amount_paid;
|
||||||
$order->total_paid_real = 0;
|
$order->total_paid_real = 0;
|
||||||
$order->total_products = (float)$cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $product_list, $carrier->id);
|
|
||||||
$order->total_products_wt = (float)$cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $product_list, $carrier->id);
|
$order->total_products = (float)$cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $order->product_list, $carrier->id);
|
||||||
|
$order->total_products_wt = (float)$cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $order->product_list, $carrier->id);
|
||||||
|
|
||||||
$order->total_discounts = (float)abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list, $carrier->id));
|
$order->total_discounts_tax_excl = (float)abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $order->product_list, $carrier->id));
|
||||||
$order->total_discounts_tax_excl = (float)abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $product_list, $carrier->id));
|
$order->total_discounts_tax_incl = (float)abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $order->product_list, $carrier->id));
|
||||||
$order->total_discounts_tax_incl = (float)abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list, $carrier->id));
|
$order->total_discounts = $order->total_discounts_tax_incl;
|
||||||
|
|
||||||
$order->total_shipping = (float)$cart->getPackageShippingCost((int)$carrier->id, true, null, $product_list);
|
|
||||||
$order->total_shipping_tax_excl = (float)$cart->getPackageShippingCost((int)$carrier->id, false, null, $product_list);
|
|
||||||
$order->total_shipping_tax_incl = (float)$cart->getPackageShippingCost((int)$carrier->id, true, null, $product_list);
|
|
||||||
|
|
||||||
|
$order->total_shipping_tax_excl = (float)$cart->getPackageShippingCost((int)$carrier->id, false, null, $order->product_list);
|
||||||
|
$order->total_shipping_tax_incl = (float)$cart->getPackageShippingCost((int)$carrier->id, true, null, $order->product_list);
|
||||||
|
$order->total_shipping = $order->total_shipping_tax_incl;
|
||||||
|
|
||||||
if (!is_null($carrier) && Validate::isLoadedObject($carrier))
|
if (!is_null($carrier) && Validate::isLoadedObject($carrier))
|
||||||
$order->carrier_tax_rate = $carrier->getTaxesRate(new Address($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
|
$order->carrier_tax_rate = $carrier->getTaxesRate(new Address($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
|
||||||
|
|
||||||
$order->total_wrapping = (float)abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $product_list, $carrier->id));
|
$order->total_wrapping_tax_excl = (float)abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $order->product_list, $carrier->id));
|
||||||
$order->total_wrapping_tax_excl = (float)abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $product_list, $carrier->id));
|
$order->total_wrapping_tax_incl = (float)abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $order->product_list, $carrier->id));
|
||||||
$order->total_wrapping_tax_incl = (float)abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $product_list, $carrier->id));
|
$order->total_wrapping = $order->total_wrapping_tax_incl;
|
||||||
|
|
||||||
$order->total_paid = (float)Tools::ps_round((float)$cart->getOrderTotal(true, Cart::BOTH, $product_list, $carrier->id), 2);
|
$order->total_paid_tax_excl = (float)Tools::ps_round((float)$cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $carrier->id), 2);
|
||||||
$order->total_paid_tax_excl = (float)Tools::ps_round((float)$cart->getOrderTotal(false, Cart::BOTH, $product_list, $carrier->id), 2);
|
$order->total_paid_tax_incl = (float)Tools::ps_round((float)$cart->getOrderTotal(true, Cart::BOTH, $order->product_list, $carrier->id), 2);
|
||||||
$order->total_paid_tax_incl = (float)Tools::ps_round((float)$cart->getOrderTotal(true, Cart::BOTH, $product_list, $carrier->id), 2);
|
$order->total_paid = $order->total_paid_tax_incl;
|
||||||
|
|
||||||
$order->invoice_date = '0000-00-00 00:00:00';
|
$order->invoice_date = '0000-00-00 00:00:00';
|
||||||
$order->delivery_date = '0000-00-00 00:00:00';
|
$order->delivery_date = '0000-00-00 00:00:00';
|
||||||
@@ -223,7 +222,7 @@ abstract class PaymentModuleCore extends Module
|
|||||||
|
|
||||||
// Insert new Order detail list using cart for the current order
|
// Insert new Order detail list using cart for the current order
|
||||||
$order_detail = new OrderDetail(null, null, $this->context);
|
$order_detail = new OrderDetail(null, null, $this->context);
|
||||||
$order_detail->createList($order, $cart, $id_order_state, $product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
|
$order_detail->createList($order, $cart, $id_order_state, $order->product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
|
||||||
$order_detail_list[] = $order_detail;
|
$order_detail_list[] = $order_detail;
|
||||||
|
|
||||||
// Adding an entry in order_carrier table
|
// Adding an entry in order_carrier table
|
||||||
@@ -322,63 +321,18 @@ abstract class PaymentModuleCore extends Module
|
|||||||
} // end foreach ($products)
|
} // end foreach ($products)
|
||||||
|
|
||||||
$cart_rules_list = '';
|
$cart_rules_list = '';
|
||||||
$cart_rules = $cart->getCartRules();
|
foreach ($cart->getCartRules() as $cart_rule)
|
||||||
$total_cart_rules = array('tax_incl' => 0, 'tax_excl' => 0);
|
|
||||||
foreach ($cart_rules as $cart_rule)
|
|
||||||
{
|
{
|
||||||
$values = array('tax_incl' => 0, 'tax_excl' => 0);
|
$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)
|
||||||
|
);
|
||||||
|
|
||||||
// If the cart is split in multiple orders, the cart rule must be split too
|
// If the reduction is not applicable to this order, then continue with the next one
|
||||||
if (count($order_list) > 1)
|
|
||||||
{
|
|
||||||
// If the cart rule is a fee gift, then add the free gift value only if the gift is in this order
|
|
||||||
if ((int)$cart_rule['obj']->gift_product && !$only_one_gift)
|
|
||||||
{
|
|
||||||
$in_order = (bool)Db::getInstance()->getValue('
|
|
||||||
SELECT product_id
|
|
||||||
FROM '._DB_PREFIX_.'order_detail
|
|
||||||
WHERE product_id = '.(int)$cart_rule['obj']->gift_product.'
|
|
||||||
AND product_attribute_id = '.(int)$cart_rule['obj']->gift_product_attribute.'
|
|
||||||
AND id_order = '.(int)$order->id);
|
|
||||||
|
|
||||||
if ($in_order)
|
|
||||||
{
|
|
||||||
$values['tax_incl'] += $cart_rule['obj']->getContextualValue(true, null, CartRule::FILTER_ACTION_GIFT);
|
|
||||||
$values['tax_excl'] += $cart_rule['obj']->getContextualValue(false, null, CartRule::FILTER_ACTION_GIFT);
|
|
||||||
$only_one_gift = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the cart rule offers free shipping, add the shipping cost
|
|
||||||
if ($cart_rule['obj']->free_shipping)
|
|
||||||
{
|
|
||||||
$values['tax_incl'] += $order->total_shipping_tax_incl;
|
|
||||||
$values['tax_excl'] += $order->total_shipping_tax_excl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the cart rule offers a reduction, the amount is prorated
|
|
||||||
if ($cart_rule['obj']->reduction_amount || $cart_rule['obj']->reduction_percent)
|
|
||||||
{
|
|
||||||
$prorata = $order->total_paid_tax_incl / $cart_total_paid;
|
|
||||||
$values['tax_incl'] += Tools::ps_round($prorata * $cart_rule['obj']->getContextualValue(true, null, CartRule::FILTER_ACTION_REDUCTION), 2);
|
|
||||||
$values['tax_excl'] += Tools::ps_round($prorata * $cart_rule['obj']->getContextualValue(false, null, CartRule::FILTER_ACTION_REDUCTION), 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$values = array(
|
|
||||||
'tax_incl' => $cart_rule['obj']->getContextualValue(true),
|
|
||||||
'tax_excl' => $cart_rule['obj']->getContextualValue(false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the reduction is not applicable to this order (in a multi-shipping case), then try the next
|
|
||||||
if (!$values['tax_excl'])
|
if (!$values['tax_excl'])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$total_cart_rules['tax_incl'] += $values['tax_incl'];
|
$order->addCartRule($cart_rule['obj']->id, $cart_rule['obj']->name, $values);
|
||||||
$total_cart_rules['tax_excl'] += $values['tax_excl'];
|
|
||||||
|
|
||||||
|
|
||||||
/* IF
|
/* IF
|
||||||
** - This is not multi-shipping
|
** - This is not multi-shipping
|
||||||
@@ -423,12 +377,6 @@ abstract class PaymentModuleCore extends Module
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$order->addCartRule($cart_rule['obj']->id, $cart_rule['obj']->name, $values);
|
|
||||||
|
|
||||||
$order->total_discounts = $order->total_discounts_tax_incl = round($total_cart_rules['tax_incl'], 9);
|
|
||||||
$order->total_discounts_tax_excl = round($total_cart_rules['tax_excl'], 9);
|
|
||||||
$order->update();
|
|
||||||
|
|
||||||
if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && !in_array($cart_rule['obj']->id, $cart_rule_used))
|
if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && !in_array($cart_rule['obj']->id, $cart_rule_used))
|
||||||
{
|
{
|
||||||
$cart_rule_used[] = $cart_rule['obj']->id;
|
$cart_rule_used[] = $cart_rule['obj']->id;
|
||||||
|
|||||||
Reference in new issue
Block a user