Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
TierPriceStorage.php
Go to the documentation of this file.
1 <?php
8 
10 
15 {
21  private $tierPricePersistence;
22 
28  private $tierPriceValidator;
29 
35  private $tierPriceFactory;
36 
42  private $priceIndexer;
43 
49  private $productIdLocator;
50 
56  private $config;
57 
63  private $typeList;
64 
70  private $indexerChunkValue = 500;
71 
81  public function __construct(
82  TierPricePersistence $tierPricePersistence,
83  \Magento\Catalog\Model\Product\Price\Validation\TierPriceValidator $tierPriceValidator,
84  TierPriceFactory $tierPriceFactory,
85  \Magento\Catalog\Model\Indexer\Product\Price $priceIndexer,
86  \Magento\Catalog\Model\ProductIdLocatorInterface $productIdLocator,
87  \Magento\PageCache\Model\Config $config,
88  \Magento\Framework\App\Cache\TypeListInterface $typeList
89  ) {
90  $this->tierPricePersistence = $tierPricePersistence;
91  $this->tierPriceValidator = $tierPriceValidator;
92  $this->tierPriceFactory = $tierPriceFactory;
93  $this->priceIndexer = $priceIndexer;
94  $this->productIdLocator = $productIdLocator;
95  $this->config = $config;
96  $this->typeList = $typeList;
97  }
98 
102  public function get(array $skus)
103  {
104  $skus = $this->tierPriceValidator->validateSkus($skus);
105 
106  return $this->getExistingPrices($skus);
107  }
108 
112  public function update(array $prices)
113  {
114  $affectedIds = $this->retrieveAffectedProductIdsForPrices($prices);
115  $skus = array_unique(
116  array_map(function ($price) {
117  return $price->getSku();
118  }, $prices)
119  );
120  $result = $this->tierPriceValidator->retrieveValidationResult($prices, $this->getExistingPrices($skus, true));
121  $prices = $this->removeIncorrectPrices($prices, $result->getFailedRowIds());
122  $formattedPrices = $this->retrieveFormattedPrices($prices);
123  $this->tierPricePersistence->update($formattedPrices);
124  $this->reindexPrices($affectedIds);
125  $this->invalidateFullPageCache();
126 
127  return $result->getFailedItems();
128  }
129 
133  public function replace(array $prices)
134  {
135  $result = $this->tierPriceValidator->retrieveValidationResult($prices);
136  $prices = $this->removeIncorrectPrices($prices, $result->getFailedRowIds());
137  $affectedIds = $this->retrieveAffectedProductIdsForPrices($prices);
138  $formattedPrices = $this->retrieveFormattedPrices($prices);
139  $this->tierPricePersistence->replace($formattedPrices, $affectedIds);
140  $this->reindexPrices($affectedIds);
141  $this->invalidateFullPageCache();
142 
143  return $result->getFailedItems();
144  }
145 
149  public function delete(array $prices)
150  {
151  $affectedIds = $this->retrieveAffectedProductIdsForPrices($prices);
152  $result = $this->tierPriceValidator->retrieveValidationResult($prices);
153  $prices = $this->removeIncorrectPrices($prices, $result->getFailedRowIds());
154  $priceIds = $this->retrieveAffectedPriceIds($prices);
155  $this->tierPricePersistence->delete($priceIds);
156  $this->reindexPrices($affectedIds);
157  $this->invalidateFullPageCache();
158 
159  return $result->getFailedItems();
160  }
161 
169  private function getExistingPrices(array $skus, $groupBySku = false)
170  {
171  $ids = $this->retrieveAffectedIds($skus);
172  $rawPrices = $this->tierPricePersistence->get($ids);
173  $prices = [];
174 
175  $linkField = $this->tierPricePersistence->getEntityLinkField();
176  $skuByIdLookup = $this->buildSkuByIdLookup($skus);
177  foreach ($rawPrices as $rawPrice) {
178  $sku = $skuByIdLookup[$rawPrice[$linkField]];
179  $price = $this->tierPriceFactory->create($rawPrice, $sku);
180  if ($groupBySku) {
181  $prices[$sku][] = $price;
182  } else {
183  $prices[] = $price;
184  }
185  }
186 
187  return $prices;
188  }
189 
196  private function retrieveFormattedPrices(array $prices)
197  {
198  $formattedPrices = [];
199 
200  foreach ($prices as $price) {
201  $idsBySku = $this->productIdLocator->retrieveProductIdsBySkus([$price->getSku()]);
202  $ids = array_keys($idsBySku[$price->getSku()]);
203  foreach ($ids as $id) {
204  $formattedPrices[] = $this->tierPriceFactory->createSkeleton($price, $id);
205  }
206  }
207 
208  return $formattedPrices;
209  }
210 
217  private function retrieveAffectedProductIdsForPrices(array $prices)
218  {
219  $skus = array_unique(
220  array_map(function ($price) {
221  return $price->getSku();
222  }, $prices)
223  );
224 
225  return $this->retrieveAffectedIds($skus);
226  }
227 
234  private function retrieveAffectedIds(array $skus)
235  {
236  $affectedIds = [];
237 
238  foreach ($this->productIdLocator->retrieveProductIdsBySkus($skus) as $productId) {
239  $affectedIds = array_merge($affectedIds, array_keys($productId));
240  }
241 
242  return array_unique($affectedIds);
243  }
244 
251  private function retrieveAffectedPriceIds(array $prices)
252  {
253  $affectedIds = $this->retrieveAffectedProductIdsForPrices($prices);
254  $formattedPrices = $this->retrieveFormattedPrices($prices);
255  $existingPrices = $this->tierPricePersistence->get($affectedIds);
256  $priceIds = [];
257 
258  foreach ($formattedPrices as $price) {
259  $priceIds[] = $this->retrievePriceId($price, $existingPrices);
260  }
261 
262  return $priceIds;
263  }
264 
272  private function retrievePriceId(array $price, array $existingPrices)
273  {
274  $linkField = $this->tierPricePersistence->getEntityLinkField();
275 
276  foreach ($existingPrices as $existingPrice) {
277  if ($existingPrice['all_groups'] == $price['all_groups']
278  && $existingPrice['customer_group_id'] == $price['customer_group_id']
279  && $existingPrice['qty'] == $price['qty']
280  && $this->isCorrectPriceValue($existingPrice, $price)
281  && $existingPrice[$linkField] == $price[$linkField]
282  ) {
283  return $existingPrice['value_id'];
284  }
285  }
286 
287  return null;
288  }
289 
297  private function isCorrectPriceValue(array $existingPrice, array $price)
298  {
299  return ($existingPrice['value'] != 0 && $existingPrice['value'] == $price['value'])
300  || ($existingPrice['percentage_value'] !== null
301  && $existingPrice['percentage_value'] == $price['percentage_value']);
302  }
303 
310  private function buildSkuByIdLookup($skus)
311  {
312  $lookup = [];
313  foreach ($this->productIdLocator->retrieveProductIdsBySkus($skus) as $sku => $ids) {
314  foreach (array_keys($ids) as $id) {
315  $lookup[$id] = $sku;
316  }
317  }
318 
319  return $lookup;
320  }
321 
327  private function invalidateFullPageCache()
328  {
329  if ($this->config->isEnabled()) {
330  $this->typeList->invalidate('full_page');
331  }
332  }
333 
340  private function reindexPrices(array $ids)
341  {
342  foreach (array_chunk($ids, $this->indexerChunkValue) as $affectedIds) {
343  $this->priceIndexer->execute($affectedIds);
344  }
345  }
346 
354  private function removeIncorrectPrices(array $prices, array $ids)
355  {
356  foreach ($ids as $id) {
357  unset($prices[$id]);
358  }
359 
360  return $prices;
361  }
362 }
$config
Definition: fraud_order.php:17
$id
Definition: fieldset.phtml:14
$price
foreach($websiteCodes as $websiteCode) $skus
__construct(TierPricePersistence $tierPricePersistence, \Magento\Catalog\Model\Product\Price\Validation\TierPriceValidator $tierPriceValidator, TierPriceFactory $tierPriceFactory, \Magento\Catalog\Model\Indexer\Product\Price $priceIndexer, \Magento\Catalog\Model\ProductIdLocatorInterface $productIdLocator, \Magento\PageCache\Model\Config $config, \Magento\Framework\App\Cache\TypeListInterface $typeList)