Question

I have added a custom checkbox in checkout page, and I have added a custom column to sales_order and sales_order_grid tables, now I want to get the value of my checkbox and save it in my custom columns on database, but i don't know how I can do this.

My files to create checkbox:

vendor/module/view/frontend/web/template/invoiceCheckTemplate.html

<div class="col-mp mp-12">
<input type="checkbox" name="invoiceCheck" value="1" data-bind="checked: invoiceCheck, attr: {id: 'invoiceCheck'}"/>
<label data-bind="attr: {for: 'place-order-invoiceCheck'}"><span data-bind="i18n: 'Send invoice'"></span></label>

vendor/module/view/frontend/web/js/invoiceCheck.js

define(
[
    'ko',
    'uiComponent'
],
function (ko, Component) {
    "use strict";

    return Component.extend({
        defaults: {
            template: 'vendor_module/invoiceCheckTemplate.html'
        },
        invoiceCheck: true
    });
}

);

vendor/module/view/frontend/layout/checkout_index_index.xml

 <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">
                                        <!-- Modifying an existing step-->
                                        <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">
                                                                <item name="invoiceCheck" xsi:type="array">
                                                                    <item name="component" xsi:type="string">vendor_module/js/invoiceCheck</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>

                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                 </argument>
             </arguments>
     </referenceBlock>
 </body>

And this is the InstallSchema.php that I have used for my custom columns:

vendor/module/Setup/InstallSchema.php

public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
    $installer = $setup;
    $installer->startSetup();

    $installer->getConnection()->addColumn(
        $installer->getTable('sales_order'),
        'invoice_check',
        [
            'type' => 'boolean',
            'comment' => 'Send Invoice',
            'source' => Boolean::class,
            'visible' => false,
            'default' => 0,
            'nullable' => false
        ]
    );


    $installer->getConnection()->addColumn(
        $installer->getTable('sales_order_grid'),
        'invoice_check',
        [
            'type' => 'boolean',
            'comment' => 'Send Invoice',
            'source' => Boolean::class,
            'visible' => false,
            'default' => 0,
            'nullable' => false
        ]
    );

    $setup->endSetup();
}

I am pretty new like magento 2 developer so I am very grateful for any help. Thank you and sorry for my bad english.

Edit: I have added the follow code:

vendor/module/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="sales_model_service_quote_submit_before">
        <observer name="transfer_value_to_order"
                  instance="Module\Vendor\Observer\TransferValueToOrder" />
    </event>
</config>

vendor/module/Observer/TransferValueToOrder.php

<?php
declare(strict_types=1);

namespace Module\Vendor\Observer;

class TransferValueToOrder implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $requestPayload = json_decode(file_get_contents('php://input'),true);
        // extract the checkbox value from request payload into $checkboxValue
        $checkboxValue = $requestPayload["invoiceCheck"];

       
        $order = $observer->getOrder();
        $order->setInvoiceCheck($checkboxValue);
        return;
    }
    
}

Now, I have de this error:

Notice: Undefined index: invoice_check in /var/www/html/app/code/Module/Vendor/Observer/TransferValueToOrder.php on line 16

So I can't get the value of checkbox with $checkboxValue = $requestPayload["invoiceCheck"];

I'm working with Magento 2.3.5, my custom checkbox is in first step to checkout (I'm working with 2 steps checkout).

No correct solution

OTHER TIPS

One option is to use an observer.

I'm assuming your using default one page checkout from Magento, but this might work with other checkouts as well.

Configure the Observer

<!-- your-module/etc/webapi_rest/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="sales_model_service_quote_submit_before">
        <observer name="some.observer.name"
                  instance="Vendor\Module\Observer\TransferValueToOrder" />
    </event>
</config>

Now the Observer code

<!-- your-module/Observer -->
<?php
declare(strict_types=1);

namespace Vendor\Module\Observer;


class TransferValueToOrder implements ObserverInterface
{
    /**
     * @param Observer $observer
     */
    public function execute(Observer $observer)
    {
        $requestPayload = json_decode(file_get_contents('php://input'),true);
        // extract the checkbox value from request payload into $checkboxValue
       
        $order = $observer->getOrder();
        $order->setInvoiceCheck($checkboxValue);
        return;
    }
}

Due to the inner workings of Magento the value will be persisted in the database. setInvoiceCheck() will invoke __set() magic method which will add the passed value into the inner data property of the Order.

Everything in the inner data property which has a key consistent with a column name in sales_order table will be persisted in the database.

Now I'm assuming that an ajax request is made when you click the Place Order button(default Magento) and that is why the non-conventional way of extracting params from the request, normally you would inject the Magento\Framework\App\RequestInterface object and call the getParameters() method to retrieve them.

Hope this helps, cheers!

EDIT: Also you might want to take a look at the current standard for building/altering db tables https://devdocs.magento.com/guides/v2.4/extension-dev-guide/declarative-schema/db-schema.html

EDIT 2: Once saved on sales_order it will propagate on sales_order_grid;

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top