checkout page refresh issue
-
30-09-2020 - |
Question
First of all I want to give some screen shots to understand my issue.
Now I want to add related code here.
etc/frontend/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Model\CompositeConfigProvider">
<arguments>
<argument name="configProviders" xsi:type="array">
<item name="checkout_deliverysign_block" xsi:type="object">Kensium\DeliverySign\Model\DeliverySignConfigProvider</item>
</argument>
</arguments>
</type>
</config>
DeliverySignConfigProvider
<?php
namespace Kensium\DeliverySign\Model;
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Store\Model\ScopeInterface;
class DeliverySignConfigProvider implements ConfigProviderInterface
{
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
protected $scopeConfiguration;
protected $checkoutSession;
protected $logger;
/**
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration
* @codeCoverageIgnore
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration,
\Magento\Checkout\Model\Session $checkoutSession,
\Psr\Log\LoggerInterface $logger
)
{
$this->scopeConfiguration = $scopeConfiguration;
$this->checkoutSession=$checkoutSession;
$this->logger=$logger;
}
/**
* {@inheritdoc}
*/
public function getConfig()
{
$deliverySignConfig = [];
$enabled = $this->scopeConfiguration->getValue('deliverysign/deliverysign/status', ScopeInterface::SCOPE_STORE);
$minimumOrderAmount = $this->scopeConfiguration->getValue('deliverysign/deliverysign/minimum_order_amount', ScopeInterface::SCOPE_STORE);
$quote=$this->checkoutSession->getQuote();
$subtotal=$quote->getSubtotal();
$this->logger->addDebug($subtotal);
$deliverySignConfig['delivery_sign_amount'] = $this->scopeConfiguration->getValue('deliverysign/deliverysign/deliverysign_amount', ScopeInterface::SCOPE_STORE);
$deliverySignConfig['show_hide_deliverysign_block'] = ($enabled && ($minimumOrderAmount<$subtotal) && $quote->getFee()) ? true : false;
$deliverySignConfig['show_hide_deliverysign_shipblock'] = ($enabled && ($minimumOrderAmount<$subtotal)) ? true : false;
return $deliverySignConfig;
}
}
Please find below for more details
https://github.com/sivajik34/Delivery-Signature-Magento2
My observation is DeliverySignConfigProvider
object is not calling when you click next button,only its calling when you are reloading the page.
Can you anyone help me on this?
Solution
I think we don't need to reload the total summary. Because, when click the Next button, Magento will make a request(API) V1/carts/mine/shipping-information
to re-calculate the totals and output the totals data to our templates.
So, if we want to check the fee, we should check the response total_segments
When click Next to the payment step, there is a request to set shipping information vendor/magento/module-checkout/view/frontend/web/js/view/shipping.js
/**
* Set shipping information handler
*/
setShippingInformation: function () {
if (this.validateShippingInformation()) {
setShippingInformationAction().done(
function () {
stepNavigator.next();
}
);
}
}
This request will re-calculate the totals.
In your case, in our html template, it should have a isDisplayed()
function:
Kensium/DeliverySign/view/frontend/web/template/checkout/cart/totals/fee.html
<!-- ko if: isDisplayed() -->
<tr class="totals fee excl" data-bind="visible: canVisibleDeliverySignBlock">
<th class="mark" colspan="1" scope="row" data-bind="text: title"></th>
<td class="amount">
<span class="price" data-bind="text: getValue()"></span>
</td>
</tr>
<!-- /ko -->
Check isDisplayed()
function:
Kensium/DeliverySign/view/frontend/web/js/view/checkout/cart/totals/fee.js
define([
'ko',
'uiComponent',
'Magento_Checkout/js/model/quote',
'Magento_Catalog/js/price-utils',
'Magento_Checkout/js/model/totals'
], function (ko, Component, quote, priceUtils, totals) {
'use strict';
var show_hide_deliverysign_blockConfig = window.checkoutConfig.show_hide_deliverysign_block;
var delivery_sign_amount = window.checkoutConfig.delivery_sign_amount;
return Component.extend({
totals: quote.getTotals(),
canVisibleDeliverySignBlock: show_hide_deliverysign_blockConfig,
getFormattedPrice: ko.observable(priceUtils.formatPrice(delivery_sign_amount, quote.getPriceFormat())),
isDisplayed: function () {
return this.getValue() != 0;
},
getValue: function() {
var price = 0;
if (this.totals() && totals.getSegment('fee')) {
price = totals.getSegment('fee').value;
}
return this.getFormattedPrice(price);
}
});
});
This function will check the totals fee
segment from the response.
I make a git pull here.
NOTE: Make sure your fee is calculated right way. On the payment step, please check the response has our fee.
OTHER TIPS
You need to overwrite checkout 'payment-service.js' model class. You can do this following way:
#Kensium/DeliverySign/view/frontend/requirejs-config.js var config = { "map": { "*": { 'Magento_Checkout/js/model/shipping-save-processor/default': 'Kensium_DeliverySign/js/model/shipping-save-processor/default', 'Magento_Checkout/js/model/payment-service': 'Kensium_DeliverySign/js/model/payment-service' } } };
So create Kensium/DeliverySign/view/frontend/web/js/model/payment-service.js and content should be
/** * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ define( [ 'underscore', 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/payment/method-list', 'Magento_Checkout/js/action/select-payment-method', 'Magento_Checkout/js/model/totals' ], function (_, quote, methodList, selectPaymentMethod, totals) { 'use strict'; var freeMethodCode = 'free'; return { isFreeAvailable: false, /** * Populate the list of payment methods * @param {Array} methods */ setPaymentMethods: function (methods) { var self = this, freeMethod, filteredMethods, methodIsAvailable; freeMethod = _.find(methods, function (method) { return method.method === freeMethodCode; }); this.isFreeAvailable = freeMethod ? true : false; if (self.isFreeAvailable && freeMethod && quote.totals().grand_total <= 0) { methods.splice(0, methods.length, freeMethod); selectPaymentMethod(freeMethod); } filteredMethods = _.without(methods, freeMethod); if (filteredMethods.length === 1) { selectPaymentMethod(filteredMethods[0]); } else if (quote.paymentMethod()) { methodIsAvailable = methods.some(function (item) { return item.method === quote.paymentMethod().method; }); //Unset selected payment method if not available if (!methodIsAvailable) { selectPaymentMethod(null); } } methodList(methods); totals.isLoading(true); window.checkoutConfig.show_hide_deliverysign_block = 1; totals.isLoading(false); }, /** * Get the list of available payment methods. * @returns {Array} */ getAvailablePaymentMethods: function () { var methods = [], self = this; _.each(methodList(), function (method) { if (self.isFreeAvailable && ( quote.totals().grand_total 0 && method.method !== freeMethodCode ) || !self.isFreeAvailable ) { methods.push(method); } }); return methods; } }; } );
Delete pub/static/frontend/Magento/luma/en_US/Kensium_DeliverySign if already exist
Run following deploy command
php bin/magento setup:static-content:deploy
You should create also a session name on Delivery Sign.
So this would reload cart changes on each POST request to your controller. Basically, action node indicates controller path and section node defines which client-side content should be updated.
Caches have to be flushed for this change to apply.
Check Checkout/etc/frontend/sections.xml
For example a sections.xml
in etc/frontend
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
<action name="youraction/process/observer">
<section name="cart"/>
</action>
</config>