Автоматические купоны на скидку, конфликтующие с Оформлением нулевой оплаты
Я работал над проектом, который требует, чтобы клиенты автоматически применяли код скидки к своей корзине на основе товаров, которые там находятся.
Я думал, что это отлично работает с логикой кода ниже. Я видел, как код был сгенерирован (в конце и показал скидку в корзине). Однако сегодня был поднят вопрос о том, что кредит клиента не может быть использован исключительно для оплаты заказа.
Я успешно сузил его до этого модуля который при отключении проблемы нет. Однако я считаю, что, поскольку мы генерируем код на лету и позволяем Magento обрабатывать фактическую скидку, это должно работать как обычно. Отладка показывает, что общая сумма по-прежнему остается первоначальной ценой при проверке, доступна ли она в бесплатной кассе.
Есть ли какая-то дополнительная логика, которую мне нужно ввести, чтобы это было совместимо?
Пожалуйста, имейте в виду, что я немного замаскировал имя пространства имен/модуля из-за по соображениям конфиденциальности клиента, поэтому вы можете обнаружить некоторые ошибки ниже в этом, но, пожалуйста, не обращайте внимания на то, что код действительно выполняется и выполняет то, что я ожидал.
Ожидания:
Если клиент соответствует критериям для скидки, генерируется код скидки, и он получает скидку в корзине.
Если у клиента есть достаточный кредит в магазине для полной оплаты, он должен иметь возможность полностью оплатить кредит в магазине.
Фактический:
Скидка генерируется код (если применимо)
Клиент не может использовать кредит магазина для полной оплаты своей покупки.
Наблюдатель: checkout_cart_product_add_ после
public function checkout_cart_product_add_after($observer)
{
if (!Mage::helper('core')->isModuleOutputEnabled('Namespace_WholesaleDiscount')) {
return;
}
/*
* When emptying the cart this observer is updated
* due to the setting of it to 0 for deletion.
* This prevents running the observer and thus resetting items in quote.
*/
$request = Mage::app()->getRequest()->getParam('update_cart_action');
if ($request == 'empty_cart') {
return;
}
try {
$model = Mage::getModel('salesrule/rule')
->getCollection()
->addFieldToSelect('*')
->addFieldToFilter('name', array('eq' => sprintf('WHOLESALE AUTO_%s', Mage::getSingleton('customer/session')->getSessionId())))
->load();
if ($model->count() < 1) {
// No coupon yet.
$helper = Mage::helper('wholesalediscount');
$helper->createDiscountCode($helper->getDiscountAmount(), Mage::getSingleton('customer/session')->getSessionId());
$model = Mage::getModel('salesrule/rule')
->getCollection()
->addFieldToFilter('name', array('eq' => sprintf('WHOLESALE AUTO_%s', Mage::getSingleton('customer/session')->getSessionId())))
->getFirstItem();
} else {
$helper = Mage::helper('wholesalediscount');
$model = $model->getFirstItem();
$model->setDiscountAmount($helper->getDiscountAmount());
$code = Mage::helper('core')->getRandomString(16);
// Magento initializes the coupon_code, but on model load it is code.
$model->setCouponCode($code);
$model->setCode($code);
$model->save();
}
$couponCode = $model->getCode();
/* END This part is my extra, just to load our coupon for this specific customer */
Mage::getSingleton('checkout/cart')
->getQuote()
->getShippingAddress()
->setCollectShippingRates(true);
Mage::getSingleton('checkout/cart')
->getQuote()
->setCouponCode(strlen($couponCode) ? $couponCode : '')
->collectTotals()
->save();
} catch (Exception $e) {
Mage::logException($e);
}
return $this;
}
Вспомогательная логика: Опять же, как и выше, я замаскировал все, что, по моему мнению, потенциально могло бы раскрыть бизнес-логику или нарушить конфиденциальность любого клиента. Как и прежде, два метода здесь просто генерируют купон с кодом скидки (который я вижу, работая в admin и применяя скидку) и вычисляют скидка (это полностью бизнес-логика)
public function createDiscountCode($discount, $reference)
{
$now = new Zend_Date();
$now->setTimezone('UTC');
$data = array(
'product_ids' => null,
'name' => sprintf('WHOLESALE AUTO_%s', $reference),
'description' => null,
'is_active' => 1,
'website_ids' => array(Mage::app()->getWebsite()->getId()),
'customer_group_ids' => array(Mage::getSingleton('customer/session')->getCustomerGroupId()),
'coupon_type' => 2,
'coupon_code' => Mage::helper('core')->getRandomString(16),
'uses_per_coupon' => 1,
'uses_per_customer' => 1,
'from_date' => $now->getFullYear() . "-". $now->getMonth() . "-" . $now->getDay(),
'to_date' => null,
'sort_order' => null,
'is_rss' => 1,
'rule' => array(
'conditions' => array(
array(
'type' => 'salesrule/rule_condition_combine',
'aggregator' => 'all',
'value' => 1,
'new_child' => null
)
)
),
'simple_action' => 'cart_fixed',
'discount_amount' => $this->getDiscountAmount(),
'discount_qty' => 0,
'discount_step' => null,
'apply_to_shipping' => 0,
'simple_free_shipping' => 0,
'stop_rules_processing' => 0,
'rule' => array(
'actions' => array(
array(
'type' => 'salesrule/rule_condition_product_combine',
'aggregator' => 'all',
'value' => 1,
'new_child' => null
)
)
),
'store_labels' => array('E-Liquids With Kits')
);
$model = Mage::getModel('salesrule/rule');
$validateResult = $model->validateData(new Varien_Object($data));
if ($validateResult == true) {
if (isset($data['simple_action']) && $data['simple_action'] == 'by_percent'
&& isset($data['discount_amount'])) {
$data['discount_amount'] = min(100, $data['discount_amount']);
}
if (isset($data['rule']['conditions'])) {
$data['conditions'] = $data['rule']['conditions'];
}
if (isset($data['rule']['actions'])) {
$data['actions'] = $data['rule']['actions'];
}
unset($data['rule']);
$model->setData($data);
$model->save();
}
}
/*
* Use this to calculate how much money off is allowed based on whats in the cart.
*/
public function getDiscountAmount()
{
$customer = Mage::getSingleton('customer/session')->getCustomer();
$cart = Mage::getModel('checkout/cart');
$discountItems = array();
/* Exclude some Business logic here */
foreach ($cart->getQuote()->getAllVisibleItems() as $_item) {
$product = Mage::getModel('catalog/product')->load($_item->getProduct()->getId());
/* Business Logic to decide if this item is relevent */
$discountItems[] = $_item;
}
// Calculate Discount
$appliedDiscounts = 0;
$discount = 0;
foreach ($discountitem as $_item) {
if ($appliedDiscounts < $allowed) {
$i = 0;
while ($appliedDiscounts < $allowed && $i < $_item->getQty()) {
$appliedDiscounts++;
$discount += $_item->getProduct()->getFinalPrice();
$i++;
}
}
}
return $discount;
}
1 answers
Поэтому на случай, если кто-нибудь столкнется с подобной проблемой в будущем, мне удалось выяснить, в чем была причина моей проблемы. Итоговые суммы сбора устанавливали флаг, из-за которого он не пересчитывался после применения скидки.
Mage::getSingleton('checkout/cart')
->getQuote()
->setCouponCode(strlen($couponCode) ? $couponCode : '')
->collectTotals()
->save();
Заменив вышеприведенное на:
Mage::getSingleton('checkout/cart')
->getQuote()
->setCouponCode(strlen($couponCode) ? $couponCode : '')
->save();
Это означает, что при попытке применить кредит клиента он пересчитывает общую сумму и получает право на оформление нулевого платежа.