88
99use Magento \Eav \Model \Config ;
1010use 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 ;
1612use Magento \Framework \Setup \Patch \DataPatchInterface ;
1713use 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+ */
2020class 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