0

I have to add custom attribute to /rest/default/V1/carts/mine/totals-information, so I found TotalsInformationInterface and I tried to add on this, but it is not working.

I am doing this because I have to override the shipping price to a custom one.

Here is what I got so far:

enter image description here

extension_attributes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Checkout\Api\Data\TotalsInformationInterface">
    <attribute code="selected_shipping" type="string"/>
</extension_attributes>

/etc/sales.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
<section name="quote">
    <group name="totals">
        <item name="shipping_amount" instance="MyModule\Model\Quote\Address\Total\CustomShippingPrice" sort_order="510"/>
    </group>
</section>

/view/frontend/web/js/model/cart/totals-processor/default.js

define([
'jquery',
'underscore',
'Magento_Checkout/js/model/resource-url-manager',
'Magento_Checkout/js/model/quote',
'mage/storage',
'Magento_Checkout/js/model/totals',
'Magento_Checkout/js/model/error-processor',
'Magento_Checkout/js/model/cart/cache',
'Magento_Customer/js/customer-data'
], function ($, _, resourceUrlManager, quote, storage, totalsService, errorProcessor, cartCache, customerData) {
'use strict';

/**
 * Load data from server.
 *
 * @param {Object} address
 */
var loadFromServer = function (address) {
    var serviceUrl,
        payload;

    // Start loader for totals block
    totalsService.isLoading(true);
    serviceUrl = resourceUrlManager.getUrlForTotalsEstimationForNewAddress(quote);
    payload = {
        addressInformation: {
            address: _.pick(address, cartCache.requiredFields),
            extension_attributes: {
                selected_shipping: $('[name="selected_shipping"]').val()
            }
        }
    };

    if (quote.shippingMethod() && quote.shippingMethod()['method_code']) {
        payload.addressInformation['shipping_method_code'] = quote.shippingMethod()['method_code'];
        payload.addressInformation['shipping_carrier_code'] = quote.shippingMethod()['carrier_code'];
    }

    storage.post(
        serviceUrl, JSON.stringify(payload), false
    ).done(function (result) {
        var data = {
            totals: result,
            address: address,
            cartVersion: customerData.get('cart')()['data_id'],
            shippingMethodCode: null,
            shippingCarrierCode: null
        };

        if (quote.shippingMethod() && quote.shippingMethod()['method_code']) {
            data.shippingMethodCode = quote.shippingMethod()['method_code'];
            data.shippingCarrierCode = quote.shippingMethod()['carrier_code'];
        }

        quote.setTotals(result);
        cartCache.set('cart-data', data);
    }).fail(function (response) {
        errorProcessor.process(response);
    }).always(function () {
        // Stop loader for totals block
        totalsService.isLoading(false);
    });
};

return {
    /**
     * Array of required address fields.
     * @property {Array.String} requiredFields
     * @deprecated Use cart cache.
     */
    requiredFields: cartCache.requiredFields,

    /**
     * Get shipping rates for specified address.
     * @param {Object} address
     */
    estimateTotals: function (address) {
        var data = {
            shippingMethodCode: null,
            shippingCarrierCode: null
        };

        if (quote.shippingMethod() && quote.shippingMethod()['method_code']) {
            data.shippingMethodCode = quote.shippingMethod()['method_code'];
            data.shippingCarrierCode = quote.shippingMethod()['carrier_code'];
        }

        if (!cartCache.isChanged('cartVersion', customerData.get('cart')()['data_id']) &&
            !cartCache.isChanged('shippingMethodCode', data.shippingMethodCode) &&
            !cartCache.isChanged('shippingCarrierCode', data.shippingCarrierCode) &&
            !cartCache.isChanged('address', address) &&
            cartCache.get('totals') &&
            !cartCache.isChanged('subtotal', parseFloat(quote.totals().subtotal))
        ) {
            quote.setTotals(cartCache.get('totals'));
        } else {
            loadFromServer(address);
        }
    }
};
});

MyModule\Model\Quote\Address\Total\CustomShippingPrice.php

<?php

namespace MyModule\Model\Quote\Address\Total;

use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Quote\Model\Quote\Address\FreeShippingInterface;


class CustomShippingPrice extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{
/**
 * @var PriceCurrencyInterface
 */
protected $priceCurrency;

/**
 * @var FreeShippingInterface
 */
protected $freeShipping;

/**
 * @param PriceCurrencyInterface $priceCurrency
 * @param FreeShippingInterface $freeShipping
 */
public function __construct(
    PriceCurrencyInterface $priceCurrency,
    FreeShippingInterface $freeShipping
)
{
    $this->priceCurrency = $priceCurrency;
    $this->freeShipping = $freeShipping;
    $this->setCode('shipping');
}

/**
 * Collect totals information about shipping
 *
 * @param \Magento\Quote\Model\Quote $quote
 * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
 * @param \Magento\Quote\Model\Quote\Address\Total $total
 * @return $this
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
 * @SuppressWarnings(PHPMD.NPathComplexity)
 * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
 */
public function collect(
    \Magento\Quote\Model\Quote $quote,
    \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
    \Magento\Quote\Model\Quote\Address\Total $total
)
{
    parent::collect($quote, $shippingAssignment, $total);

    $addressExtensionAttributes = $shippingAssignment->getShipping()->getExtensionAttributes();

    $amount = $quote->getShippingAddress()->getShippingAmount();
    $total->setShippingAmount(0);
    $total->setBaseShippingAmount(0);
    $total->setShippingAmount(0);
    $total->setShippingDescription("");

    return $this;
}

/**
 * This function will fetch the quote details
 *
 * @param Quote $quote quote
 * @param Total $total total
 *
 * @return array|null
 */
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
{
    $result = null;
    $amount = $total->getDiscountAmount();
    if ($amount != 0) {
        $description = $total->getDiscountDescription();
        $result = [
            'code' => $this->getCode(),
            'title' => $description,
            'value' => $amount
        ];
    }
    return $result;
}
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.