3

I have added the drop-down custom field on checkout page with custom values.

enter image description here

InstallSchema.php

$connection->addColumn(
                $installer->getTable('quote_address'),
                'mob_type',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table ::TYPE_TEXT,
                    'nullable' => true,
                    'default' => NULL,
                    'length' => 255,
                    'comment' => 'Mob Type'
                ]
            );
        $connection->addColumn(
                $installer->getTable('sales_order_address'),
                'mob_type',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table ::TYPE_TEXT,
                    'nullable' => true,
                    'default' => NULL,
                    'length' => 255,
                    'comment' => 'Mob Type'
                ]
            );
        $installer->endSetup();

Plugin

use Magento\Checkout\Block\Checkout\LayoutProcessor;

class MobPlugin
{
    public function afterProcess(LayoutProcessor $subject, $jsLayout) {
        $customAttributeCode = 'mob_type';
        $customField = [
            'component' => 'Magento_Ui/js/form/element/select',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/select',
                'id' => 'drop-down',
            ],
            'dataScope' => 'shippingAddress.custom_attributes.mob_type',
            'label' => 'Mob Type',
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' => ['required-entry' => true],
            'sortOrder' => 150,
            'id' => 'drop-down',
            'options' => [
                [
                    'value' => 'local',
                    'label' => 'Local',
                ],
                [
                    'value' => 'vip',
                    'label' => 'VIP',
                ]
            ]
        ];

        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

        return $jsLayout;
    }
}

etc/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\ShippingInformationManagement">
        <plugin name="save_custom_field" type="Namespace\CustomModule\Plugin\Checkout\SaveAddressInformation" />
    </type>

</config>

SaveAddressInformation.php

class SaveAddressInformation
{
    protected $quoteRepository;
    public function __construct(
        \Magento\Quote\Model\QuoteRepository $quoteRepository
    ) {
        $this->quoteRepository = $quoteRepository;
    }
    /**
     * @param \Magento\Checkout\Model\ShippingInformationManagement $subject
     * @param $cartId
     * @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
     */
    public function beforeSaveAddressInformation(
        \Magento\Checkout\Model\ShippingInformationManagement $subject,
        $cartId,
        \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
    ) {
        $shippingAddress = $addressInformation->getShippingAddress();
    $shippingAddressExtensionAttributes = $shippingAddress->getExtensionAttributes();
    if ($shippingAddressExtensionAttributes) {
        $customField = $shippingAddressExtensionAttributes->getMobType();
        $shippingAddress->setMobType($customField);
    }

    }
}

But once click on shipping rate of radio button Magento call guest or user API to carrier model, In carrier model all request information passed but my custom attribute values not getting.

-module-offline-shipping\Model\Carrier\Flaterate.php

private function getShippingPrice(RateRequest $request, $freeBoxes)
    {
       echo $request->getMobType(); exit; // empty result
        $shippingPrice = false;

        $configPrice = $this->getConfigData('price');
        if ($this->getConfigData('type') === 'O') {
            // per order
            $shippingPrice = $this->itemPriceCalculator->getShippingPricePerOrder($request, $configPrice, $freeBoxes);
        } elseif ($this->getConfigData('type') === 'I') {
            // per item
            $shippingPrice = $this->itemPriceCalculator->getShippingPricePerItem($request, $configPrice, $freeBoxes);
        }

        $shippingPrice = $this->getFinalPriceWithHandlingFee($shippingPrice);

        if ($shippingPrice !== false && (
                $request->getFreeShipping() === true || $request->getPackageQty() == $freeBoxes
            )
        ) {
            $shippingPrice = '0.00';
        }
        return $shippingPrice;
    }
5
  • Do you mean, when you click "Next" button you lose your custom attribute on shipping address ? Do you have set-shipping-information-mixin.js in your module?
    – krybbio
    Apr 1 '18 at 3:31
  • yes. I did it. but I am not getting me value on request object. Apr 1 '18 at 5:44
  • Did you found solution for this? May 13 '21 at 14:01
  • @Magento2Devloper Have you found any solution
    – Pawankumar
    Jul 28 '21 at 14:36
  • @Ranganathan have you found any solution
    – Pawankumar
    Aug 6 '21 at 2:16
1

When you click on a specific shipping rate, all fields are not passed to the api call. It only passes the fields specified in the shipping rate validation rules JS.

You can find the file for FlatRate here:

vendor/magento/module-offline-shipping/view/frontend/web/js/shipping-rate-validation-rules/flatrate.js

Override that file and add your field there, that should send it to the shipping rates api call.

10
  • but how can i pass custom attribute in require? Mar 26 '18 at 6:33
  • What do you mean? You need to override the js file and add it to the getRules() function
    – hungersoft
    Mar 26 '18 at 6:35
  • I understand but how can I set it? like as getRules: function () { return { 'postcode': { 'required': true }, 'custom_attributes': { 'required': true } }; } Mar 26 '18 at 6:39
  • No, you need to use the attribute code mob_type.
    – hungersoft
    Mar 26 '18 at 6:43
  • did but only four values passed in the address. Mar 26 '18 at 6:50
1

It's not possible, Magento2 is hard coding the fields needed for collecting shipping methods here : /magento/module-quote/Model/Quote/Address.php line : 984

Magento2 design is not flexible [at all] and is over complicated.

3
  • 984 - but this position in how to get address values? May 29 '18 at 10:32
  • @Magento2Devloper your comment isn't clear. May 30 '18 at 10:59
  • it's means I am not getting custom filed values in address object and not in request object May 30 '18 at 11:20
1

I was having the exact same problem. In the end the only thing that worked for me was to get the POST data and use them to calculate the shipping rate cost. I will really glad to see how it should be done the "magento way"

$formpostdata = json_decode(file_get_contents('php://input'), true);
if (isset($formpostdata['address']['custom_attributes']['mob_type'])) {
    // add here your logic
}
1
  • This one solution is not working in magento2.2.x version getting json_decode error. Feb 5 '19 at 5:40
0

Flatrate->geShippingPrice() log:

[2018-04-01 09:25:48] main.DEBUG: Flatrate->getShippingPrice::Array
(
    [all_items] => Array
        (
            [0 (Magento\Quote\Model\Quote\Item)] => Array
                (
                    [item_id] => 134
                    [quote_id] => 138
                    [created_at] => 2018-04-01 09:15:02
                    [updated_at] => 0000-00-00 00:00:00
                    [product_id] => 3
                    [store_id] => 1
                    [is_virtual] => 0
                    [sku] => test
                    [name] => test
                    [is_qty_decimal] => 
                    [no_discount] => 0
                    [weight] => 0.0000
                    [qty] => 1
                    [price] => 10
                    [base_price] => 10
                    [discount_percent] => 0.0000
                    [discount_amount] => 0.0000
                    [base_discount_amount] => 0.0000
                    [tax_percent] => 0
                    [tax_amount] => 0
                    [base_tax_amount] => 0
                    [row_total] => 10
                    [base_row_total] => 10
                    [row_total_with_discount] => 0.0000
                    [row_weight] => 0
                    [product_type] => simple
                    [price_incl_tax] => 10
                    [base_price_incl_tax] => 10
                    [row_total_incl_tax] => 10
                    [base_row_total_incl_tax] => 10
                    [discount_tax_compensation_amount] => 0
                    [base_discount_tax_compensation_amount] => 0
                    [free_shipping] => 
                    [qty_options] => Array
                        (
                        )

                    [product (Magento\Catalog\Model\Product\Interceptor)] => Array
                        (
                            [entity_id] => 3
                            [attribute_set_id] => 4
                            [type_id] => simple
                            [sku] => test
                            [has_options] => 0
                            [required_options] => 0
                            [created_at] => 2018-03-12 15:09:32
                            [updated_at] => 2018-03-12 15:13:51
                            [price] => 10.0000
                            [weight] => 0.0000
                            [name] => test
                            [url_key] => test
                            [gift_message_available] => 2
                            [status] => 1
                            [visibility] => 4
                            [tax_class_id] => 2
                            [request_path] => test.html
                            [tier_price] => Array
                                (
                                )

                            [tier_price_changed] => 0
                            [store_id] => 1
                            [customer_group_id] => 0
                        )

                    [tax_class_id] => 2
                    [has_error] => 
                    [converted_price] => 10
                    [base_original_price] => 10.0000
                    [base_calculation_price] => 10
                    [tax_calculation_item_id] => sequence-1
                    [tax_calculation_price] => 10
                    [base_tax_calculation_price] => 10
                    [discount_calculation_price] => 10
                    [base_discount_calculation_price] => 10
                )

        )

    [dest_country_id] => IT
    [dest_region_code] => Stato/Provincia
    [dest_street] => Indirizzo
    [dest_city] => Città
    [dest_postcode] => 00000
    [package_value] => 10
    [package_value_with_discount] => 10
    [package_weight] => 0
    [package_qty] => 1
    [package_physical_value] => 10
    [free_method_weight] => 0
    [store_id] => 1
    [website_id] => 1
    [free_shipping] => 
    [base_currency (Magento\Directory\Model\Currency)] => Array
        (
            [currency_code] => EUR
        )

    [package_currency (Magento\Directory\Model\Currency)] => Array
        (
            [currency_code] => EUR
        )

    [base_subtotal_incl_tax] => 10
    [country_id] => US
    [region_id] => 12
    [postcode] => 90034
)

The only fields from Shipping address are:

[dest_country_id] => IT
[dest_region_code] => Stato/Provincia
[dest_street] => Indirizzo
[dest_city] => Città
[dest_postcode] => 00000

because they're needed to calculate shipping rates. So, unless your field affects shipping costs, you don't need it in $request object.

2
  • But I need custom attribute value if mob_type == local set cost - $5 else $8. Apr 1 '18 at 11:51
  • That's why I need custom attribute value on request object Apr 1 '18 at 11:51

Your Answer

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

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