15

顧客が [注文する] ボタンをクリックした時点で使用済みとしてマークされている Magento シングル クーポン コードに問題があります。Paypal での支払いが失敗した場合、またはクライアントが注文が完了する前にページを離れた場合、クライアントは、一度だけ使用するように設定され、既に使用済みとマークされているこのクーポンで戻って再注文することはできません.

ユーザーがクーポンを使用する回数を減らし、クーポンを再利用できるようにするコードを見つけました。残念ながら、注文ボタンをクリックして Paypal ページに接続しようとすると、エラーが発生します。もう一度クーポンを使用して Paypal ページにアクセスできるようにするには、テーブルsalesrule_coupon_usagesalesrule_customerの SQL データベースの行を、この顧客 ID で削除する必要があります。

顧客 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();
                    }
                }
            }
        }
    }
}
4

1 に答える 1

1

これは 1.4 からおそらく 1.6 までの古いバグだったと思います。ただし、古いバージョンを使用しているかどうかに関係なく、Magento の使い方を知っていれば、これはかなり簡単に修正できます。

問題は、支払いボタンをクリックした直後に salesrule_coupon_usage テーブルを更新するコードがあることです。これはあなたが本当に望んでいるものではありません。これを支払いトランザクションにラップする必要があります。このバグがカスタム コードを持っているためなのか、古いバージョンの Magento を使用しているために発生しているのかはわかりませんが、問題を解決する方法を説明します。次に、あなたが提案したものと同様の修正を提供します。

Magento にはすでに「トランザクション」と呼ばれる抽象化があります。トランザクションは、すべて成功するかすべて失敗する必要があるオブジェクトをまとめてグループ化するために使用されます。Magento はトランザクションを実行し、そこに配置した各オブジェクトを保存しようとします。それらのいずれかが失敗した場合 (たとえば、支払いが完了しない場合)、既に保存されているすべてのイベントが "ロールバック" されます。

幸いなことに、Magento は、支払いが成功したときに一緒に更新する必要があるさまざまなものの支払いを処理するためのトランザクション オブジェクトを既に作成しています。そのトランザクションを利用して、クーポンの使用状況を正しく更新するために使用できます。

これが、何をする必要があるかの 10,000 フィート ビューです。

  • salesrule_coupon_usage テーブルの更新が早す​​ぎるものを見つけて削除します。独自のトランザクション セーフ バージョンを追加するので、他の場所に保存したくありません。これを行う最も簡単な方法は、どのモデルがそのテーブルに接続されているかを把握し、そのモデルの作成を検索することです。1.7 および 1.8 では、これがルール/顧客モデルです。
  • 支払いトランザクションの開始をキャッチするオブザーバーを作成します。Magento の最新バージョンでは、このイベントは sales_order_payment_place_start と呼ばれ、app/code/core/Mage/Sales/Model/Order/Payment.php で確認できます。
  • イベントから注文を引き出し、イベントからクーポンコードを引き出します。
  • 更新する実際のモデルをプルします。誰かがあなたのコードでそれを見つけられなかったようですが、salesrule_coupon_usage テーブルを使用するモデルがどこかに隠れているはずです。.xml ファイルで「salesrule_coupon_usage」を検索し、そのテーブルを使用しているモデルを確認します。繰り返しますが、私にとって 1.7 では、それがルール/顧客モデルです。
  • そのモデルをロードし、顧客がクーポン コードに関係する値を変更して、顧客がクーポンを使用したことを示しますが、まだ保存しないでください。
  • イベントからトランザクションを取得し、更新したクーポン オブジェクトを addObject メソッドに登録します。

そして、あなたの完了。トランザクションは、追加されたすべてのオブジェクトを自動的に保存しようとします。いずれかの部分が失敗した場合 (支払いの失敗を含む)、プロセス全体がロールバックされ、クーポンは使用されません。わーい!

さて、私の意見では、上記が問題を処理する最善の方法ですが、何らかの理由で問題が発生している場合は、失敗した支払いを見つけてからコードを使用することに基づく代替手段があります.

繰り返しますが、ここに 10,000 フィート ビューがあります。

  • 失敗した支払いイベントをキャッチするオブザーバーを作成します。ほとんどのバージョンでは、必要なイベントは sales_order_payment_cancel です。
  • あなたが持っているコードを実行してください...それはそれを行うはずです。しかし、他の人のために明確にするために:
    • イベントから注文を取り出し、そこからクーポン コードと顧客 ID を取り出します。
    • customer、rule、および salesrule_coupon_usage テーブルを更新します。(実際にはそのためのモデルがあるはずですが、それを見つけることができると確信しています)

販売が失敗した場合は、戻って手動ですべてを巻き戻します。これは私の最初の解決策ほどきれいではありませんが、Magento に精通している場合は、より簡単になる可能性があります。

Magento の新しくクリーンなバージョンにはこの問題がないと確信しているので、3 番目の解決策としてかなり明白な提案をさせてください。

  • マジェントを更新する
  • Magento が最新の場合は、何かが壊れているため、カスタム モジュールを無効にしてテストします。Amasty クーポン プラグインには特にバグがあることに気付きました。
  • Magento コアに独自の変更を加えた場合は、頑張ってください。

幸運を!

于 2014-01-19T07:51:12.350 に答える