I've been searching the web on how to create an order attribute (if thats whats called), essentially I just want a new database column to appear in the sales_order database, obviously I could create it manually but is there a way I can create it via an upgrade script/programmatically?
3 Answers
Practically, there are two main ways to add an order attribute (a new column) to order via an upgrade script.
--Using $setup->getConnection()->addColumn()
app/code/Vendor/SalesOrder/Setup/UpgradeSchema.php
<?php
namespace Vendor\SalesOrder\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
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)
{
$setup->startSetup();
$quote = 'quote';
$orderTable = 'sales_order';
$setup->getConnection()
->addColumn(
$setup->getTable($quote),
'custom_attribute',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 255,
'comment' =>'Custom Attribute'
]
);
//Order table
$setup->getConnection()
->addColumn(
$setup->getTable($orderTable),
'custom_attribute',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 255,
'comment' =>'Custom Attribute'
]
);
$setup->endSetup();
}
}
--Using Quote and Sale Setup Factory
app/code/Vendor/SalesOrder/Setup/UpgradeData.php
<?php
namespace Vendor\SalesOrder\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Quote\Setup\QuoteSetupFactory;
use Magento\Sales\Setup\SalesSetupFactory;
class UpgradeData implements UpgradeDataInterface
{
/**
* @var QuoteSetupFactory
*/
protected $quoteSetupFactory;
/**
* @var SalesSetupFactory
*/
protected $salesSetupFactory;
/**
* @param QuoteSetupFactory $quoteSetupFactory
* @param SalesSetupFactory $salesSetupFactory
*/
public function __construct(
QuoteSetupFactory $quoteSetupFactory,
SalesSetupFactory $salesSetupFactory
) {
$this->quoteSetupFactory = $quoteSetupFactory;
$this->salesSetupFactory = $salesSetupFactory;
}
/**
* Upgrades DB for a module
*
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
/** @var \Magento\Quote\Setup\QuoteSetup $quoteInstaller */
$quoteInstaller = $this->quoteSetupFactory->create(['resourceName' => 'quote_setup', 'setup' => $setup]);
/** @var \Magento\Sales\Setup\SalesSetup $salesInstaller */
$salesInstaller = $this->salesSetupFactory->create(['resourceName' => 'sales_setup', 'setup' => $setup]);
$setup->startSetup();
//Add multiple attributes to quote
$entityAttributesCodes = [
'custom_attribute' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'custom_attribute1' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT
];
foreach ($entityAttributesCodes as $code => $type) {
$quoteInstaller->addAttribute('quote', $code, ['type' => $type, 'length'=> 255, 'visible' => false, 'nullable' => true,]);
$salesInstaller->addAttribute('order', $code, ['type' => $type, 'length'=> 255, 'visible' => false,'nullable' => true,]);
$salesInstaller->addAttribute('invoice', $code, ['type' => $type, 'length'=> 255, 'visible' => false, 'nullable' => true,]);
}
$setup->endSetup();
}
}
-
Thank you very much, I was just about to add a solution. Commented Aug 18, 2016 at 12:55
-
4This is only for creating an empty extra column in order table right? How can we copy the data from a custom attribute into this extra column in order table? Commented Apr 24, 2017 at 10:58
-
2
-
Is this attribute pass in any third party order manage api? Commented Mar 1, 2019 at 4:50
-
Magento 2.3.4 do not support above format:
Please check below steps to add new attribute to sales_order, quote and sales_invoice tables.
Vendor/Module/etc/db_schema.xml
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="sales_order" resource="sales" engine="innodb" comment="Sales Order">
<column xsi:type="varchar" name="note" nullable="true" length="255" comment="Note"/>
</table>
<table name="quote" resource="checkout" engine="innodb" comment="Quote">
<column xsi:type="varchar" name="note" nullable="true" length="255" comment="Note"/>
</table>
<table name="sales_invoice" resource="sales" engine="innodb" comment="Sales Invoice">
<column xsi:type="varchar" name="note" nullable="true" length="255" comment="Note"/>
</table>
</schema>
After that please run
php bin/magento setup:upgrade
command.
-
1reference devdocs.magento.com/guides/v2.4/extension-dev-guide/… Commented Mar 22, 2021 at 8:38
-
What about the DataPatchInterface? the same procedure to add a new customer attribute? AFAIK, this way is for Magento 2.3– jstuardoCommented Jul 29, 2021 at 15:24
Create a setup/upgrade script using \Magento\Sales\Setup\SalesSetupFactory
and create an event for sales_order_save_before
to set the new attribute.