6
6
7
7
namespace Magento \Catalog \Model \Product \Price ;
8
8
9
+ use Magento \Catalog \Api \Data \SpecialPriceInterface ;
10
+ use Magento \Catalog \Api \Data \SpecialPriceInterfaceFactory ;
11
+ use Magento \Catalog \Api \SpecialPriceStorageInterface ;
12
+ use Magento \Catalog \Model \Product \Price \Validation \InvalidSkuProcessor ;
13
+ use Magento \Catalog \Model \Product \Price \Validation \Result ;
14
+ use Magento \Catalog \Model \ProductIdLocatorInterface ;
15
+ use Magento \Framework \App \ObjectManager ;
9
16
use Magento \Framework \Exception \NoSuchEntityException ;
17
+ use Magento \Catalog \Helper \Data ;
18
+ use Magento \Store \Api \StoreRepositoryInterface ;
10
19
11
20
/**
12
21
* Special price storage presents efficient price API and is used to retrieve, update or delete special prices.
22
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
13
23
*/
14
- class SpecialPriceStorage implements \ Magento \ Catalog \ Api \ SpecialPriceStorageInterface
24
+ class SpecialPriceStorage implements SpecialPriceStorageInterface
15
25
{
16
26
/**
17
27
* @var \Magento\Catalog\Api\SpecialPriceInterface
18
28
*/
19
29
private $ specialPriceResource ;
20
30
21
31
/**
22
- * @var \Magento\Catalog\Api\Data\ SpecialPriceInterfaceFactory
32
+ * @var SpecialPriceInterfaceFactory
23
33
*/
24
34
private $ specialPriceFactory ;
25
35
26
36
/**
27
- * @var \Magento\Catalog\Model\ ProductIdLocatorInterface
37
+ * @var ProductIdLocatorInterface
28
38
*/
29
39
private $ productIdLocator ;
30
40
31
41
/**
32
- * @var \Magento\Store\Api\ StoreRepositoryInterface
42
+ * @var StoreRepositoryInterface
33
43
*/
34
44
private $ storeRepository ;
35
45
36
46
/**
37
- * @var \Magento\Catalog\Model\Product\Price\Validation\ Result
47
+ * @var Result
38
48
*/
39
49
private $ validationResult ;
40
50
41
51
/**
42
- * @var \Magento\Catalog\Model\Product\Price\Validation\ InvalidSkuProcessor
52
+ * @var InvalidSkuProcessor
43
53
*/
44
54
private $ invalidSkuProcessor ;
45
55
46
56
/**
47
57
* @var array
48
58
*/
49
- private $ allowedProductTypes = [];
59
+ private $ allowedProductTypes ;
60
+
61
+ /**
62
+ * @var Data
63
+ */
64
+ private $ catalogData ;
50
65
51
66
/**
52
67
* @param \Magento\Catalog\Api\SpecialPriceInterface $specialPriceResource
53
- * @param \Magento\Catalog\Api\Data\SpecialPriceInterfaceFactory $specialPriceFactory
54
- * @param \Magento\Catalog\Model\ProductIdLocatorInterface $productIdLocator
55
- * @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository
56
- * @param \Magento\Catalog\Model\Product\Price\Validation\Result $validationResult
57
- * @param \Magento\Catalog\Model\Product\Price\Validation\InvalidSkuProcessor $invalidSkuProcessor
58
- * @param array $allowedProductTypes [optional]
68
+ * @param SpecialPriceInterfaceFactory $specialPriceFactory
69
+ * @param ProductIdLocatorInterface $productIdLocator
70
+ * @param StoreRepositoryInterface $storeRepository
71
+ * @param Result $validationResult
72
+ * @param InvalidSkuProcessor $invalidSkuProcessor
73
+ * @param array $allowedProductTypes
74
+ * @param Data|null $catalogData
59
75
*/
60
76
public function __construct (
61
77
\Magento \Catalog \Api \SpecialPriceInterface $ specialPriceResource ,
62
- \Magento \Catalog \Api \Data \SpecialPriceInterfaceFactory $ specialPriceFactory ,
63
- \Magento \Catalog \Model \ProductIdLocatorInterface $ productIdLocator ,
64
- \Magento \Store \Api \StoreRepositoryInterface $ storeRepository ,
65
- \Magento \Catalog \Model \Product \Price \Validation \Result $ validationResult ,
66
- \Magento \Catalog \Model \Product \Price \Validation \InvalidSkuProcessor $ invalidSkuProcessor ,
67
- array $ allowedProductTypes = []
78
+ SpecialPriceInterfaceFactory $ specialPriceFactory ,
79
+ ProductIdLocatorInterface $ productIdLocator ,
80
+ StoreRepositoryInterface $ storeRepository ,
81
+ Result $ validationResult ,
82
+ InvalidSkuProcessor $ invalidSkuProcessor ,
83
+ array $ allowedProductTypes = [],
84
+ ?Data $ catalogData = null
68
85
) {
69
86
$ this ->specialPriceResource = $ specialPriceResource ;
70
87
$ this ->specialPriceFactory = $ specialPriceFactory ;
@@ -73,10 +90,11 @@ public function __construct(
73
90
$ this ->validationResult = $ validationResult ;
74
91
$ this ->invalidSkuProcessor = $ invalidSkuProcessor ;
75
92
$ this ->allowedProductTypes = $ allowedProductTypes ;
93
+ $ this ->catalogData = $ catalogData ?: ObjectManager::getInstance ()->get (Data::class);
76
94
}
77
95
78
96
/**
79
- * { @inheritdoc}
97
+ * @inheritdoc
80
98
*/
81
99
public function get (array $ skus )
82
100
{
@@ -85,7 +103,7 @@ public function get(array $skus)
85
103
86
104
$ prices = [];
87
105
foreach ($ rawPrices as $ rawPrice ) {
88
- /** @var \Magento\Catalog\Api\Data\ SpecialPriceInterface $price */
106
+ /** @var SpecialPriceInterface $price */
89
107
$ price = $ this ->specialPriceFactory ->create ();
90
108
$ sku = isset ($ rawPrice ['sku ' ])
91
109
? $ rawPrice ['sku ' ]
@@ -102,7 +120,7 @@ public function get(array $skus)
102
120
}
103
121
104
122
/**
105
- * { @inheritdoc}
123
+ * @inheritdoc
106
124
*/
107
125
public function update (array $ prices )
108
126
{
@@ -113,7 +131,7 @@ public function update(array $prices)
113
131
}
114
132
115
133
/**
116
- * { @inheritdoc}
134
+ * @inheritdoc
117
135
*/
118
136
public function delete (array $ prices )
119
137
{
@@ -140,52 +158,14 @@ private function retrieveValidPrices(array $prices)
140
158
141
159
foreach ($ prices as $ key => $ price ) {
142
160
if (!$ price ->getSku () || in_array ($ price ->getSku (), $ failedSkus )) {
143
- $ this ->validationResult ->addFailedItem (
144
- $ key ,
145
- __ (
146
- 'The product that was requested doesn \'t exist. Verify the product and try again. '
147
- . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ,
148
- [
149
- 'SKU ' => $ price ->getSku (),
150
- 'storeId ' => $ price ->getStoreId (),
151
- 'priceFrom ' => $ price ->getPriceFrom (),
152
- 'priceTo ' => $ price ->getPriceTo ()
153
- ]
154
- ),
155
- [
156
- 'SKU ' => $ price ->getSku (),
157
- 'storeId ' => $ price ->getStoreId (),
158
- 'priceFrom ' => $ price ->getPriceFrom (),
159
- 'priceTo ' => $ price ->getPriceTo ()
160
- ]
161
- );
161
+ $ errorMessage = 'The product that was requested doesn \'t exist. Verify the product and try again. '
162
+ . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ;
163
+ $ this ->addFailedItemPrice ($ price , $ key , $ errorMessage , []);
162
164
}
165
+ $ this ->checkStore ($ price , $ key );
163
166
$ this ->checkPrice ($ price , $ key );
164
167
$ this ->checkDate ($ price , $ price ->getPriceFrom (), 'Price From ' , $ key );
165
168
$ this ->checkDate ($ price , $ price ->getPriceTo (), 'Price To ' , $ key );
166
- try {
167
- $ this ->storeRepository ->getById ($ price ->getStoreId ());
168
- } catch (NoSuchEntityException $ e ) {
169
- $ this ->validationResult ->addFailedItem (
170
- $ key ,
171
- __ (
172
- 'Requested store is not found. '
173
- . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ,
174
- [
175
- 'SKU ' => $ price ->getSku (),
176
- 'storeId ' => $ price ->getStoreId (),
177
- 'priceFrom ' => $ price ->getPriceFrom (),
178
- 'priceTo ' => $ price ->getPriceTo ()
179
- ]
180
- ),
181
- [
182
- 'SKU ' => $ price ->getSku (),
183
- 'storeId ' => $ price ->getStoreId (),
184
- 'priceFrom ' => $ price ->getPriceFrom (),
185
- 'priceTo ' => $ price ->getPriceTo ()
186
- ]
187
- );
188
- }
189
169
}
190
170
191
171
foreach ($ this ->validationResult ->getFailedRowIds () as $ id ) {
@@ -195,77 +175,95 @@ private function retrieveValidPrices(array $prices)
195
175
return $ prices ;
196
176
}
197
177
178
+ /**
179
+ * Check that store exists and is global when price scope is global and otherwise add error to aggregator.
180
+ *
181
+ * @param SpecialPriceInterface $price
182
+ * @param int $key
183
+ * @return void
184
+ */
185
+ private function checkStore (SpecialPriceInterface $ price , int $ key ): void
186
+ {
187
+ if ($ this ->catalogData ->isPriceGlobal () && $ price ->getStoreId () !== 0 ) {
188
+ $ errorMessage = 'Could not change non global Price when price scope is global. '
189
+ . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ;
190
+ $ this ->addFailedItemPrice ($ price , $ key , $ errorMessage , []);
191
+ }
192
+
193
+ try {
194
+ $ this ->storeRepository ->getById ($ price ->getStoreId ());
195
+ } catch (NoSuchEntityException $ e ) {
196
+ $ errorMessage = 'Requested store is not found. '
197
+ . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ;
198
+ $ this ->addFailedItemPrice ($ price , $ key , $ errorMessage , []);
199
+ }
200
+ }
201
+
198
202
/**
199
203
* Check that date value is correct and add error to aggregator if it contains incorrect data.
200
204
*
201
- * @param \Magento\Catalog\Api\Data\ SpecialPriceInterface $price
205
+ * @param SpecialPriceInterface $price
202
206
* @param string $value
203
207
* @param string $label
204
208
* @param int $key
205
209
* @return void
206
210
*/
207
- private function checkDate (\ Magento \ Catalog \ Api \ Data \ SpecialPriceInterface $ price , $ value , $ label , $ key )
211
+ private function checkDate (SpecialPriceInterface $ price , $ value , $ label , $ key )
208
212
{
209
213
if ($ value && !$ this ->isCorrectDateValue ($ value )) {
210
- $ this ->validationResult ->addFailedItem (
211
- $ key ,
212
- __ (
213
- 'Invalid attribute %label = %priceTo. '
214
- . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ,
215
- [
216
- 'label ' => $ label ,
217
- 'SKU ' => $ price ->getSku (),
218
- 'storeId ' => $ price ->getStoreId (),
219
- 'priceFrom ' => $ price ->getPriceFrom (),
220
- 'priceTo ' => $ price ->getPriceTo ()
221
- ]
222
- ),
223
- [
224
- 'label ' => $ label ,
225
- 'SKU ' => $ price ->getSku (),
226
- 'storeId ' => $ price ->getStoreId (),
227
- 'priceFrom ' => $ price ->getPriceFrom (),
228
- 'priceTo ' => $ price ->getPriceTo ()
229
- ]
230
- );
214
+ $ errorMessage = 'Invalid attribute %label = %priceTo. '
215
+ . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ;
216
+ $ this ->addFailedItemPrice ($ price , $ key , $ errorMessage , ['label ' => $ label ]);
231
217
}
232
218
}
233
219
234
220
/**
235
- * Check that provided price value is not empty and not lower then zero and add error to aggregator if price
221
+ * Check price.
222
+ *
223
+ * Verify that provided price value is not empty and not lower then zero and add error to aggregator if price
236
224
* contains not valid data.
237
225
*
238
- * @param \Magento\Catalog\Api\Data\ SpecialPriceInterface $price
226
+ * @param SpecialPriceInterface $price
239
227
* @param int $key
240
228
* @return void
241
229
*/
242
- private function checkPrice (\ Magento \ Catalog \ Api \ Data \ SpecialPriceInterface $ price , $ key )
230
+ private function checkPrice (SpecialPriceInterface $ price , int $ key ): void
243
231
{
244
232
if (null === $ price ->getPrice () || $ price ->getPrice () < 0 ) {
245
- $ this ->validationResult ->addFailedItem (
246
- $ key ,
247
- __ (
248
- 'Invalid attribute Price = %price. '
249
- . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ,
250
- [
251
- 'price ' => $ price ->getPrice (),
252
- 'SKU ' => $ price ->getSku (),
253
- 'storeId ' => $ price ->getStoreId (),
254
- 'priceFrom ' => $ price ->getPriceFrom (),
255
- 'priceTo ' => $ price ->getPriceTo ()
256
- ]
257
- ),
258
- [
259
- 'price ' => $ price ->getPrice (),
260
- 'SKU ' => $ price ->getSku (),
261
- 'storeId ' => $ price ->getStoreId (),
262
- 'priceFrom ' => $ price ->getPriceFrom (),
263
- 'priceTo ' => $ price ->getPriceTo ()
264
- ]
265
- );
233
+ $ errorMessage = 'Invalid attribute Price = %price. '
234
+ . 'Row ID: SKU = %SKU, Store ID: %storeId, Price From: %priceFrom, Price To: %priceTo. ' ;
235
+ $ this ->addFailedItemPrice ($ price , $ key , $ errorMessage , ['price ' => $ price ->getPrice ()]);
266
236
}
267
237
}
268
238
239
+ /**
240
+ * Adds failed item price to validation result
241
+ *
242
+ * @param SpecialPriceInterface $price
243
+ * @param int $key
244
+ * @param string $message
245
+ * @param array $firstParam
246
+ * @return void
247
+ */
248
+ private function addFailedItemPrice (
249
+ SpecialPriceInterface $ price ,
250
+ int $ key ,
251
+ string $ message ,
252
+ array $ firstParam
253
+ ): void {
254
+ $ additionalInfo = [];
255
+ if ($ firstParam ) {
256
+ $ additionalInfo = array_merge ($ additionalInfo , $ firstParam );
257
+ }
258
+
259
+ $ additionalInfo ['SKU ' ] = $ price ->getSku ();
260
+ $ additionalInfo ['storeId ' ] = $ price ->getStoreId ();
261
+ $ additionalInfo ['priceFrom ' ] = $ price ->getPriceFrom ();
262
+ $ additionalInfo ['priceTo ' ] = $ price ->getPriceTo ();
263
+
264
+ $ this ->validationResult ->addFailedItem ($ key , __ ($ message , $ additionalInfo ), $ additionalInfo );
265
+ }
266
+
269
267
/**
270
268
* Retrieve SKU by product ID.
271
269
*
0 commit comments