Amasty_Rewards 1.5.0. Fixing a Checkout Bug

Share

Amasty provides a useful module, Amasty_Rewards, for store loyalty program. This extension lets administrators ability to configure rules for how customers will accrue Reward Points (usually for previously created orders). Customers can use these points to get discounts on future orders.

Let’s say you have a site on Magento 2 and this module has been working since its first version. After upgrading from Amasty 1.2.2 to 1.5.0, you’re pleased to see a new component for using points on the checkout page. Before, a customer could only set the desired number of points on the cart page, and a custom component was implemented for checkout. A custom component was immediately deleted since it would be no longer needed. However, a bug was identified in the component from Amasty. We describe it below.

Let’s say a customer has 100 points. In the configuration, a Point Rate of 20 is set, meaning 20 points translate to a $1 discount, and 1 point gives the customer a $0.05 discount. After submitting a form (using AJAX), the number of points in the form is changed to 0.05, and the text below the input field incorrectly says, “You have 99.95 points left,” while the discount amount is calculated correctly as $0.05.

Next, we will determine the cause of the bug and show how to fix it.

Investigating the Reason for the Bug at Checkout

The following was established after analyzing the component. The component itself is defined as follows:

Its main part is the Javascript file Amasty_Rewards/js/view/checkout/payment/rewards and the knockout template Amasty_Rewards/checkout/payment/rewards. There is also a child component that displays messages, but we aren’t considering it now. Below is the code for the files (knockout component and knockout template) mentioned above:

As you can see, the template has an input field and two buttons: “Apply Reward” and “Cancel Reward.” Only one of them is visible at any given time, depending on whether or not the user has entered a number of points to use. When the button is clicked, the component method applies or cancel is applied accordingly. Then the apply method calls the setRewardPointAction function, which is implemented in Amasty_Rewards/js/action/add-reward. This function passes the pointsUsed and pointsLeft variables as a knockout parameter. Let’s analyze the code of this function:

As you can see, the code sends a request to the server for applying points. Next, according to the response, getPaymentInformation() is called to get updates to totals and methods of payment. Then, for some reason, the discount_amount value received is recorded as the number of points used. This would be accurate if the customer received a $1 discount for 1 point; however, when the customer gets only $0.05 for 1 point (see the previously-configured discount calculation rule) this logic is incorrect. It seems that Amasty did not consider this case. It would be more logically sound to receive the number of used and remaining points from the server, but Amasty decided not to implement a separate controller to do this, which would have returned JSON. In any event, the problem must be solved.

Fixing the Checkout Bug in Amasty_Rewards 1.5.0 and 1.6.0

This fix is made up of two parts: a server part and a browser part. In Magento 2, the totals class implements the Magento\Quote\Api\Data\TotalsInterface interface and supports extension attributes. Since we don’t need to save the extension attributes on the server side and use the built-in attribute joiner, we define a new extension attribute as follows (extension_attributes.xml file).

As you can see, the information about points used and remaining was successfully added to the totals extension attribute and is passed to the front end. Now we have to process this information on the front end. This is where we ran into some difficulties. The knockout variables pointsUsed and pointsLeft aren’t visible outside the Amasty component, and as such, it isn’t possible to redefine the method that uses them. It’s also difficult to replace the Amasty_Rewards/js/action/add-reward function. To fix this problem, we can create event handlers for changing the knockout variables. The totals variable of the componentMagento_Checkout/js/model/totals is one of these variables.

We replace the component’s Javascript file using the layout file checkout_index_index.xml.

As you can see, we implemented an event handler for changing totals. However, that’s not enough. Immediately after executing the handler for changing totals, the callback from Amasty_Rewards/js/action/add-reward is executed, and the value of the knockout variables changes. The incorrect values are also displayed in the browser. But since the code above in Amasty_Rewards/js/action/add-reward also initializes the message for the messages child component, we can use its knockout variable to create a handler. This will also allow us to display the correct message about the client’s points. The self.initialize() call sets the required values for the knockout variables from the parent code.

We also must note that this bug in the Amasty_Rewards module wasn’t fixed in Amasty version 1.6.0, but the resolution described above only works for Magento versions 2.2.4 and later. When installing Amasty_Rewards 1.6.0 on Magento 2.2.3, the component installed threw a Javascript error on the checkout page in the browser console: “reward.js:10 Uncaught TypeError: Cannot read property ‘reward’ of undefined”

The cause of this problem is on the back end. What happened is that starting with some version, the Amasty_Rewards module depends on Amasty_Conditions, but in Amasty_Conditions the plugin was implemented in Magento\Quote\Model\Cart\CartTotalRepository the following way:

As you can see, this plugin checks the Magento version, and for versions less than 2.2.4 it implements its own code, blocking the execution of further plugins. As such, the extension attribute implemented in our plugin doesn’t even have the chance to be defined and passed to the front end. We understand why this plugin was implemented. The CartTotalRepository class had a completely different implementation until version 2.2.4, and this could create problems for a full cross-version implementation of the Amasty extension. In any event, we had to correct the above error of passing the extension attribute to the front end in case, for some reason, it isn’t possible to upgrade to newer versions of Magento. This can be done by adding the following plugin:

Summary

As stated above, you must install a plugin for Magento 2.2.3 in order for the extension attribute to be passed correctly to the front end and the points to be calculated accurately. However, keep in mind that our solution was checked on versions 2.2.3 – 2.2.5 of Magento and 1.6.0 of the Amasty_Rewards module. It has not been confirmed to work on other versions.

Choose Our Team!

We are here to give you a hand and provide experts in web development and design. Tell us about your needs, ideas, and requirements – we are ready to take a task. Drop us a line, and it will be a perfect beginning for our partnership. Let’s get it started!

Custom Web Development

Frontend Development

Do you have a question?

Or do you want to talk and share some news? We’ll be glad to communicate with you and clarify all you need. Feel free to contact us anytime, and we’ll reply as soon as possible.
Let’s get acquainted and be partners. We’ll be happy to keep in touch with you.