1010use Magento \Catalog \Api \ProductAttributeRepositoryInterface ;
1111use Magento \Catalog \Model \ProductIdLocatorInterface ;
1212use Magento \Catalog \Model \ResourceModel \Attribute ;
13+ use Magento \Catalog \Model \ResourceModel \Product \Price \BasePriceFactory ;
1314use Magento \Framework \App \ObjectManager ;
1415use Magento \Framework \EntityManager \MetadataPool ;
1516use Magento \Framework \Exception \CouldNotDeleteException ;
@@ -88,14 +89,16 @@ class PricePersistence
8889 * @param MetadataPool $metadataPool
8990 * @param string $attributeCode
9091 * @param DateTime|null $dateTime
92+ * @param BasePriceFactory|null $basePriceFactory
9193 */
9294 public function __construct (
9395 Attribute $ attributeResource ,
9496 ProductAttributeRepositoryInterface $ attributeRepository ,
9597 ProductIdLocatorInterface $ productIdLocator ,
9698 MetadataPool $ metadataPool ,
9799 $ attributeCode = '' ,
98- ?DateTime $ dateTime = null
100+ ?DateTime $ dateTime = null ,
101+ private ?BasePriceFactory $ basePriceFactory = null
99102 ) {
100103 $ this ->attributeResource = $ attributeResource ;
101104 $ this ->attributeRepository = $ attributeRepository ;
@@ -104,6 +107,8 @@ public function __construct(
104107 $ this ->metadataPool = $ metadataPool ;
105108 $ this ->dateTime = $ dateTime ?: ObjectManager::getInstance ()
106109 ->get (DateTime::class);
110+ $ this ->basePriceFactory = $ this ->basePriceFactory ?: ObjectManager::getInstance ()
111+ ->get (BasePriceFactory::class);
107112 }
108113
109114 /**
@@ -137,103 +142,17 @@ public function update(array $prices)
137142 return $ price ['attribute_id ' ] = (int )$ this ->getAttributeId ();
138143 });
139144
140- $ connection = $ this ->attributeResource ->getConnection ();
141- $ connection ->beginTransaction ();
145+ $ basePrice = $ this ->basePriceFactory ->create (['attributeId ' => (int )$ this ->getAttributeId ()]);
142146 try {
143- foreach (array_chunk ($ prices , $ this ->itemsPerOperation ) as $ pricesBunch ) {
144- $ existingPrices = $ this ->getExistingPrices ($ pricesBunch );
145- $ pricesBunch = $ this ->doUpdate ($ pricesBunch , $ existingPrices );
146- $ this ->doInsert ($ pricesBunch );
147- }
148- $ connection ->commit ();
147+ $ basePrice ->update ($ prices );
149148 } catch (\Exception $ e ) {
150- $ connection ->rollBack ();
151149 throw new CouldNotSaveException (
152150 __ ('Could not save Prices. ' ),
153151 $ e
154152 );
155153 }
156154 }
157155
158- /**
159- * Get prices that will need update
160- *
161- * @param array $priceBunch
162- * @return array
163- */
164- private function getExistingPrices (array $ priceBunch ): array
165- {
166- $ linkField = $ this ->getEntityLinkField ();
167- $ connection = $ this ->attributeResource ->getConnection ();
168-
169- return $ connection ->fetchAll (
170- $ connection ->select ()
171- ->from ($ this ->attributeResource ->getTable ($ this ->table ))
172- ->where ('attribute_id = ? ' , $ this ->getAttributeId ())
173- ->where ('store_id IN (?) ' , array_unique (array_column ($ priceBunch , 'store_id ' )))
174- ->where ($ linkField . ' IN (?) ' , array_unique (array_column ($ priceBunch , $ linkField )))
175- );
176- }
177-
178- /**
179- * Update existing prices
180- *
181- * @param array $priceBunches
182- * @param array $existingPrices
183- * @return array
184- */
185- private function doUpdate (array $ priceBunches , array $ existingPrices ): array
186- {
187- $ updateData = [];
188- $ linkField = $ this ->getEntityLinkField ();
189- foreach ($ existingPrices as $ existingPrice ) {
190- foreach ($ priceBunches as $ key => $ price ) {
191- if ($ price [$ linkField ] == $ existingPrice [$ linkField ] &&
192- $ price ['store_id ' ] == $ existingPrice ['store_id ' ] &&
193- $ existingPrice ['attribute_id ' ] == $ price ['attribute_id ' ]
194- ) {
195- $ priceBunches [$ key ]['value_id ' ] = $ existingPrice ['value_id ' ];
196- $ uniqueKey = $ price [$ linkField ].$ price ['attribute_id ' ].$ price ['store_id ' ];
197- $ updateData [$ uniqueKey ] = $ priceBunches [$ key ];
198- }
199- }
200- }
201- if (!empty ($ updateData )) {
202- foreach ($ updateData as $ row ) {
203- $ this ->attributeResource ->getConnection ()->update (
204- $ this ->attributeResource ->getTable ($ this ->table ),
205- ['value ' => $ row ['value ' ]],
206- ['value_id = ? ' => (int )$ row ['value_id ' ]]
207- );
208- }
209- }
210- return $ priceBunches ;
211- }
212-
213- /**
214- * Insert new prices
215- *
216- * @param array $priceBunches
217- * @return void
218- */
219- private function doInsert (array $ priceBunches ): void
220- {
221- $ insertData = [];
222- $ linkField = $ this ->getEntityLinkField ();
223- foreach ($ priceBunches as $ price ) {
224- if (!isset ($ price ['value_id ' ])) {
225- $ uniqueKey = $ price [$ linkField ].$ price ['attribute_id ' ].$ price ['store_id ' ];
226- $ insertData [$ uniqueKey ] = $ price ;
227- }
228- }
229- if (!empty ($ insertData )) {
230- $ this ->attributeResource ->getConnection ()->insertMultiple (
231- $ this ->attributeResource ->getTable ($ this ->table ),
232- $ insertData
233- );
234- }
235- }
236-
237156 /**
238157 * Delete product attribute by SKU.
239158 *
0 commit comments