回答:
あなたの質問に答えるために、3つの部分があります:
注文属性の作成
注文属性を作成するには、次のコードでセットアップスクリプトを使用する必要があります。
<?php
namespace Vendor\Module\Setup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Quote\Setup\QuoteSetupFactory;
use Magento\Sales\Setup\SalesSetupFactory;
class UpgradeData implements UpgradeDataInterface
{
/**
* @var QuoteSetupFactory
*/
protected $quoteSetupFactory;
/**
* @var SalesSetupFactory
*/
protected $salesSetupFactory;
/**
* @var EavSetupFactory
*/
protected $eavSetupFactory;
/**
* Constructor
*/
public function __construct(
QuoteSetupFactory $quoteSetupFactory,
SalesSetupFactory $salesSetupFactory,
EavSetupFactory $eavSetupFactory
) {
$this->quoteSetupFactory = $quoteSetupFactory;
$this->salesSetupFactory = $salesSetupFactory;
$this->eavSetupFactory = $eavSetupFactory;
}
/**
* {@inheritdoc}
*/
public function upgrade(
ModuleDataSetupInterface $setup,
ModuleContextInterface $context
) {
$setup->startSetup();
if (version_compare($context->getVersion(), '1.0.1', '<')) {
/** @var \Magento\Quote\Setup\QuoteSetup $quoteInstaller */
$quoteInstaller = $this->quoteSetupFactory->create(['resourceName' => 'quote_setup', 'setup' => $setup]);
/** @var \Magento\Sales\Setup\SalesSetup $salesInstaller */
$salesInstaller = $this->salesSetupFactory->create(['resourceName' => 'sales_setup', 'setup' => $setup]);
//Add attributes to quote
$entityAttributesCodes = [
'bank_name' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
];
foreach ($entityAttributesCodes as $code => $type) {
$quoteInstaller->addAttribute('quote', $code, ['type' => $type, 'length' => 255, 'visible' => true, 'nullable' => true,]);
$salesInstaller->addAttribute('order', $code, ['type' => $type, 'length' => 255, 'visible' => true, 'nullable' => true,]);
}
$setup->endSetup();
}
}
例としてアップグレードスクリプトを使用しましたが、inscriptを使用して同じ機能を実行することもできます。
注文時に属性を挿入
このプロセスは少しトリッキーですが、それでも問題はありません。
app/code/Vendor/Module/etc/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="bank_name" type="string"/>
</extension_attributes>
</config>
app/code/Vendor/Module/view/frontend/requirejs-config.js
次のコードでファイルを作成します。
var config = {
config: {
mixins: {
'Magento_Checkout/js/action/set-shipping-information': {
'Vendor_Module/js/order/set-shipping-information-mixin': true
}
}
}
};
app/code/Vendor/Module/view/frontend/web/js/order/set-shipping-information-mixin.js
次のコードで新しいファイルを作成します。
define([
'jquery',
'mage/utils/wrapper',
'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
'use strict';
return function (setShippingInformationAction) {
return wrapper.wrap(setShippingInformationAction, function (originalAction) {
var shippingAddress = quote.shippingAddress();
if (shippingAddress['extension_attributes'] === undefined) {
shippingAddress['extension_attributes'] = {};
}
// you can extract value of extension attribute from any place (in this example I use customAttributes approach)
shippingAddress['extension_attributes']['bank_name'] = jQuery('input[name="bank_name"]').val();
// pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
return originalAction();
});
};
});
ファイルを作成する app/code/Vendor/Module/view/frontend/layout/checkout_index_index.xml
<?xml version="1.0" encoding="UTF-8"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="before-form" xsi:type="array">
<item name="children" xsi:type="array">
<!-- Your form declaration here -->
<item name="custom-checkout-form-container" xsi:type="array">
<item name="component" xsi:type="string">Vendor_Module/js/view/order_attr</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Vendor_Module/order_attr</item>
</item>
<item name="children" xsi:type="array">
<item name="custom-checkout-form-fieldset" xsi:type="array">
<!-- uiComponent is used as a wrapper for form fields (its template will render all children as a list) -->
<item name="component" xsi:type="string">uiComponent</item>
<!-- the following display area is used in template (see below) -->
<item name="displayArea" xsi:type="string">custom-checkout-form-fields</item>
<item name="children" xsi:type="array">
<item name="bank_name" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
<item name="config" xsi:type="array">
<!-- customScope is used to group elements within a single form (e.g. they can be validated separately) -->
<item name="customScope" xsi:type="string">customCheckoutForm</item>
<item name="template" xsi:type="string">ui/form/field</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/input</item>
</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.bank_name</item>
<item name="label" xsi:type="string">Clearance Full Name</item>
<item name="sortOrder" xsi:type="string">1</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="string">true</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
app/code/Vendor/Module/view/frontend/web/template/order_attr.html
次のコードでファイルを作成します。
<div>
<form id="custom-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
<fieldset class="fieldset">
<legend data-bind="i18n: 'Clearance Info'"></legend>
<div><!-- ko i18n: 'This is clearance description' --><!-- /ko --></div>
<!-- ko foreach: getRegion('custom-checkout-form-fields') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</fieldset>
</form>
</div>
app/code/Vendor/Module/view/frontend/web/js/view/order_attr.js
次のコードでファイルを作成します。
define([
'Magento_Ui/js/form/form'
], function(Component) {
'use strict';
return Component.extend({
initialize: function () {
this._super();
// component initialization logic
return this;
},
/**
* Form submit handler
*
* This method can have any name.
*/
onSubmit: function() {
// trigger form validation
this.source.set('params.invalid', false);
this.source.trigger('customCheckoutForm.data.validate');
// verify that form data is valid
if (!this.source.get('params.invalid')) {
// data is retrieved from data provider by value of the customScope property
var formData = this.source.get('customCheckoutForm');
// do something with form data
console.dir(formData);
}
}
});
});
app/code/Vendor/Module/etc/di.xml
次のコードでファイルを作成します。
<?xml version="1.0" encoding="UTF-8"?>
<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-in-quote" type="Vendor\Module\Plugin\AddOrderAttrToQuote" sortOrder="10"/>
</type>
</config>
app/code/Vendor/Module/Plugin/AddOrderAttrToQuote.php
次のコードで新しいファイルを作成します。
<?php
namespace Vendor\Module\Plugin;
class AddOrderAttrToQuote
{
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
) {
$extAttributes = $addressInformation->getShippingAddress()->getExtensionAttributes();
$bank_name = $extAttributes->getBankName();
$quote = $this->quoteRepository->getActive($cartId);
$quote->setBankName($bank_name);
$extAttributes->setBankName("");
}
}
新しいファイルを作成 app/code/Cleargo/NewAttributes/etc/events.xml
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_model_service_quote_submit_before">
<observer name="handle_order_attrs" instance="Vendor\Module\Observer\HandleOrderAttrs" />
</event>
</config>
app/code/Vendor/Module/Observer/HandleOrderAttrs.php
次のコードで新しいファイルを作成します。
<?php
namespace Vendor\Module\Observer;
use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer;
class HandleOrderAttrs implements ObserverInterface
{
public function execute(Observer $observer)
{
$order = $observer->getOrder();
$quote = $observer->getQuote();
//Load the values
$bank_name = $quote->getData("bank_name");
$order->setData('bank_name', $bank_name)
->save();
}
}
支払いモジュールで注文属性を読み取る
ケース3の場合、サードパーティのモジュールからのものと思われます。とにかく、bank_name
注文の値を取得したい場合は、次のコードを使用できます。
$order->getData('bank_name')
結論
order属性に対して行うのはかなりの作業ですが、キーポイントを取得すると、すべてがスムーズになります。