Muszę dodać dwa niestandardowe pola na każdym etapie wysyłki i płatności na stronie kasy w Magento 2, a także dane powinny być zapisane w potrzebnych tabelach
jak to zrobić w Magento 2
Dzisiaj wyjaśnię, jak dodać niestandardowe pola do wszystkich kroków strony kasy i zapisać je po złożeniu zamówienia, a także jak używać zaksięgowanych danych po złożeniu zamówienia
1. pola delivery_date
: - gdzie klient poda datę dostawy na etapie wysyłki
Komentarze do drugiego pola Komentarze: - będą w kroku Płatności, a po złożeniu zamówienia komentarze zostaną dodane do historii komentarzy do zamówienia
Krok 1 : - upewnij się, że data dostawy jest dodana do wszystkich potrzebnych tabel, takich jak oferta, sales_order
oraz sales_order_grid
poprzez skrypt instalacyjny lub aktualizacyjny
<?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();
}
}
Krok 2 : - Dodanie niestandardowych pól w etapach wysyłki i płatności, możemy osiągnąć na dwa sposoby, jeden z nich, layout xml
a drugi to wtyczka poniżej to sposób dodawania pól poprzez wtyczkę
Tworzymy di.xml
plik w naszym module -Sugarcode/Deliverydate/etc/frontend/di.xml
Używamy obszaru interfejsu, aby utrzymać go w czystości, nasza wtyczka powinna działać tylko na interfejsie.
<?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;
}
}
Teraz wszystkie pola znajdują się na stronie kasy, teraz jak zapisać dane
w przeciwieństwie do M1 w M2, cała strona kasy jest całkowicie nokautem JS i API
Mamy dwa kroki, pierwszy z nich to wysyłka, a drugi to płatność, w której musimy zapisać oba pola
Poniżej znajduje się sposób zapisywania danych po zapisaniu adresów wysyłki
Krok wysyłki
Aby zapisać informacje o wysyłce w M2 używa
app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js
do przygotowania json
i wywołania, api
więc musimy zastąpić ten js, a po php
stronie nastąpi zapis
\ Magento \ Checkout \ Model \ ShippingInformationManagement :: SaveAddressInformation () i ShippingInformationManagement zaimplementowane przez Magento \ Checkout \ Api \ Data \ ShippingInformationInterface
M2 ma jedną potężną koncepcję zwaną extension_attributes
dynamiczną transmisją danych do podstawowych tabel, która pozwala to wykorzystać
krok 3 : - utwórz plikDeliverydate/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>
aby przesłonić js, utwórz plik js Deliverydate/view/frontend/requirejs-config.js
, musimy użyć 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 data_dostawy
/**
* @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();
});
};
});
Następnym krokiem jest zapisanie tych niestandardowych danych pola w wycenie. Zróbmy kolejną wtyczkę, dodając do naszego węzła xmletc/di.xml
<type name="Magento\Checkout\Model\ShippingInformationManagement">
<plugin name="save-in-quote" type="Sugarcode\Deliverydate\Plugin\Checkout\ShippingInformationManagementPlugin" sortOrder="10"/>
</type>
Utwórz plik Sugarcode \ Deliverydate \ Plugin \ Checkout \ ShippingInformationManagementPlugin.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);
}
}
wkrótce po przejściu do kroków płatności dane zostaną zapisane w tabeli ofert
aby zapisać te same dane po złożeniu zamówienia, musimy użyć zestawu pól
etc / 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>
Teraz pozwala zapisać pole Kroki płatności
jeśli mamy dodatkowe pola w kroku płatności i musimy opublikować te dane, musimy zastąpić inne js, tak jak zrobiliśmy to w kroku wysyłki
tak jak informacje o wysyłce, mamy informacje o płatności
ww może osiągnąć przez zastąpienie jest Magento_Checkout/js/action/place-order.js
(ale będzie miało problem, gdy zgoda jest włączona, więc musimy użyć mixin jako wzmianki o re)
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-assigner.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);
});
};
});
i musisz utworzyć wtyczkę dla Magento\Checkout\Model\PaymentInformationManagement
więc etc/di
dodaj poniższy kod
<type name="Magento\Checkout\Model\PaymentInformationManagement">
<plugin name="order_comments_save-in-order" type="Sugarcode\Deliverydate\Plugin\Checkout\PaymentInformationManagementPlugin" sortOrder="10"/>
</type>
a następnie utwórz plik 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;
}
}
Uwaga: - jeśli pole w kroku płatności musi zostać zapisane w tabeli wycen, użyj wtyczki „beofore” dla tej samej funkcji i postępuj zgodnie z instrukcją ShippingInformationManagementPlugin
Przed dostosowaniem wykonaj następujące czynności.
Krok 1: Utwórz implementację JS formularza interfejsu użytkownika
W swoim
<your_module_dir>/view/frontend/web/js/view/
katalogu utwórz plik .js implementujący formularz.Krok 2: Utwórz szablon HTML
Dodaj
knockout.js
szablon HTML dla komponentu formularza w<your_module_dir>/view/frontend/web/
katalogu szablonów.Przykład:
Wyczyść pliki po modyfikacji
Jeśli zmodyfikujesz niestandardowy szablon .html po zastosowaniu go na stronach sklepu, zmiany nie zostaną zastosowane, dopóki nie wykonasz następujących czynności:
Usuń wszystkie pliki z katalogów
pub/static/frontend
ivar/view_preprocessed
. Załaduj ponownie strony.Krok 3: Zadeklaruj formularz w układzie strony kasy
Aby dodać zawartość do kroku Informacje o wysyłce, utwórz
checkout_index_index.xml
aktualizację układu w<your_module_dir>/view/frontend/layout/
.Powinien być podobny do następującego.
Formy statyczne:
Poniższy przykładowy kod pokazuje konfigurację formularza zawierającego cztery pola: wprowadzanie tekstu, zaznaczanie, pole wyboru i datę. Ten formularz używa dostawcy danych do kasy (CheckoutProvider), który jest wprowadzony w module Magento_Checkout:
Mam nadzieję że to pomoże.
źródło