Làm thế nào để thêm vào giỏ hàng một sản phẩm với trường nhập tùy chỉnh và lưu nó vào cơ sở dữ liệu?


9

Tôi đã tạo một mô-đun tùy chỉnh trong đó tôi ghi đè biểu mẫu thêm vào giỏ hàng trên trang sản phẩm và tôi đã thực hiện thành công với catalog_product_view.xmltệp. Bây giờ tôi có thể thấy một trường đầu vào tùy chỉnh trên giao diện phía trước của trang sản phẩm, nhưng tôi cần đăng giá trị của trường này lên cơ sở dữ liệu với Qty, giá, v.v. và truy xuất lại trong lịch sử đơn hàng.

Tôi đã tìm kiếm một lúc và cũng thành công trong việc tạo các cột tùy chỉnh mới trong quote_item& sales_orderbảng. (Theo thông tin của tôi, hãy thêm vào mục nhập giỏ hàng quote_itemvà đặt hàng sau khi thanh toán đi đến sales_orderbàn. Nếu tôi sai về điều đó, xin vui lòng sửa tôi trong điều này vì tôi vẫn là người học.)

Tôi đã thử rất nhiều và tìm kiếm nó nhưng không tìm thấy giải pháp liên quan. Tên nhà cung cấp của tôi là Cloudways và tên mô-đun là Mymodule . Dưới đây là các tệp cho mô-đun của tôi:

Cloudways / Mymodule / register.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Cloudways_Mymodule',
    __DIR__
);

Cloudways / Mymodule / etc / module.xml

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Cloudways_Mymodule" setup_version="1.0.1"></module>
</config>

Cloudways / Mymodule / Setup / Nâng cấpSchema.php

<?php

namespace Cloudways\Mymodule\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;

class UpgradeSchema implements UpgradeSchemaInterface
{
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (version_compare($context->getVersion(), '1.0.1') < 0) {

        $installer = $setup;
        $installer->startSetup();
        $connection = $installer->getConnection();
        //cart table
        $connection->addColumn(
                $installer->getTable('quote_item'),
                'remarks',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' =>'Remarks'
                ]
            );
        //Order address table
        $connection->addColumn(
                $installer->getTable('sales_order'),
                'remarks',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' =>'Remarks'

                ]
            );
        $installer->endSetup(); }
    }
}

Cloudways / Mymodule / view / frontend / layout / catalog_product_view.xml

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.addtocart">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Cloudways_Mymodule::catalog/product/view/addtocart.phtml</argument>
            </action>
        </referenceBlock>
        <referenceBlock name="product.info.addtocart.additional">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Cloudways_Mymodule::catalog/product/view/addtocart.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

Cloudways / Mymodule / view / frontend / samples / catalog / sản phẩm / view / addtocart.phtml

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

/** @var $block \Magento\Catalog\Block\Product\View */
?>
<?php $_product = $block->getProduct(); ?>
<?php $buttonTitle = __('Add to Cart'); ?>
<?php if ($_product->isSaleable()): ?>
<div class="box-tocart">
    <div class="fieldset">
        <?php if ($block->shouldRenderQuantity()): ?>
        <div class="field qty">
            <label class="label" for="qty"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label>
            <div class="control">
                <input type="number"
                       name="qty"
                       id="qty"
                       maxlength="12"
                       value="<?php /* @escapeNotVerified */ echo $block->getProductDefaultQty() * 1 ?>"
                       title="<?php /* @escapeNotVerified */ echo __('Qty') ?>" class="input-text qty"
                       data-validate="<?php echo $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
                       />
            </div>
        </div>
        <!-- Custom Input Field -->
        <div>
            <input
                type="text"
                name="remarks"
                id="remarks"
                maxlength="255"
                placeholder="Remarks"
            />
        </div>
        <!-- Custom Input Field -->
        <br>
        <?php endif; ?>
        <div class="actions">
            <button type="submit"
                    title="<?php /* @escapeNotVerified */ echo $buttonTitle ?>"
                    class="action primary tocart"
                    id="product-addtocart-button">
                <span><?php /* @escapeNotVerified */ echo $buttonTitle ?></span>
            </button>
            <?php echo $block->getChildHtml('', true) ?>
        </div>
    </div>
</div>
<?php endif; ?>
<?php if ($block->isRedirectToCartEnabled()) : ?>
<script type="text/x-magento-init">
    {
        "#product_addtocart_form": {
            "Magento_Catalog/product/view/validation": {
                "radioCheckboxClosest": ".nested"
            }
        }
    }
</script>
<?php else : ?>
<script>
    require([
        'jquery',
        'mage/mage',
        'Magento_Catalog/product/view/validation',
        'Magento_Catalog/js/catalog-add-to-cart'
    ], function ($) {
        'use strict';

        $('#product_addtocart_form').mage('validation', {
            radioCheckboxClosest: '.nested',
            submitHandler: function (form) {
                var widget = $(form).catalogAddToCart({
                    bindSubmit: false
                });

                widget.catalogAddToCart('submitForm', $(form));

                return false;
            }
        });
    });
</script>
<?php endif; ?>

Dưới đây là ảnh chụp màn hình của mặt trước:

nhập mô tả hình ảnh ở đây

Tất cả tôi cần là đăng giá trị của trường đầu vào tùy chỉnh và lưu nó trong cơ sở dữ liệu cùng với thứ tự. Cảm ơn trước!

EDIT: TÔI ĐÃ THỰC HIỆN THAY ĐỔI THEO CÂU TRẢ LỜI CỦA RS VÀ ĐÂY LÀ VẤN ĐỀ TÔI ĐANG TÌM KIẾM: (PS TÔI ĐANG SỬ DỤNG MAGENTO 2.0.9)

nhập mô tả hình ảnh ở đây

Tôi đã kiểm tra tệp nhật ký và đây là những gì tôi đã tìm thấy:

[2016-08-26 07:29:38] main.CRITICAL: exception 'Exception' with message 'Report ID: webapi-57bfefe2d8272; Message: Warning: Invalid argument supplied for foreach() in /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/app/code/Cloudways/Mymodule/Observer/SalesModelServiceQuoteSubmitBeforeObserver.php on line 67' in /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/vendor/magento/framework/Webapi/ErrorProcessor.php:194
Stack trace:
#0 /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/vendor/magento/framework/Webapi/ErrorProcessor.php(139): Magento\Framework\Webapi\ErrorProcessor->_critical(Object(Exception))
#1 /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/vendor/magento/module-webapi/Controller/Rest.php(163): Magento\Framework\Webapi\ErrorProcessor->maskException(Object(Exception))
#2 /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/var/generation/Magento/Webapi/Controller/Rest/Interceptor.php(24): Magento\Webapi\Controller\Rest->dispatch(Object(Magento\Framework\App\Request\Http))
#3 /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/vendor/magento/framework/App/Http.php(115): Magento\Webapi\Controller\Rest\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#4 /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/vendor/magento/framework/App/Bootstrap.php(258): Magento\Framework\App\Http->launch()
#5 /home/41209-54048.cloudwaysapps.com/yyzmyegjdk/public_html/index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#6 {main} [] []

Có gợi ý nào không?


Hãy xem ví dụ về magento 1 stackoverflow.com/questions/9412074/, ... bạn sẽ có thể sử dụng "thêm_options" để lưu trữ thông tin này bằng cách sử dụng trình quan sát github.com/magento/magento2/iêu ... Sử dụng thêm_options sẽ tự động hiển thị thông tin này trong quản trị viên, email đặt hàng bán hàng, v.v.
Renon Stewart

Có một lý do bạn không sử dụng một sản phẩm đơn giản với các tùy chọn tùy chỉnh để thực hiện điều này?
Renon Stewart

@RS Tôi cần thực hiện theo chương trình vì chúng tôi sẽ mở rộng thêm giỏ hàng tùy chỉnh này với các tùy chọn tùy chỉnh khác nhau mà tôi nghĩ chỉ có thể được thực hiện với mô-đun tùy chỉnh.
Fayyaz Khattak

Bạn có thể thêm liên kết (github) vào mã của mình không, vì vậy tôi có thể tải xuống và thử triển khai
thêm_options

@RS Có chắc chắn, xin vui lòng cho tôi vài phút.
Fayyaz Khattak ngày 19/8/2016

Câu trả lời:


14

Để thực hiện điều này, bạn có thể sử dụng chức năng "thêm_options" của magento để bạn không phải chỉnh sửa mẫu email, chế độ xem đơn hàng của quản trị viên, chế độ xem đơn đặt hàng của khách hàng (v.v.) để hiển thị các tùy chọn tùy chỉnh của bạn.

Github: https://github.com/srenon/Cloudways_Mymodule

/app/code/Cloudways/Mymodule/etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_cart_product_add_after">
        <observer name="cloudways_mymodule_checkout_cart_product_add_after" instance="Cloudways\Mymodule\Observer\CheckoutCartProductAddAfterObserver" />
    </event>
    <event name="sales_model_service_quote_submit_before">
        <observer name="cloudways_mymodule_sales_model_service_quote_submit_before" instance="Cloudways\Mymodule\Observer\SalesModelServiceQuoteSubmitBeforeObserver" />
    </event>
</config>

Thêm tùy chọn để trích dẫn

/app/code/Cloudways/Mymodule/Observer/CheckoutCart ProducttAddAfterObserver.php

<?php

namespace Cloudways\Mymodule\Observer;

use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class CheckoutCartProductAddAfterObserver implements ObserverInterface
{

    protected $_request;

    /**
     * @param RequestInterface $request
     */
    public function __construct(RequestInterface $request){
            $this->_request = $request;
    }

    /**
     * @param EventObserver $observer
     * @return void
     */
    public function execute(EventObserver $observer)
    {
        /* @var \Magento\Quote\Model\Quote\Item $item */
        $item = $observer->getQuoteItem();

        $additionalOptions = array();

        if ($additionalOption = $item->getOptionByCode('additional_options')){
            $additionalOptions = (array) unserialize($additionalOption->getValue());
        }

        $post = $this->_request->getParam('cloudways');

        if(is_array($post)){
            foreach($post as $key => $value){
                if($key == '' || $value == ''){
                    continue;
                }

                $additionalOptions[] = [
                    'label' => $key,
                    'value' => $value
                ];
            }
        }

        if(count($additionalOptions) > 0){
            $item->addOption(array(
                'code' => 'additional_options',
                'value' => serialize($additionalOptions)
            ));
        }


        /* To Do */

        // Edit Cart - May need to remove option and readd them
        // Pre-fill remarks on product edit pages


        /* Issues */

        // Create new cart item with identical option values will add a new line item, instead of increment previous item qty

    }
}

Phương pháp # 1 - Tùy chọn sao chép từ quote_item sang order_item bằng cách sử dụng Observer Xem Magento 2 fieldset.xml; sao chép các trường từ trích dẫn để đặt hàng

/app/code/Cloudways/Mymodule/Observer/SalesModelServiceQuoteSubmitB BeforeObserver.php

<?php

namespace Cloudways\Mymodule\Observer;

use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;


class SalesModelServiceQuoteSubmitBeforeObserver implements ObserverInterface
{

    private $quoteItems = [];

    private $quote = null;
    private $order = null;

    /**
     * Add order information into GA block to render on checkout success pages
     *
     * @param EventObserver $observer
     * @return void
     */
    public function execute(EventObserver $observer)
    {

        $this->quote = $observer->getQuote();
        $this->order = $observer->getOrder();

        // can not find an equivalent event for sales_convert_quote_item_to_order_item


        /* @var  \Magento\Sales\Model\Order\Item $orderItem */
        foreach($this->order->getItems() as $orderItem){
            if(!$orderItem->getParentItemId() && $orderItem->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE){

                if($quoteItem = $this->getQuoteItemById($orderItem->getQuoteItemId())){
                    if ($additionalOptionsQuote = $quoteItem->getOptionByCode('additional_options')) {

                        //To do
                        // - check to make sure element are not added twice
                        // - $additionalOptionsQuote - may not be an array
                        if($additionalOptionsOrder = $orderItem->getProductOptionByCode('additional_options')){
                            $additionalOptions = array_merge($additionalOptionsQuote, $additionalOptionsOrder);
                        }
                        else{
                            $additionalOptions = $additionalOptionsQuote;
                        }


                        if(count($additionalOptions) > 0){
                            $options = $orderItem->getProductOptions();
                            $options['additional_options'] = unserialize($additionalOptions->getValue());
                            $orderItem->setProductOptions($options);
                        }

                    }
                }
            }
        }

    }


    private function getQuoteItemById($id){
        if(empty($this->quoteItems)){
            /* @var  \Magento\Quote\Model\Quote\Item $item */
            foreach($this->quote->getItems() as $item){

                //filter out config/bundle etc product
                if(!$item->getParentItemId() && $item->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE){
                    $this->quoteItems[$item->getId()] = $item;
                }
            }
        }


        if(array_key_exists($id, $this->quoteItems)){
            return $this->quoteItems[$id];
        }

        return null;
    }
}

Phương pháp # 2 - Tùy chọn sao chép từ quote_item sang order_item bằng Plugin

/app/code/Cloudways/Mymodule/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\Quote\Model\Quote\Item\ToOrderItem">
        <plugin name="cloudways_mymodule\_Sales_Quote_Item_ToOrderItem" type="Cloudways\Mymodule\Plugin\QuoteItemToOrderItemPlugin" />
    </type>
</config>

/app/code/Cloudways/Mymodule/Plugin/QuoteItemToOrderItemPlugin.php

<?php

namespace Cloudways\Mymodule\Plugin;

class QuoteItemToOrderItemPlugin
{

    public function aroundConvert(\Magento\Quote\Model\Quote\Item\ToOrderItem $subject, callable $proceed, $quoteItem, $data)
    {

        // get order item
        $orderItem = $proceed($quoteItem, $data);


        if(!$orderItem->getParentItemId() && $orderItem->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE){
            if ($additionalOptionsQuote = $quoteItem->getOptionByCode('additional_options')) {
                //To do
                // - check to make sure element are not added twice
                // - $additionalOptionsQuote - may not be an array
                if($additionalOptionsOrder = $orderItem->getProductOptionByCode('additional_options')){
                    $additionalOptions = array_merge($additionalOptionsQuote, $additionalOptionsOrder);
                }
                else{
                    $additionalOptions = $additionalOptionsQuote;
                }
                if(count($additionalOptions) > 0){
                    $options = $orderItem->getProductOptions();
                    $options['additional_options'] = unserialize($additionalOptions->getValue());
                    $orderItem->setProductOptions($options);
                }
            }
        }

        return $orderItem;
    }
}

Giỏ hàng và trang xem thứ tự Admin

Căn cứ tắt của Magento1 - Trích / trật tự thuộc tính mục sản phẩm dựa trên người dùng nhập vào


@renon Tôi đã thử chức năng trên cho sản phẩm đơn giản và nó hoạt động rất tốt, cảm ơn! nhưng tôi cần điều tương tự cho sản phẩm có thể định cấu hình nhưng tôi gặp lỗi sau trên trang giỏ hàng "Tùy chọn được chọn hoặc kết hợp của chúng hiện không khả dụng." Tôi biết tại sao vấn đề này phát sinh, nhưng có cách nào để khắc phục nó, ý tôi là lọc ra các tùy chọn cụ thể?
Nausif

Chỉ cần sử dụng này và nó hoạt động như một nét duyên dáng. Cảm ơn! Bạn có biết bất kỳ chức năng nào trong Magento thực sự cho phép các thuộc tính trên mỗi mục (không phải trên mỗi sản phẩm) không? Ví dụ: một văn bản tùy chỉnh trên áo sơ mi, nhưng trong khi có nhiều áo sơ mi giống nhau với các văn bản khác nhau. Magento hiện kết hợp các sản phẩm đó trong giỏ hàng và do đó tôi mất các cài đặt thực sự cụ thể cho mỗi mục.
Jurgen

@Nausif, tôi đã đối mặt với vấn đề tương tự, nhưng bây giờ nó đã được giải quyết. Tham khảo url này - magento.stackexchange.com/questions/177133/ Kẻ
Kishor Hase

@renon Tôi sử dụng cái này và các giá trị được hiển thị trong mini-cart, cart và checkout. Tôi có sản phẩm cấu hình để làm điều này. Tôi đã thử cả hai phương thức chuyển đổi Trích dẫn, nhưng các giá trị không hiển thị theo thứ tự thư và phần đặt hàng trong quản trị viên.
Rishabh Rk Rai

Nếu bất cứ ai nhận được [invalidargumentexception] unable to unserialize value.sử dụng json_encode và json_decode thay vì tuần tự hóa và
hủy kích hoạt

0

Để giải quyết vấn đề này: // Tạo mục giỏ hàng mới với các giá trị tùy chọn giống hệt nhau sẽ thêm một mục hàng mới, thay vì tăng mục trước đó qty

Tôi đã thêm sau khi plugin cho phương thức đại diệnSản phẩm trong Magento \ Trích dẫn \ Mô hình \ Trích dẫn \ Mục. Trong plugin tôi kiểm tra xem nó có phải là thông số bổ sung cần thiết của tôi không và nếu nó trả về kết quả cần thiết (đúng).

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.