2

I have created a new small module to add a checkbox on last step of order process:

enter image description here

The value will transfer over payment JSON:

enter image description here

In the generated PaymentExtensionInterface I have the getter and setter methods:

<?php
namespace Magento\Quote\Api\Data;

/**
 * ExtensionInterface class for @see \Magento\Quote\Api\Data\PaymentInterface
 */
interface PaymentExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
{
    /**
     * @return boolean|null
     */
    public function getTestCheckboxValue();

    /**
     * @param boolean $testCheckboxValue
     * @return $this
     */
    public function setTestCheckboxValue($testCheckboxValue);

But the question is how can I get the value in the event "sales_order_save_commit_after" in an other module like this class?

<?php

use Magento\Sales\Api\Data\OrderInterface;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface;
use Magento\Payment\Model\InfoInterface;

class Test extends AbstractObserver
{
    protected $_request;

    public function __construct(
        \Magento\Framework\App\RequestInterface $request
    ) {
        $this->_request = $request;
    }

    protected function _execute(\Magento\Framework\Event\Observer $observer) {

        $order = $observer->getData('order');
  • I update my answer @Michael, check if it works now for you – gemig_hol Feb 13 at 15:24
0

This is my extension_attributes.xml:

<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\PaymentInterface">
        <attribute code="test_checkbox_value" type="boolean" />
    </extension_attributes>
</config>
0

UPDATE

You can also add a checkbox in a knockoutjs html template and save the value in a controller to your quote table, probably this is not the preferable Magento2 way.

Add your checkbox in a html knockoutjs template, I will do it in the design folder (you can also do it in your module, just to keep it simple here): Magento_Checkout/web/template/form/element/email.html

            <div class="field">
                <label class="label" for="checkbox-custom">
                    <span data-bind="i18n: 'Checkbox Custom:'"></span>
                </label>
                <div class="control checkbox-custom">
                    <input
                            type="checkbox"
                            name="checkbox-custom"
                            id="checkbox-custom"
                            data-bind="afterRender: bindToCheckbox"/>
                </div>
            </div>

After add in design folder:

Magento_Checkout/templates/onepage.phtml

Add in the end of the file:

<script type="text/javascript">
        function bindToCheckbox() {
            jQuery("#checkbox-custom").change(function() {
                if(this.checked) {
                    var url = '/checkbox/checkbox/checkbox';
                    var data = {
                        checked : "check",
                    };

                    jQuery.get(url, data, function(response) {
                        console.warn(response);
                    });
                }
                else {
                    var url = '/checkbox/checkbox/checkbox';
                    var data = {
                        checked : "not",
                    };

                    jQuery.get(url, data, function(response) {
                        console.warn(response);
                    });
                }
            });
        }
</script>

Create a module with a route < Vendor>/Checkbox/etc/frontend/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="checkbox" frontName="checkbox">
            <module name="Vendor_Checkbox"/>
        </route>
    </router>
</config>

Add your controller: < Vendor>/Checkbox/Controller/Checkbox/Checkbox.php

<?php

namespace < Vendor>\Checkbox\Controller\Checkbox;

use Magento\Checkout\Model\Session;
use Magento\Framework\App\Action\Context;
use Magento\Quote\Model\QuoteRepository;

class Checkbox extends \Magento\Framework\App\Action\Action
{
    /**
     * @var Session
     */
    private $checkoutSession;
    /**
     * @var QuoteRepository
     */
    private $quoteRepository;

    /**
     * Checkbox constructor.
     * @param Context $context
     * @param Session $checkoutSession
     * @param QuoteRepository $quoteRepository
     */
    public function __construct(
        Context $context,
        Session $checkoutSession,
        QuoteRepository $quoteRepository
    ){
        parent::__construct($context);
        $this->checkoutSession = $checkoutSession;
        $this->quoteRepository = $quoteRepository;
    }

    public function execute()
    {
        $checkbox= $this->getRequest()->getParam('checked');

        if($checkbox == "check"){
            $checkbox = "1";
        }
        else{
            $checkbox = "0";
        }

        $quoteId = $this->checkoutSession->getQuoteId();

        $quote = $this->quoteRepository->get($quoteId);

        $quote->setCustomCheckbox($checkbox);

        $quote->save();

        die($checkbox);
    }
}

Create a setup script for new fields in quote and sales_order tables < Vendor>/Checkbox/Setup/UpgradeSchema.php

<?php


namespace < Vendor>\Checkbox\Setup;

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

class UpgradeSchema implements UpgradeSchemaInterface
{

    /**
     * Upgrades DB schema for a module
     *
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (version_compare($context->getVersion(), '1.0.1') < 0) {
            $setup->startSetup();

            $setup->getConnection()->addColumn(
                $setup->getTable('sales_order'),
                'custom_checkbox',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                    'length' => '11',
                    'nullable' => false,
                    'default' => '0'
                ]
            );

            $setup->getConnection()->addColumn(
                $setup->getTable('quote'),
                'custom_checkbox',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                    'length' => '11',
                    'nullable' => false,
                    'default' => '0'

                ]
            );


            $setup->endSetup();
        }
    }
}

Set the module version to 1.0.1 in module.xml Run bin/magento setup:upgrade

Create < Vendor>/Checkbox/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_order_place_after">
        <observer name="place_order_after_checkbox" instance="< Vendor>\Checkbox\Observer\Orderplaceafter" />
    </event>
</config>

Than you can get the data from your custom checkbox in the event, here I also set the data in the sales_order table, what Magento 2 doesn't do automatically. Create < Vendor>/Checkbox/Observer/Orderplaceafter.php

<?php


namespace < Vendor>\Checkbox\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Quote\Model\QuoteRepository;
use Magento\Checkout\Api\Data\ShippingInformationInterface;
use Magento\Quote\Model\ShippingFactory;

class Orderplaceafter implements ObserverInterface
{
    /**
     * @var QuoteRepository
     */
    private $quoteRepository;
    /**
     * @var ShippingInformationInterface
     */
    private $shippingInformation;
    /**
     * @var ShippingFactory
     */
    private $shippingFactory;

    /**
     * Orderplaceafter constructor.
     * @param QuoteRepository $quoteRepository
     * @param ShippingInformationInterface $shippingInformation
     * @param ShippingFactory $shippingFactory
     */
    public function __construct(
        QuoteRepository $quoteRepository,
        ShippingInformationInterface $shippingInformation,
        ShippingFactory $shippingFactory
    ){
        $this->quoteRepository = $quoteRepository;
        $this->shippingInformation = $shippingInformation;
        $this->shippingFactory = $shippingFactory;
    }

    /**
     * @param Observer $observer
     * @return void
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function execute(Observer $observer)
    {
        $order = $observer->getOrder();
        $quote = $this->quoteRepository->get($order->getQuoteId());

        $order->setData('custom_checkbox', $quote->getCustomCheckbox());

        $order->save();
    }
}

Let me know if it works for you.

  • Thank you but it doesn't work. I get always the error message like this: "Uncaught Error: Call to undefined method Magento\\Sales\\Api\\Data\\OrderExtension::getTestCheckboxValue()" I have tried so many things... – Michael Jan 10 at 8:42
  • Try adding $order->getPayment()->getExtensionAttributes() – gemig_hol Jan 10 at 8:47
  • I have tried this too. Then I get the output "Magento\Sales\Api\Data\OrderPaymentExtension Object ( [_data:protected] => Array ( ) )" But I can not access to getTestCheckboxValue() or also to getAgreementIds(). – Michael Jan 10 at 10:27
  • Could you post your extension_attributes.xml ? – gemig_hol Jan 10 at 20:44
  • I have post it on the answer. – Michael Jan 11 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.