6

I have created a custom shipping method which allows delivery to a local office of the carrier. I have created a select when the shipping method is selected, so the user picks the office. Now I need to store the office ID to quote_address when it is provided.

I have managed to add that field to extension_attributes, so when the checkout form is submitted, this is passed to the back-end (@ http://website/rest/default/V1/guest-carts/e01f063c3b16e082b3546697e321e643/shipping-information:

sendJson

carrier_office in extension_attributes is what I need to save. I already created an install script, which creates a column in quote_address and its there in the database. I just need to save the value to it.

What I've done is first, I set up an extension field in in extension_attributes.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="carrier_office" type="string"/>
    </extension_attributes>
</config>

Then in di.xml I set up a plugin:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Vendor_Module\Api\OfficeManagementInterface" type="Vendor_Module\Model\OfficeManagement" />
    <preference for="Vendor_Module\Api\Data\OfficeInterface" type="Vendor_Module\Model\Office" />
    <type name="Magento\Quote\Model\ShippingAddressManagement">
        <plugin disabled="false" name="Creatizmo_Speedy_Plugin_Magento_Quote_Model_ShippingAddressManagement" sortOrder="10" type="Vendor_Module\Plugin\Magento\Quote\Model\ShippingAddressManagement"/>
    </type>
</config>

Where of course Vendor_Module is replaced with my module's name.

And then in Plugin/Magento/Quote/Model/ShippingAddressManagement:

namespace Vendor_Module\Plugin\Magento\Quote\Model;


class ShippingAddressManagement
{
    protected $logger;

    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->logger = $logger;
    }

    public function beforeAssign(
        \Magento\Quote\Model\ShippingAddressManagement $subject,
        $cartId,
        \Magento\Quote\Api\Data\AddressInterface $address
    ) {

        $extAttributes = $address->getExtensionAttributes();

        if (!empty($extAttributes)) {

            try {
                $address->setCarrierOffice($address->getCarrierOffice());
            } catch (\Exception $e) {
                $this->logger->critical($e->getMessage());
            }

        }

    }
}

In the last file I can see the extension attribute with the correct ID (if I dump it), but it's not saved. It seems $address->setCarrierOffice is not doing its thing or maybe it's not the right place for a hook.. I don't know

Any suggestions on what I'm doing wrong or what I should be doing are highly appreciated.

2
  • Hi i want add custom distance (warehosue to shipping address which i get from google api in scripts/helper class)variable/value to shipping address whenever address change or default address in shipping address.
    – sangan
    Commented Jan 4, 2018 at 6:55
  • wait, so $address get the attribute, and then you set the attribute back to $address? @@ I'm doing exactly like you but don't understand at all .. @@
    – fudu
    Commented Sep 14, 2018 at 7:18

3 Answers 3

3
+50

Seem that you're wrong when trying to get the carrier office code

$address->setCarrierOffice($address->getCarrierOffice());

It should be

$address->setCarrierOffice($extAttributes->getCarrierOffice());

The value is from extension attributes.

1
  • how does $extAttributes->getCarrierOffice() works? Commented Oct 17, 2019 at 8:57
1

Following a tutorial it used a helper method to transport the fields from extension attributes to another object via the getters and setters.

Within the Plugin e.g. Payment Information Management is the example I had. Their helper method could be used on the payment or shipping extension attributes.

{
    $extAttributes = $address->getExtensionAttributes();
    if (!empty($extAttributes)) {
        $this->helper->transportFieldsFromExtensionAttributesToObject(
            $extAttributes,
            $address,
            'extra_checkout_billing_address_fields'
        );
    }
}

In Helper/Data.php

public function transportFieldsFromExtensionAttributesToObject(
    $fromObject,
    $toObject,
    $fieldset='extra_checkout_billing_address_fields'
)
{
    foreach($this->getExtraCheckoutAddressFields($fieldset) as $extraField) {
        $set = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $extraField)));
        $get = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $extraField)));
        $value = $fromObject->$get();
        try {
            $toObject->$set($value);
        } catch (\Exception $e) {
            $this->logger->critical($e->getMessage());
        }
    }
    return $toObject;
}

Which amounts to the same thing Khoa TruongDinh said. Using the getters and setters to assign the value from the Extension Attributes into the object passed through to the quote/estimates.

$extAttributes = $address->getExtensionAttributes();
if (!empty($extAttributes)) {
    $this->helper->transportFieldsFromExtensionAttributesToObject(
        $extAttributes,
        $address,
        'extra_checkout_shipping_address_fields'
    );
}

The guide I was following was was a website but was more helpful to look at their code in git. https://codeblog.experius.nl/magento-2-add-extra-billing-or-shipping-field-to-the-checkout/

Github repo here: https://github.com/experius/Magento-2-Module-Experius-ExtraCheckoutAddressFields/blob/master/Plugin/Magento/Quote/Model/ShippingAddressManagement.php

However the values are still NULL when I look at them in shipping cost estimate but I may have somewhere else to set it for my use case as I am using a different module for customized shipping/carrier costs...

0

I'm not that familiar with extension attributes and more with custom attributes.

But looking at \Magento\Quote\Api\Data\AddressInterfaceyou might want to use

->setExtensionAttributes(\Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes);

You will need to construct the \Magento\Quote\Api\Data\AddressExtensionInterfaceand use that to set your extension attribute itself.

Again , not that familiar so its just a piece of information that i hope will help you out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.