Skip to content

Commit 18a20ae

Browse files
authored
ENGCOM-4071: [Forwardport] Use batches and direct queries to fix sales address upgrade #20785
2 parents 2a55512 + d014ad0 commit 18a20ae

File tree

1 file changed

+104
-62
lines changed

1 file changed

+104
-62
lines changed

app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php

Lines changed: 104 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,22 @@
88

99
use Magento\Eav\Model\Config;
1010
use Magento\Framework\App\State;
11-
use Magento\Quote\Model\QuoteFactory;
12-
use Magento\Sales\Model\OrderFactory;
13-
use Magento\Sales\Model\ResourceModel\Order\Address\CollectionFactory as AddressCollectionFactory;
14-
use Magento\Framework\App\ResourceConnection;
15-
use Magento\Sales\Setup\SalesSetupFactory;
11+
use Magento\Framework\Setup\ModuleDataSetupInterface;
1612
use Magento\Framework\Setup\Patch\DataPatchInterface;
1713
use Magento\Framework\Setup\Patch\PatchVersionInterface;
18-
use Magento\Framework\Setup\ModuleDataSetupInterface;
14+
use Magento\Sales\Model\Order\Address;
15+
use Magento\Sales\Setup\SalesSetupFactory;
1916

17+
/**
18+
* Fills quote_address_id in table sales_order_address if it is empty.
19+
*/
2020
class FillQuoteAddressIdInSalesOrderAddress implements DataPatchInterface, PatchVersionInterface
2121
{
2222
/**
2323
* @var ModuleDataSetupInterface
2424
*/
2525
private $moduleDataSetup;
2626

27-
/**
28-
* @var SalesSetupFactory
29-
*/
30-
private $salesSetupFactory;
31-
3227
/**
3328
* @var State
3429
*/
@@ -40,44 +35,22 @@ class FillQuoteAddressIdInSalesOrderAddress implements DataPatchInterface, Patch
4035
private $eavConfig;
4136

4237
/**
43-
* @var AddressCollectionFactory
44-
*/
45-
private $addressCollectionFactory;
46-
47-
/**
48-
* @var OrderFactory
49-
*/
50-
private $orderFactory;
51-
52-
/**
53-
* @var QuoteFactory
54-
*/
55-
private $quoteFactory;
56-
57-
/**
58-
* PatchInitial constructor.
5938
* @param ModuleDataSetupInterface $moduleDataSetup
39+
* @param State $state
40+
* @param Config $eavConfig
6041
*/
6142
public function __construct(
6243
ModuleDataSetupInterface $moduleDataSetup,
63-
SalesSetupFactory $salesSetupFactory,
6444
State $state,
65-
Config $eavConfig,
66-
AddressCollectionFactory $addressCollectionFactory,
67-
OrderFactory $orderFactory,
68-
QuoteFactory $quoteFactory
45+
Config $eavConfig
6946
) {
7047
$this->moduleDataSetup = $moduleDataSetup;
71-
$this->salesSetupFactory = $salesSetupFactory;
7248
$this->state = $state;
7349
$this->eavConfig = $eavConfig;
74-
$this->addressCollectionFactory = $addressCollectionFactory;
75-
$this->orderFactory = $orderFactory;
76-
$this->quoteFactory = $quoteFactory;
7750
}
7851

7952
/**
80-
* {@inheritdoc}
53+
* @inheritdoc
8154
*/
8255
public function apply()
8356
{
@@ -96,32 +69,12 @@ public function apply()
9669
*/
9770
public function fillQuoteAddressIdInSalesOrderAddress(ModuleDataSetupInterface $setup)
9871
{
99-
$addressTable = $setup->getTable('sales_order_address');
100-
$updateOrderAddress = $setup->getConnection()
101-
->select()
102-
->joinInner(
103-
['sales_order' => $setup->getTable('sales_order')],
104-
$addressTable . '.parent_id = sales_order.entity_id',
105-
['quote_address_id' => 'quote_address.address_id']
106-
)
107-
->joinInner(
108-
['quote_address' => $setup->getTable('quote_address')],
109-
'sales_order.quote_id = quote_address.quote_id
110-
AND ' . $addressTable . '.address_type = quote_address.address_type',
111-
[]
112-
)
113-
->where(
114-
$addressTable . '.quote_address_id IS NULL'
115-
);
116-
$updateOrderAddress = $setup->getConnection()->updateFromSelect(
117-
$updateOrderAddress,
118-
$addressTable
119-
);
120-
$setup->getConnection()->query($updateOrderAddress);
72+
$this->fillQuoteAddressIdInSalesOrderAddressByType($setup, Address::TYPE_SHIPPING);
73+
$this->fillQuoteAddressIdInSalesOrderAddressByType($setup, Address::TYPE_BILLING);
12174
}
12275

12376
/**
124-
* {@inheritdoc}
77+
* @inheritdoc
12578
*/
12679
public static function getDependencies()
12780
{
@@ -131,18 +84,107 @@ public static function getDependencies()
13184
}
13285

13386
/**
134-
* {@inheritdoc}
87+
* @inheritdoc
13588
*/
13689
public static function getVersion()
13790
{
13891
return '2.0.8';
13992
}
14093

14194
/**
142-
* {@inheritdoc}
95+
* @inheritdoc
14396
*/
14497
public function getAliases()
14598
{
14699
return [];
147100
}
101+
102+
/**
103+
* Fill quote_address_id in sales_order_address by type.
104+
*
105+
* @param ModuleDataSetupInterface $setup
106+
* @param string $addressType
107+
* @throws \Zend_Db_Statement_Exception
108+
*/
109+
private function fillQuoteAddressIdInSalesOrderAddressByType(ModuleDataSetupInterface $setup, $addressType)
110+
{
111+
$salesConnection = $setup->getConnection('sales');
112+
113+
$orderTable = $setup->getTable('sales_order', 'sales');
114+
$orderAddressTable = $setup->getTable('sales_order_address', 'sales');
115+
116+
$query = $salesConnection
117+
->select()
118+
->from(
119+
['sales_order_address' => $orderAddressTable],
120+
['entity_id', 'address_type']
121+
)
122+
->joinInner(
123+
['sales_order' => $orderTable],
124+
'sales_order_address.parent_id = sales_order.entity_id',
125+
['quote_id' => 'sales_order.quote_id']
126+
)
127+
->where('sales_order_address.quote_address_id IS NULL')
128+
->where('sales_order_address.address_type = ?', $addressType)
129+
->order('sales_order_address.entity_id');
130+
131+
$batchSize = 5000;
132+
$result = $salesConnection->query($query);
133+
$count = $result->rowCount();
134+
$batches = ceil($count / $batchSize);
135+
136+
for ($batch = $batches; $batch > 0; $batch--) {
137+
$query->limitPage($batch, $batchSize);
138+
$result = $salesConnection->fetchAssoc($query);
139+
140+
$this->fillQuoteAddressIdInSalesOrderAddressProcessBatch($setup, $result, $addressType);
141+
}
142+
}
143+
144+
/**
145+
* Process filling quote_address_id in sales_order_address in batch.
146+
*
147+
* @param ModuleDataSetupInterface $setup
148+
* @param array $orderAddresses
149+
* @param string $addressType
150+
*/
151+
private function fillQuoteAddressIdInSalesOrderAddressProcessBatch(
152+
ModuleDataSetupInterface $setup,
153+
array $orderAddresses,
154+
$addressType
155+
) {
156+
$salesConnection = $setup->getConnection('sales');
157+
$quoteConnection = $setup->getConnection('checkout');
158+
159+
$quoteAddressTable = $setup->getTable('quote_address', 'checkout');
160+
$quoteTable = $setup->getTable('quote', 'checkout');
161+
$salesOrderAddressTable = $setup->getTable('sales_order_address', 'sales');
162+
163+
$query = $quoteConnection
164+
->select()
165+
->from(
166+
['quote_address' => $quoteAddressTable],
167+
['quote_id', 'address_id']
168+
)
169+
->joinInner(
170+
['quote' => $quoteTable],
171+
'quote_address.quote_id = quote.entity_id',
172+
[]
173+
)
174+
->where('quote.entity_id in (?)', array_column($orderAddresses, 'quote_id'))
175+
->where('address_type = ?', $addressType);
176+
177+
$quoteAddresses = $quoteConnection->fetchAssoc($query);
178+
179+
foreach ($orderAddresses as $orderAddress) {
180+
$bind = [
181+
'quote_address_id' => $quoteAddresses[$orderAddress['quote_id']]['address_id'] ?? null,
182+
];
183+
$where = [
184+
'entity_id = ?' => $orderAddress['entity_id']
185+
];
186+
187+
$salesConnection->update($salesOrderAddressTable, $bind, $where);
188+
}
189+
}
148190
}

0 commit comments

Comments
 (0)