我遇到了Magento单一优惠券代码的问题,该代码被标记为在客户点击下订单按钮时使用。如果Paypal付款失败或客户在订单完成之前离开页面,他将无法返回并重新订购此优惠券,该优惠券设置为仅使用一次,并且已被标记已使用过。< / p>
我找到了一段代码,减少了优惠券被用户使用的次数,并允许他重复使用优惠券。不幸的是,他在单击下订单按钮时尝试连接Paypal页面时出错。为了能够再次使用优惠券并访问Paypal页面,我必须使用此客户的ID删除表 salesrule_coupon_usage 和 salesrule_customer 中SQL数据库中的行。
以下是我需要更改以自动删除客户ID的优惠券使用信息的代码:
public function cancel($observer)
{
$order = $observer->getEvent()->getPayment()->getOrder();
if ($order->canCancel()) {
if ($code = $order->getCouponCode()) {
$coupon = Mage::getModel('salesrule/coupon')->load($code, 'code');
if ($coupon->getTimesUsed() > 0) {
$coupon->setTimesUsed($coupon->getTimesUsed() - 1);
$coupon->save();
}
$rule = Mage::getModel('salesrule/rule')->load($coupon->getRuleId());
error_log("\nrule times used=" . $rule->getTimesUsed(), 3, "var/log/debug.log");
if ($rule->getTimesUsed() > 0) {
$rule->setTimesUsed($rule->getTimesUsed()-1);
$rule->save();
}
if ($customerId = $order->getCustomerId()) {
if ($customerCoupon = Mage::getModel('salesrule/rule_customer')->loadByCustomerRule($customerId, $rule->getId())) {
$couponUsage = new Varien_Object();
Mage::getResourceModel('salesrule/coupon_usage')->loadByCustomerCoupon($couponUsage, $customerId, $coupon->getId());
if ($couponUsage->getTimesUsed() > 0) {
/* I can't find any #@$!@$ interface to do anything but increment a coupon_usage record */
$resource = Mage::getSingleton('core/resource');
$writeConnection = $resource->getConnection('core_write');
$tableName = $resource->getTableName('salesrule_coupon_usage');
$query = "UPDATE {$tableName} SET times_used = times_used-1 "
. "WHERE coupon_id = {$coupon->getId()} AND customer_id = {$customerId} AND times_used > 0";
$writeConnection->query($query);
}
if ($customerCoupon->getTimesUsed() > 0) {
$customerCoupon->setTimesUsed($customerCoupon->getTimesUsed()-1);
$customerCoupon->save();
}
}
}
}
}
}
答案 0 :(得分:1)
我相信这是一个从1.4到1.6左右的旧bug。但是,无论你是否有旧版本,如果你知道你在Magento周围的方式,这可以很容易地修复。
问题是,您有代码在点击付款按钮时更新salesrule_coupon_usage表。这根本不是你想要的。您希望将其包含在付款交易中。我不知道这个错误是否发生,因为你有自定义代码或者使用旧版本的Magento,但我会告诉你我将如何解决这个问题。然后我会给你一个类似你提议的修复:
Magento已经有了一个叫做“交易”的抽象概念。事务用于放置和组合对象,这些对象需要全部成功或全部失败,没有半量级。 Magento将完成交易并尝试保存您放入其中的每个对象。如果其中任何一个失败(例如,付款未通过),则已经保存的所有事件都将“回滚”。
幸运的是,Magento已经创建了一个交易对象来处理在成功付款时需要一起更新的各种事情的付款。您可以使用该交易并使用它来正确更新优惠券使用情况。
以下是您需要做的10000英尺视图。
你做完了。事务将自动尝试保存已添加到其中的所有对象。如果任何部分失败(包括付款失败),它将回滚整个过程并且您的优惠券将不会被使用。好极了!
现在,在我看来,以上是解决问题的最佳方法,但如果您因某些原因遇到问题,可以选择基于捕获不成功的付款然后使用您的代码。
再次,这是10,000英尺的视图:
现在,当销售失败时,您将返回并手动展开所有内容。这不像我的第一个解决方案那么干净,但根据您对Magento的熟悉程度,对您来说可能更容易。
我很确定Magento新的,干净的版本没有这个问题,所以让我提供一个相当明显的建议作为第三个解决方案。