I have added the drop-down custom field on checkout page with custom values.
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;
}
4 Answers 4
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.
-
but how can i pass custom attribute in require?Magento2 Devloper– Magento2 Devloper2018年03月26日 06:33:47 +00:00Commented Mar 26, 2018 at 6:33
-
What do you mean? You need to override the js file and add it to the getRules() functionhungersoft– hungersoft2018年03月26日 06:35:56 +00:00Commented Mar 26, 2018 at 6:35
-
I understand but how can I set it? like as getRules: function () { return { 'postcode': { 'required': true }, 'custom_attributes': { 'required': true } }; }Magento2 Devloper– Magento2 Devloper2018年03月26日 06:39:25 +00:00Commented Mar 26, 2018 at 6:39
-
No, you need to use the attribute code
mob_type.hungersoft– hungersoft2018年03月26日 06:43:07 +00:00Commented Mar 26, 2018 at 6:43 -
did but only four values passed in the address.Magento2 Devloper– Magento2 Devloper2018年03月26日 06:50:23 +00:00Commented Mar 26, 2018 at 6:50
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.
-
984 - but this position in how to get address values?Magento2 Devloper– Magento2 Devloper2018年05月29日 10:32:24 +00:00Commented May 29, 2018 at 10:32
-
@Magento2Devloper your comment isn't clear.Ahmed Kooli– Ahmed Kooli2018年05月30日 10:59:34 +00:00Commented May 30, 2018 at 10:59
-
it's means I am not getting custom filed values in address object and not in request objectMagento2 Devloper– Magento2 Devloper2018年05月30日 11:20:06 +00:00Commented May 30, 2018 at 11:20
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
}
-
This one solution is not working in magento2.2.x version getting json_decode error.Magento2 Devloper– Magento2 Devloper2019年02月05日 05:40:35 +00:00Commented Feb 5, 2019 at 5:40
-
Hi, this works but were you able to find solution in standard magento way? I am facing the same issue like in this posthardik malkani– hardik malkani2023年10月11日 09:43:53 +00:00Commented Oct 11, 2023 at 9:43
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.
-
But I need custom attribute value if mob_type == local set cost - 5ドル else 8ドル.Magento2 Devloper– Magento2 Devloper2018年04月01日 11:51:03 +00:00Commented Apr 1, 2018 at 11:51
-
That's why I need custom attribute value on request objectMagento2 Devloper– Magento2 Devloper2018年04月01日 11:51:34 +00:00Commented Apr 1, 2018 at 11:51
Explore related questions
See similar questions with these tags.
set-shipping-information-mixin.jsin your module?