У власному модулі додайте наступне до config.xml
:
<models>
<salesrule>
<rewrite>
<quote_discount>Namespace_Module_Rewrite_SalesRule_Model_Quote_Discount</quote_discount>
</rewrite>
</salesrule>
</models>
<frontend>
<routers>
<checkout>
<args>
<modules>
<Namespace_Module before="Mage_Checkout">Namespace_Module_Checkout</Namespace_Module>
</modules>
</args>
</checkout>
</routers>
</frontend>
Перший - це переписання Mage_SalesRule_Model_Quote_Discount
наNamespace_Module_Rewrite_SalesRule_Model_Quote_Discount
Другий - перевантажений контролер Mage_Checkout_CartController
Далі додайте наступний файл app/code/community/Namespace/Module/controllers/Checkout/CartController.php
і вставте наступний код:
<?php
require_once 'Mage/Checkout/controllers/CartController.php';
class Namespace_Module_Checkout_CartController extends Mage_Checkout_CartController
{
/**
* Initialize coupon
*/
public function couponPostAction()
{
/**
* No reason continue with empty shopping cart
*/
if (!$this->_getCart()->getQuote()->getItemsCount()) {
$this->_goBack();
return;
}
$couponCode = (string) $this->getRequest()->getParam('coupon_code');
if ($this->getRequest()->getParam('remove') == 1) {
$couponCode = '';
}
$oldCouponCode = $this->_getQuote()->getCouponCode();
if (!strlen($couponCode) && !strlen($oldCouponCode)) {
$this->_goBack();
return;
}
try {
$codeLength = strlen($couponCode);
$isCodeLengthValid = $codeLength && $codeLength <= Mage_Checkout_Helper_Cart::COUPON_CODE_MAX_LENGTH;
// Combine multiple coupons
$couponFlag = true;
if ($isCodeLengthValid) {
$del = ',';
if ($oldCouponCode) {
if ($oldCouponCode == $couponCode) {
$couponCode = $oldCouponCode;
} else {
$couponCode = $oldCouponCode . $del . $couponCode;
}
}
} else {
$couponCode = '';
}
$this->_getQuote()->getShippingAddress()->setCollectShippingRates(true);
$this->_getQuote()->setCouponCode($couponCode)
->collectTotals()
->save();
if ($codeLength) {
if ($isCodeLengthValid && $couponFlag) {
$this->_getSession()->addSuccess(
$this->__('Coupon code "%s" was applied.', Mage::helper('core')->escapeHtml($couponCode))
);
} else {
$this->_getSession()->addError(
$this->__('Coupon code "%s" is not valid.', Mage::helper('core')->escapeHtml($couponCode))
);
}
} else {
$this->_getSession()->addSuccess($this->__('Coupon code was canceled.'));
}
} catch (Mage_Core_Exception $e) {
$this->_getSession()->addError($e->getMessage());
} catch (Exception $e) {
$this->_getSession()->addError($this->__('Cannot apply the coupon code.'));
Mage::logException($e);
}
$this->_goBack();
}
}
Ви помітите, що я додав розділ, який поєднує купонні коди з ",". Це, очевидно, може бути більш вдосконаленим, і ви можете додати додаткові перевірки тощо, але цей код повинен працювати прямо з місця.
І нарешті нам потрібно додати ту частину, яка виконує всю магію. Додайте файлapp/code/community/Namespace/Module/Rewrite/SalesRule/Model/Quote/Discount.php
і додайте вміст:
<?php
class Namespace_Module_Rewrite_SalesRule_Model_Quote_Discount extends Mage_SalesRule_Model_Quote_Discount
{
/**
* Collect address discount amount
*
* @param Mage_Sales_Model_Quote_Address $address
* @return Mage_SalesRule_Model_Quote_Discount
*/
public function collect(Mage_Sales_Model_Quote_Address $address)
{
Mage_Sales_Model_Quote_Address_Total_Abstract::collect($address);
$quote = $address->getQuote();
$store = Mage::app()->getStore($quote->getStoreId());
$this->_calculator->reset($address);
$items = $this->_getAddressItems($address);
if (!count($items)) {
return $this;
}
$couponCode = $quote->getCouponCode();
$couponArray = explode(',',$couponCode);
foreach ($couponArray as $couponCode) {
$this->_calculator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $couponCode);
$this->_calculator->initTotals($items, $address);
$eventArgs = array(
'website_id' => $store->getWebsiteId(),
'customer_group_id' => $quote->getCustomerGroupId(),
'coupon_code' => $couponCode,
);
$address->setDiscountDescription(array());
$items = $this->_calculator->sortItemsByPriority($items);
foreach ($items as $item) {
if ($item->getNoDiscount()) {
$item->setDiscountAmount(0);
$item->setBaseDiscountAmount(0);
}
else {
/**
* Child item discount we calculate for parent
*/
if ($item->getParentItemId()) {
continue;
}
$eventArgs['item'] = $item;
Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);
if ($item->getHasChildren() && $item->isChildrenCalculated()) {
foreach ($item->getChildren() as $child) {
$this->_calculator->process($child);
$eventArgs['item'] = $child;
Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);
$this->_aggregateItemDiscount($child);
}
} else {
$this->_calculator->process($item);
$this->_aggregateItemDiscount($item);
}
}
}
/**
* process weee amount
*/
if (Mage::helper('weee')->isEnabled() && Mage::helper('weee')->isDiscounted($store)) {
$this->_calculator->processWeeeAmount($address, $items);
}
/**
* Process shipping amount discount
*/
$address->setShippingDiscountAmount(0);
$address->setBaseShippingDiscountAmount(0);
if ($address->getShippingAmount()) {
$this->_calculator->processShippingAmount($address);
$this->_addAmount(-$address->getShippingDiscountAmount());
$this->_addBaseAmount(-$address->getBaseShippingDiscountAmount());
}
$this->_calculator->prepareDescription($address);
}
return $this;
}
}
В основному, це робить розбиття купона, прокручування кожного коду купона, обчислення та оновлення підсумків котирувань.
Для тестування у мене є правила налаштування 2 кошика:
- тест 1 - 10% знижка на ціну товару - Зупиніть подальший обробку правил: Ні
- тест 2 - 10% знижка на ціну товару - Зупиніть подальший обробку правил: Ні
Немає купона:
Додано купонний тест 1:
Додано купонний тест 2
Я перевірив фіксовану кількість знижок, і це працює, як і очікувалося.
І, як я вже сказав, вам може знадобитися додати додаткову перевірку, можливо, на копії, але саме з цього ви б почали. На передній частині ви можете додати деякі логічні коди з розбиттям коду, проте ви віддаєте перевагу або залиште так, як є.