Magento 2 - Cách thêm trường tùy chỉnh để thanh toán và sau đó gửi nó


49

Tất cả các hướng dẫn chỉ bao gồm thêm một trường, nhưng việc lưu giá trị của tệp này được bỏ qua #mindblown. Tôi không biết tại sao, đó là phần quan trọng nhất của việc thêm bất kỳ trường hoặc biểu mẫu nào.

Tôi đã cố làm theo tài liệu Magento , nhưng ... nó thật tệ.

Đối với mục đích thử nghiệm, tôi cố gắng thêm các trường khác vào địa chỉ giao hàng, chỉ cần bỏ qua phạm vi tùy chỉnh, bộ dữ liệu tùy chỉnh, nhà cung cấp dữ liệu tùy chỉnh và các công cụ không có giấy tờ khác, có vẻ quá kỳ lạ đối với tôi.

Tôi không biết ý nghĩa của hình thức đó là "tĩnh" hay "động". Đối với tôi, tất cả các hình thức thanh toán đều được xây dựng linh hoạt trên các mẫu KnockoutJS, nhưng ... khi tôi thử cách "tĩnh", tôi có thể thêm đầu vào ở đây (vì vậy nó có phải là dạng tĩnh hay không?).

Đầu tiên tôi cố gắng gỡ lỗi tại sao các thiết bị quan sát Knockout chỉ bỏ qua các trường của tôi trong quá trình phân tích và gửi dữ liệu. Tôi thấy rằng các trường của tôi có nametham số trống , nhưng tôi không thể quản lý cách khắc phục vấn đề này. IMO nên được chuyển đến trình kết xuất thành phần UI thông qua inputNametham số, giống như bất kỳ tùy chọn nào khác disabled, placeholderv.v. (các tham số khác hoạt động tốt, tôi đã kiểm tra cấu hình được tạo từ XML của mình để kiểm tra khởi tạo mô-đun và có vẻ tốt cho tôi)

Thứ hai, tôi đã cố gắng sử dụng cách "động" với việc tạo plugin với LayoutProcessorvà truyền chính xác cùng một dữ liệu ... và bây giờ tôi có các trường có names, nhưng gửi vẫn không hoạt động.

Sau khi đào sâu vào JS tôi thấy rằng việc chuẩn bị yêu cầu này được duy trì trong module-checkout/view/frontend/web/js/model/shipping-save-processor/default.jstệp, điều này phụ thuộc vào module-checkout/view/frontend/web/js/model/quote.jsnơi mà các quan sát Knockout được xác định / tạo.

Bằng cách nào đó module-checkout/view/frontend/web/js/model/address-converter.jscập nhật các quan sát này và phụ thuộc vào module-checkout/view/frontend/web/js/model/new-customer-address.js, nơi cuối cùng tôi đã tìm thấy một số tùy chọn cấu hình thú vị - danh sách tất cả các trường địa chỉ.

Khi tôi thêm các trường của mình vào đây, các tập lệnh bắt đầu phân tích cú pháp và gửi chúng, OFC tôi nhận được 500, b / c phụ trợ không nhận ra chúng ... (đừng hỏi, tôi không phải là nhà phát triển phụ trợ)

Vì vậy, đây là câu hỏi của tôi:

  • Đó là một cách đúng đắn để xử lý loại tùy chỉnh này? (b / c có vẻ kỳ lạ đối với tôi)
  • Làm cách nào để gửi giá trị của các trường không liên quan đến địa chỉ mới? Tôi không thấy cấu hình tương tự ở bất cứ đâu. Trong trường hợp của tôi, tôi muốn gửi bình luận đơn hàng (textarea) và yêu cầu hóa đơn (hộp kiểm). Cả hai không nên được lưu dưới dạng địa chỉ, vì một số người dùng có thể muốn lưu địa chỉ này để sử dụng trong tương lai.
  • Có tài liệu nào về các hình thức "tĩnh" và "động" hoặc một số ví dụ / so sánh không? Nó đáng để suy nghĩ về nó theo cách này?

Câu hỏi hiện sinh bổ sung:

  • Tại sao điều này là không phù hợp? Tại sao tôi phải xác định hàng tấn tham số trong các tệp XML / PHP, trong khi Magento hoàn toàn chỉ có thể hiển thị đầu vào và sau đó tôi phải tự xử lý mọi thứ?

3
Magento Devdocs gần đây đã thêm một số tài liệu mới về việc sử dụng Thành phần UI. Chúng tôi thực sự đang trong quá trình viết một hướng dẫn hoàn toàn mới ... nhưng vẫn có cách để đi. Vui lòng xem tại devdocs.magento.com/guides/v2.1/ui_comp_guide/bk-ui_comps.html . Thật không may, chúng tôi chưa hoàn thành các chủ đề trên các nguồn dữ liệu, đó là những gì có vẻ như bạn chủ yếu cần. Có một chủ đề về luồng cấu hình sử dụng Thành phần UI, có thể giúp ích. Tôi sẽ làm việc để tìm thêm câu trả lời.
tanberry

Tại sao nó phải là một cơn ác mộng khi thêm một lĩnh vực đơn giản vào thanh toán? Tôi không thể hiểu được. Và hầu hết mọi thứ đều khó khăn như vậy
slayerbleast

@slayerbleast Thế giới đang thay đổi, kết xuất phía máy chủ sắp chết. Vì vậy, nó khác nhau, không khó hơn mà không có lý do.
igloczek

Câu trả lời:


55

Tôi sẽ cố gắng trả lời (các) câu hỏi của bạn.

  1. Không . Đây không phải là một cách chính xác để thêm các thuộc tính tùy chỉnh vào mẫu địa chỉ giao hàng. Bạn không cần chỉnh sửa new-customer-address.js. Thật vậy, tệp JS này liệt kê tất cả các thuộc tính địa chỉ được xác định trước và khớp với giao diện phụ trợ tương ứng, \Magento\Quote\Api\Data\AddressInterfacenhưng Magento cung cấp khả năng chuyển bất kỳ thuộc tính tùy chỉnh nào sang phụ trợ mà không sửa đổi các thành phần phụ trợ / giao diện .

    Thành phần JS được đề cập có thuộc customAttributestính. Thuộc tính tùy chỉnh của bạn sẽ được xử lý tự động nếu chúng $dataScopePrefixlà ' shippindAddress.custom_attributes'.

  2. Nếu tôi hiểu chính xác câu hỏi của bạn, bạn có dữ liệu không phải là một phần của địa chỉ khách hàng nhưng bạn cũng cần gửi nó đến phụ trợ. Câu trả lời cho câu hỏi này là:

    Nó phụ thuộc . Chẳng hạn, bạn có thể chọn cách tiếp cận sau: thêm biểu mẫu tùy chỉnh vào trang thanh toán bao gồm tất cả các trường bổ sung của bạn (like comment, invoice request etc) , thêm logic JS sẽ xử lý biểu mẫu này dựa trên một số sự kiện và cung cấp dịch vụ tùy chỉnh sẽ nhận dữ liệu từ frontend và lưu trữ nó ở đâu đó để sử dụng trong tương lai.

  3. Tất cả các tài liệu chính thức liên quan đến thanh toán được đặt tại http://devdocs.magento.com/guides/v2.1/howdoi/checkout/checkout_overview.html . Thuật ngữ tĩnh dùng để chỉ các biểu mẫu trong đó tất cả các trường đã được biết / được xác định trước (ví dụ: biểu mẫu sẽ luôn có 2 trường văn bản có nhãn được xác định trước) và không thể thay đổi dựa trên một số cài đặt trong phần phụ trợ.

    Các hình thức như vậy có thể được tuyên bố bằng cách sử dụng layout XML configuration. Mặt khác, thuật ngữ động đề cập đến các biểu mẫu có bộ trường có thể thay đổi (ví dụ: biểu mẫu thanh toán có thể có nhiều / ít trường hơn dựa trên cài đặt cấu hình).

    Trong trường hợp này, cách duy nhất để khai báo dạng đó là sử dụng LayoutProcessorplugin.

  4. :) Magento cố gắng bao gồm càng nhiều trường hợp sử dụng có thể có ý nghĩa đối với các thương nhân trong quá trình sử dụng / tùy chỉnh Magento càng tốt. Đôi khi điều này dẫn đến tình huống khi một số trường hợp sử dụng đơn giản trở nên phức tạp hơn.

Hi vọng điêu nay co ich.

================================================== =======================

OK ... Hãy viết một số mã;)

  1. Mã PHP chèn trường bổ sung trong LayoutProcessor

========

/**
 * @author aakimov
 */
$customAttributeCode = 'custom_field';
$customField = [
    'component' => 'Magento_Ui/js/form/element/abstract',
    'config' => [
        // customScope is used to group elements within a single form (e.g. they can be validated separately)
        'customScope' => 'shippingAddress.custom_attributes',
        'customEntry' => null,
        'template' => 'ui/form/field',
        'elementTmpl' => 'ui/form/element/input',
        'tooltip' => [
            'description' => 'Yes, this works. I tested it. Sacrificed my lunch break but verified this approach.',
        ],
    ],
    'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
    'label' => 'Custom Attribute',
    'provider' => 'checkoutProvider',
    'sortOrder' => 0,
    'validation' => [
       'required-entry' => true
    ],
    'options' => [],
    'filterBy' => null,
    'customEntry' => null,
    'visible' => true,
];

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

return $jsLayout;

Như tôi đã đề cập, điều này sẽ thêm trường của bạn vào customAttributesthuộc tính của đối tượng địa chỉ JS. Thuộc tính này được thiết kế để chứa các thuộc tính địa chỉ EAV tùy chỉnh và có liên quan đến \Magento\Quote\Model\Quote\Address\CustomAttributeListInterface::getAttributesphương thức.

Mã ở trên sẽ tự động xử lý lưu trữ cục bộ lưu trữ trên frontend. Bạn có thể nhận được giá trị lĩnh vực của bạn từ lưu trữ địa phương sử dụng checkoutData.getShippingAddressFromData()(trong đó checkoutDataMagento_Checkout/js/checkout-data).

  1. Thêm mixin để thay đổi hành vi của 'Magento_Checkout / js / action / set-Shipping-information' (thành phần này chịu trách nhiệm gửi dữ liệu giữa các bước kiểm tra vận chuyển và thanh toán)

========

2.1. Tạo nênyour_module_name/view/frontend/requirejs-config.js


/**
 * @author aakimov
 */
var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                '<your_module_name>/js/action/set-shipping-information-mixin': true
            }
        }
    }
};

2.2. Tạo your_module_name / view / frontend / web / js / action / set-Shipping-information-mixin.js


/**
 * @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']['custom_field'] = shippingAddress.customAttributes['custom_field'];
            // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
            return originalAction();
        });
    };
});
  1. Tạo your_module_name / etc / extension_attribut.xml

========

<?xml version="1.0"?>
<!--
/**
 * @author aakimov
 */
-->
<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="custom_field" type="string" />
    </extension_attributes>
</config>

Điều này sẽ thêm một thuộc tính mở rộng cho mô hình địa chỉ ở phía phụ trợ. Thuộc tính mở rộng là một trong những điểm mở rộng mà Magento cung cấp. Để truy cập dữ liệu của bạn vào phụ trợ, bạn có thể sử dụng:

// Magento will generate interface that includes your custom attribute
$value = $address->getExtensionAttributes()->getCustomField();

Hy vọng, điều này sẽ giúp và sẽ được thêm vào tài liệu chính thức.


Cảm ơn đã trả lời Alex! Tôi đã thử custom_attributescách, nhưng nó không làm việc cho tôi. Đây là một phần của LayoutProcessor.php` trông như thế nào - gist.github.com/Igloczek/eaf4d2d7a0a04bd950110296ec3f7727 Nhưng shipping-info hoặc thậm chí localStorage checkout-datahoàn toàn không chứa dữ liệu này.
igloczek

Xin vui lòng xem câu trả lời cập nhật của tôi ở trên;)
aakimov

4
Các tài liệu chính thức về chủ đề này đã có sẵn! devdocs.magento.com/guides/v2.1/howdoi/checkout/ cấp
Alex

1
Có thêm một bước cần thiết để có các giá trị được lưu theo thứ tự không?
Alex Hadley

Tôi nghĩ rằng nếu bạn có một dạng tĩnh, tốt hơn là chèn trường vào LayoutProcessor qua XML như trong ví dụ này: devdocs.magento.com/guides/v2.1/howdoi/checkout/ tựa
cjohansson

-1

Theo kinh nghiệm của tôi, m2 sử dụng xml để xác định các thành phần như các trường, v.v. Nó giúp ích cho việc gỡ lỗi, tương tác với dữ liệu dễ dàng hơn. Trên trường của giao diện người dùng, bạn nên cố gắng ghi đè các mẫu thanh toán và thêm các trường tùy chỉnh của riêng bạn vào đó. Với KO giúp bạn có khả năng làm việc và liên kết dữ liệu từ frontend và backend


4
Đó là lời khuyên sai, các mẫu thanh toán b / c không chứa và không bao giờ nên chứa các trường nhập được thêm thủ công. Chúng tôi phải sử dụng KO để kết xuất các mẫu trong các khu vực được chọn (mọi thứ được xây dựng bằng các thành phần UI)
igloczek

Bạn có thể chia sẻ một ví dụ về việc thêm các thành phần ui tùy chỉnh trong frontend không?
mrtuvn

Như @igloczek nói Đó là lời khuyên sai, bởi vì các mẫu thanh toán không bao giờ nên chứa các trường nhập được thêm thủ công.
diazwatson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.