Tôi cần thêm hai trường tùy chỉnh trong mỗi bước vận chuyển và thanh toán của trang thanh toán trong Magento 2 và dữ liệu cũng cần được lưu trong các bảng cần thiết
Làm thế nào để làm điều đó trong Magento 2
Tôi cần thêm hai trường tùy chỉnh trong mỗi bước vận chuyển và thanh toán của trang thanh toán trong Magento 2 và dữ liệu cũng cần được lưu trong các bảng cần thiết
Làm thế nào để làm điều đó trong Magento 2
Câu trả lời:
Hôm nay tôi sẽ giải thích cách thêm các trường tùy chỉnh vào tất cả các bước của trang thanh toán và lưu nó sau khi đặt hàng và cũng như cách sử dụng dữ liệu được đăng sau khi đặt hàng
Các trường thứ nhất delivery_date
: - nơi khách hàng sẽ đề cập vào ngày giao hàng trong bước vận chuyển
Trường thứ 2 Nhận xét: - sẽ ở bước Thanh toán và sau khi đặt hàng, nhận xét này sẽ được thêm vào lịch sử nhận xét đơn hàng
Bước 1 : - đảm bảo Delivery_date được thêm vào trong tất cả các bảng cần thiết như trích dẫn sales_order
và sales_order_grid
thông qua cài đặt hoặc nâng cấp tập lệnh
<?php
namespace Sugarcode\Deliverydate\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
/**
* @codeCoverageIgnore
*/
class InstallSchema implements InstallSchemaInterface
{
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
$installer->getConnection()->addColumn(
$installer->getTable('quote'),
'delivery_date',
[
'type' => 'datetime',
'nullable' => false,
'comment' => 'Delivery Date',
]
);
$installer->getConnection()->addColumn(
$installer->getTable('sales_order'),
'delivery_date',
[
'type' => 'datetime',
'nullable' => false,
'comment' => 'Delivery Date',
]
);
$installer->getConnection()->addColumn(
$installer->getTable('sales_order_grid'),
'delivery_date',
[
'type' => 'datetime',
'nullable' => false,
'comment' => 'Delivery Date',
]
);
$setup->endSetup();
}
}
Bước 2 : - Thêm các trường tùy chỉnh trong các bước vận chuyển và thanh toán, chúng tôi có thể đạt được theo hai cách một layout xml
và một cách khác là plugin bên dưới là cách thêm các trường thông qua plugin
Chúng tôi tạo một di.xml
tệp trong mô-đun của chúng tôi -Sugarcode/Deliverydate/etc/frontend/di.xml
Chúng tôi sử dụng khu vực lối vào để giữ cho nó sạch sẽ, plugin của chúng tôi chỉ nên chạy trên lối vào.
<?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\Block\Checkout\LayoutProcessor">
<plugin name="add-delivery-date-field"
type="Sugarcode\Deliverydate\Model\Checkout\LayoutProcessorPlugin" sortOrder="10"/>
</type>
</config>
Sugarcode \ Plugin \ Checkout \ LayoutProcessor.php
<?php
namespace Sugarcode\Plugin\Checkout;
class LayoutProcessor
{
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
protected $scopeConfig;
/**
* @var \Magento\Checkout\Model\Session
*/
protected $checkoutSession;
/**
* @var \Magento\Customer\Model\AddressFactory
*/
protected $customerAddressFactory;
/**
* @var \Magento\Framework\Data\Form\FormKey
*/
protected $formKey;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory $agreementCollectionFactory,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Customer\Model\AddressFactory $customerAddressFactory
) {
$this->scopeConfig = $context->getScopeConfig();
$this->checkoutSession = $checkoutSession;
$this->customerAddressFactory = $customerAddressFactory;
}
/**
* @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
* @param array $jsLayout
* @return array
*/
public function afterProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
array $jsLayout
) {
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children']['before-form']['children']['delivery_date'] = [
'component' => 'Magento_Ui/js/form/element/abstract',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/date',
'options' => [],
'id' => 'delivery-date'
],
'dataScope' => 'shippingAddress.delivery_date',
'label' => 'Delivery Date',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'sortOrder' => 200,
'id' => 'delivery-date'
];
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['payments-list']['children']['before-place-order']['children']['comment'] = [
'component' => 'Magento_Ui/js/form/element/textarea',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'options' => [],
'id' => 'comment'
],
'dataScope' => 'ordercomment.comment',
'label' => 'Order Comment',
'notice' => __('Comments'),
'provider' => 'checkoutProvider',
'visible' => true,
'sortOrder' => 250,
'id' => 'comment'
];
return $jsLayout;
}
}
Bây giờ tất cả các trường trong trang thanh toán, bây giờ làm thế nào để lưu dữ liệu
không giống như M1 trong M2, tất cả trang Checkout hoàn toàn loại bỏ JS và API
Chúng tôi có hai bước đầu tiên là vận chuyển và bước thứ hai là thanh toán trong đó chúng tôi cần lưu cả hai trường
Dưới đây là cách lưu dữ liệu sau khi lưu địa chỉ giao hàng
Bước vận chuyển
Để lưu thông tin vận chuyển trong M2 sử dụng
app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js
để chuẩn bị json
và cuộc gọi api
vì vậy chúng tôi cần ghi đè js này và php
lưu bên sẽ xảy ra
\ Magento \ Checkout \ Model \ ShippingIn informationQuản lý :: SaveAddressIn information () và ShippingIn informationQuản lý được thực hiện bởi Magento \ Checkout \ Api \ Data \ ShippingIn informationInterface
M2 có một khái niệm mạnh mẽ được gọi extension_attributes
là dữ liệu động được sử dụng cho các bảng lõi cho phép nó sử dụng dữ liệu đó
bước 3 : - tạo tập tinDeliverydate/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="delivery_date" type="string"/>
</extension_attributes>
<extension_attributes for="Magento\Quote\Api\Data\PaymentInterface">
<attribute code="comment" type="string"/>
</extension_attributes>
</config>
để ghi đè js tạo tệp js Deliverydate/view/frontend/requirejs-config.js
chúng ta cần sử dụng mixns
var config = {
config: {
mixins: {
'Magento_Checkout/js/action/place-order': {
'Sugarcode_Deliverydate/js/order/place-order-mixin': true
},
'Magento_Checkout/js/action/set-payment-information': {
'Sugarcode_Deliverydate/js/order/set-payment-information-mixin': true
},
'Magento_Checkout/js/action/set-shipping-information': {
'Sugarcode_Deliverydate/js/order/set-shipping-information-mixin': true
}
}
};
js / order / set-Shipping-information-mixin.js deliver_date
/**
* @author aakimov
*/
/*jshint browser:true jquery:true*/
/*global alert*/
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']['delivery_date'] = jQuery('[name="delivery_date"]').val();
// pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
return originalAction();
});
};
});
Bước tiếp theo là lưu dữ liệu bài đăng trường tùy chỉnh này vào báo giá. Hãy tạo một plugin khác bằng cách thêm một nút xml vàoetc/di.xml
<type name="Magento\Checkout\Model\ShippingInformationManagement">
<plugin name="save-in-quote" type="Sugarcode\Deliverydate\Plugin\Checkout\ShippingInformationManagementPlugin" sortOrder="10"/>
</type>
Tạo một tập tin Sugarcode \ Deliveryydate \ Plugin \ Checkout \ ShippingIn informationQuản lýPlugin.php
<?php
namespace Sugarcode\Deliverydate\Plugin\Checkout;
class ShippingInformationManagementPlugin
{
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();
$deliveryDate = $extAttributes->getDeliveryDate();
$quote = $this->quoteRepository->getActive($cartId);
$quote->setDeliveryDate($deliveryDate);
}
}
Ngay sau khi bạn chuyển sang các bước thanh toán, dữ liệu sẽ được lưu trong bảng báo giá
để lưu cùng một dữ liệu sau khi đặt hàng, chúng ta cần sử dụng fieldset
vv / fieldset.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Object/etc/fieldset.xsd">
<scope id="global">
<fieldset id="sales_convert_quote">
<field name="delivery_date">
<aspect name="to_order"/>
</field>
</fieldset>
</scope>
</config>
Bây giờ, hãy lưu trường các bước thanh toán
nếu chúng tôi có thêm các trường trong bước thanh toán và chúng tôi cần đăng dữ liệu đó thì chúng tôi cần ghi đè các js khác như chúng tôi đã thực hiện cho bước vận chuyển
giống như thông tin vận chuyển, chúng tôi có thông tin thanh toán
ww có thể đạt được bằng cách ghi đè là Magento_Checkout/js/action/place-order.js
(nhưng nó sẽ có vấn đề khi kích hoạt thỏa thuận nên chúng tôi cần sử dụng mixins như được đề cập lại)
Sugarcode_Deliverydate/js/order/place-order-mixin.js
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'jquery',
'mage/utils/wrapper',
'Sugarcode_Deliverydate/js/order/ordercomment-assigner'
], function ($, wrapper, ordercommentAssigner) {
'use strict';
return function (placeOrderAction) {
/** Override default place order action and add comments to request */
return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, messageContainer) {
ordercommentAssigner(paymentData);
return originalAction(paymentData, messageContainer);
});
};
});
Sugarcode_Deliverydate / js / order / ordercomment-gáner.js
/*jshint browser:true jquery:true*/
/*global alert*/
define([
'jquery'
], function ($) {
'use strict';
/** Override default place order action and add comment to request */
return function (paymentData) {
if (paymentData['extension_attributes'] === undefined) {
paymentData['extension_attributes'] = {};
}
paymentData['extension_attributes']['comment'] = jQuery('[name="ordercomment[comment]"]').val();
};
});
Sugarcode_Deliverydate / js / order / set-Payment-information-mixin.js
/*jshint browser:true jquery:true*/
/*global alert*/
define([
'jquery',
'mage/utils/wrapper',
'Sugarcode_Deliverydate/js/order/ordercomment-assigner'
], function ($, wrapper, ordercommentAssigner) {
'use strict';
return function (placeOrderAction) {
/** Override place-order-mixin for set-payment-information action as they differs only by method signature */
return wrapper.wrap(placeOrderAction, function (originalAction, messageContainer, paymentData) {
ordercommentAssigner(paymentData);
return originalAction(messageContainer, paymentData);
});
};
});
và cần tạo một plugin cho Magento\Checkout\Model\PaymentInformationManagement
để etc/di
thêm mã dưới đây
<type name="Magento\Checkout\Model\PaymentInformationManagement">
<plugin name="order_comments_save-in-order" type="Sugarcode\Deliverydate\Plugin\Checkout\PaymentInformationManagementPlugin" sortOrder="10"/>
</type>
và sau đó tạo một tập tin Sugarcode\Deliverydate\Plugin\Checkout\PaymentInformationManagementPlugin.php
/**
* One page checkout processing model
*/
class PaymentInformationManagementPlugin
{
protected $orderRepository;
public function __construct(
\Magento\Sales\Api\OrderRepositoryInterface $orderRepository
) {
$this->orderRepository = $orderRepository;
}
public function aroundSavePaymentInformationAndPlaceOrder(
\Magento\Checkout\Model\PaymentInformationManagement $subject,
\Closure $proceed,
$cartId,
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
) {
$result = $proceed($cartId, $paymentMethod, $billingAddress);
if($result){
$orderComment =$paymentMethod->getExtensionAttributes();
if ($orderComment->getComment())
$comment = trim($orderComment->getComment());
else
$comment = '';
$history = $order->addStatusHistoryComment($comment);
$history->save();
$order->setCustomerNote($comment);
}
return $result;
}
}
Lưu ý: - nếu trường trong bước thanh toán cần lưu trong bảng báo giá thì hãy sử dụng plugin beofore cho cùng chức năng và thực hiện như đã làm trong ShippingIn informationManloymentPlugin
Trước khi thực hiện các tùy chỉnh, làm như sau.
Bước 1: Tạo triển khai JS của thành phần UI mẫu
Trong <your_module_dir>/view/frontend/web/js/view/
thư mục của bạn , tạo tệp .js thực hiện biểu mẫu.
/*global define*/
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);
}
}
});
});
Bước 2: Tạo mẫu HTML
Thêm knockout.js
mẫu HTML cho thành phần <your_module_dir>/view/frontend/web/
biểu mẫu trong thư mục mẫu.
Thí dụ:
<div>
<form id="custom-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
<fieldset class="fieldset">
<legend data-bind="i18n: 'Custom Checkout Form'"></legend>
<!-- ko foreach: getRegion('custom-checkout-form-fields') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</fieldset>
<button type="reset">
<span data-bind="i18n: 'Reset'"></span>
</button>
<button type="button" data-bind="click: onSubmit" class="action">
<span data-bind="i18n: 'Submit'"></span>
</button>
</form>
</div>
Xóa tập tin sau khi sửa đổi
Nếu bạn sửa đổi mẫu .html tùy chỉnh của mình sau khi được áp dụng trên các trang của cửa hàng, các thay đổi sẽ không được áp dụng cho đến khi bạn thực hiện các thao tác sau:
Xóa tất cả các tập tin trong pub/static/frontend
và var/view_preprocessed
thư mục. Tải lại các trang.
Bước 3: Khai báo biểu mẫu trong bố cục trang thanh toán
Để thêm nội dung vào bước Thông tin vận chuyển, hãy tạo checkout_index_index.xml
cập nhật bố cục trong phần<your_module_dir>/view/frontend/layout/
.
Nó sẽ tương tự như sau.
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Các dạng tĩnh:
Mẫu mã sau đây cho thấy cấu hình của biểu mẫu có chứa bốn trường: nhập văn bản, chọn, hộp kiểm và ngày. Biểu mẫu này sử dụng nhà cung cấp dữ liệu thanh toán (checkoutProvider) được giới thiệu trong mô-đun Magento_Checkout:
<item name="custom-checkout-form-container" xsi:type="array">
<item name="component" xsi:type="string">%your_module_dir%/js/view/custom-checkout-form</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">%your_module_dir%/custom-checkout-form</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="text_field" 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.text_field</item>
<item name="label" xsi:type="string">Text Field</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 name="checkbox_field" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</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/checkbox</item>
</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.checkbox_field</item>
<item name="label" xsi:type="string">Checkbox Field</item>
<item name="sortOrder" xsi:type="string">3</item>
</item>
<item name="select_field" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/select</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/select</item>
</item>
<item name="options" xsi:type="array">
<item name="0" xsi:type="array">
<item name="label" xsi:type="string">Please select value</item>
<item name="value" xsi:type="string"></item>
</item>
<item name="1" xsi:type="array">
<item name="label" xsi:type="string">Value 1</item>
<item name="value" xsi:type="string">value_1</item>
</item>
<item name="2" xsi:type="array">
<item name="label" xsi:type="string">Value 2</item>
<item name="value" xsi:type="string">value_2</item>
</item>
</item>
<!-- value element allows to specify default value of the form field -->
<item name="value" xsi:type="string">value_2</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.select_field</item>
<item name="label" xsi:type="string">Select Field</item>
<item name="sortOrder" xsi:type="string">2</item>
</item>
<item name="date_field" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/date</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/date</item>
</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.date_field</item>
<item name="label" xsi:type="string">Date Field</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="string">true</item>
</item>
</item>
</item>
</item>
</item>
</item>
Hi vọng điêu nay co ich.