Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
iblockpricechanger.php
1<?php
3
8
10{
11 private $iblockId = 0;
12 private $userDialogParams = array();
13
21 public function __construct(array $userDialogParams, $iblockId)
22 {
23 $this->setUserDialogParams( $userDialogParams );
24 $this->iblockId = (int)$iblockId;
25 }
26
33 public function setUserDialogParams(array $userDialogParams)
34 {
35 if (!isset($userDialogParams['VALUE_CHANGING'])
36 ||((float)($userDialogParams['VALUE_CHANGING'] == 0)
37 ||!isset($userDialogParams['PRICE_TYPE'])
38 ||!(int)($userDialogParams['PRICE_TYPE'])))
39 {
40 return false;
41 }
42 else
43 {
44 $userDialogParams['PRICE_TYPE'] = (int)($userDialogParams['PRICE_TYPE']);
45 }
46
47 if (!isset($userDialogParams['DIFFERENCE_VALUE'])||!(float)$userDialogParams['DIFFERENCE_VALUE'])
48 {
49 $userDialogParams['DIFFERENCE_VALUE'] = 0;
50 }
51
52 if (!isset($userDialogParams['RESULT_MASK'])||!(float)$userDialogParams['RESULT_MASK'])
53 {
54 $userDialogParams['RESULT_MASK'] = 1;
55 }
56
57 if (!isset($userDialogParams['UNITS']))
58 {
59 $userDialogParams['UNITS'] = null;
60 }
61 else
62 {
63 if ($userDialogParams['UNITS'] != 'percent' && $userDialogParams['UNITS'] != 'multiple')
64 {
65 if (Currency\CurrencyManager::isCurrencyExist($userDialogParams['UNITS']))
66 {
67 $userDialogParams['CURRENCY'] = $userDialogParams['UNITS'];
68 $userDialogParams['UNITS'] = 'currency';
69 }
70 else
71 {
72 $userDialogParams['UNITS'] = null;
73 }
74 }
75 }
76
77 $_SESSION['CHANGE_PRICE_PARAMS']['PRICE_TYPE'] = $userDialogParams['PRICE_TYPE'];
78 $_SESSION['CHANGE_PRICE_PARAMS']['UNITS'] = $userDialogParams['UNITS'];
79 $_SESSION['CHANGE_PRICE_PARAMS']['FORMAT_RESULTS'] = $userDialogParams['FORMAT_RESULTS'];
80 $_SESSION['CHANGE_PRICE_PARAMS']['INITIAL_PRICE_TYPE'] = $userDialogParams['INITIAL_PRICE_TYPE'];
81
82 return $this->userDialogParams = $userDialogParams;
83 }
84
90 private function collectAllSectionsElements(&$productsIdList)
91 {
92 $resultAllElementsList = \CIBlockElement::GetList(
93 array(),
94 array(
95 "SECTION_ID"=>$productsIdList['SECTIONS'],
96 "IBLOCK_ID" => $this->iblockId,
97 "WF_PARENT_ELEMENT_ID" => NULL,
98 "INCLUDE_SUBSECTIONS"=>"Y",
99 "CHECK_PERMISSIONS" => "Y",
100 "MIN_PERMISSION" => "W"
101 ),
102 false,
103 false,
104 array('ID'));
105 while ($subSectionsResult = $resultAllElementsList->Fetch())
106 {
107 $productsIdList['ELEMENTS'][] = $subSectionsResult['ID'];
108 }
109 unset($subSectionsResult, $resultAllElementsList);
110 unset( $productsIdList['SECTIONS'] );
111 }
112
119 private function collectPriceSkuElementsId($productsIdList)
120 {
121 $sectionElementsIdList = array();
122
123 $skuIdList = \CCatalogSku::getOffersList($productsIdList['ELEMENTS'], $this->iblockId);
124 if(is_array($skuIdList))
125 {
126 foreach ($skuIdList as $skuId => $skuListElements)
127 {
128 $sectionElementsIdList[] = $skuId;
129 foreach ($skuListElements as $skuElement)
130 {
131 $priceElementsIdList['SKU_ELEMENTS'][] = $skuElement["ID"];
132 }
133 }
134 }
135
136 if (empty($priceElementsIdList))
137 {
138 $priceElementsIdList['SIMPLE_ELEMENTS'] = $productsIdList['ELEMENTS'];
139 }
140 elseif ($elementsWithoutSkuIdList = array_diff($productsIdList['ELEMENTS'], $sectionElementsIdList))
141 {
142 $priceElementsIdList['SIMPLE_ELEMENTS'] = $elementsWithoutSkuIdList;
143 unset ($elementsWithoutSkuIdList);
144 }
145
146 return $priceElementsIdList;
147 }
148
154 private function initFilterParams()
155 {
156 $catalogGroups = array();
157 if (isset($this->userDialogParams['INITIAL_PRICE_TYPE']))
158 {
159 $id = (int)$this->userDialogParams['INITIAL_PRICE_TYPE'];
160 if ($id > 0)
161 $catalogGroups[$id] = $id;
162 unset($id);
163 }
164 if (isset($this->userDialogParams['PRICE_TYPE']))
165 {
166 $id = (int)$this->userDialogParams['PRICE_TYPE'];
167 if ($id > 0)
168 $catalogGroups[$id] = $id;
169 unset($id);
170 }
171
172 $filterList = array("@CATALOG_GROUP_ID" => $catalogGroups);
173
174 return $filterList;
175 }
176
183 private function calculateResultPrice($price)
184 {
185 $userDialogParams = $this->userDialogParams;
186 $valueChangingPrice = $userDialogParams['VALUE_CHANGING'];
187
188 if ($userDialogParams['UNITS'] === "percent")
189 {
190 $price = ($price * (100 + $valueChangingPrice) / 100);
191 }
192 elseif ($userDialogParams['UNITS'] === "multiple")
193 {
194 if ($valueChangingPrice > 0)
195 {
196 $price = $price * $valueChangingPrice;
197 }
198 else
199 {
200 $price = $price / $valueChangingPrice * (-1);
201 }
202 }
203 else
204 {
205 $price = $price + $valueChangingPrice;
206 }
207
208 switch ($userDialogParams['FORMAT_RESULTS'])
209 {
210 case "floor":
211 $price = floor($price * $userDialogParams['RESULT_MASK']) / $userDialogParams['RESULT_MASK'] - $userDialogParams['DIFFERENCE_VALUE'] ;
212 break;
213 case "ceil":
214 $price = ceil($price * $userDialogParams['RESULT_MASK']) / $userDialogParams['RESULT_MASK'] - $userDialogParams['DIFFERENCE_VALUE'] ;
215 break;
216 default:
217 $price = round($price * $userDialogParams['RESULT_MASK']) / $userDialogParams['RESULT_MASK'] - $userDialogParams['DIFFERENCE_VALUE'] ;
218 break;
219 }
220
221 unset($userDialogParams);
222
223 return $price;
224 }
225
232 public function updatePrices($productsIdList)
233 {
234 $result = new Main\Result();
235
236 if ($this->userDialogParams == false)
237 {
238 $result->addError(
239 new Main\Error("IBLIST_CHPRICE_ERROR_WRONG_INPUT_VALUE", null)
240 );
241 return $result;
242 }
243
244 if($this->userDialogParams['UNITS'] === null)
245 {
246 $result->addError(
247 new Main\Error("IBLIST_CHPRICE_ERROR_WRONG_CURRENCY")
248 );
249 return $result;
250 }
251
252 if (!empty( $productsIdList['SECTIONS']) )
253 {
254 $this->collectAllSectionsElements($productsIdList);
255 }
256
257 if (\CCatalogSku::GetInfoByProductIBlock($this->iblockId))
258 {
259 $priceElementsListSplitedByType = $this->collectPriceSkuElementsId($productsIdList);
260 }
261 else
262 {
263 $priceElementsListSplitedByType['SIMPLE_ELEMENTS'] = $productsIdList['ELEMENTS'];
264 }
265 $parameters = array(
266 "select" => array(
267 'ID',
268 'PRODUCT_ID',
269 'CATALOG_GROUP_ID',
270 'PRICE',
271 'CURRENCY',
272 'EXTRA_ID',
273 'QUANTITY_FROM',
274 'QUANTITY_TO',
275 'ELEMENT_NAME' => 'ELEMENT.NAME',
276 'ELEMENT_IBLOCK_ID' => 'ELEMENT.IBLOCK_ID'
277 ),
278 "filter" => $this->initFilterParams(),
279 'order' => array('PRODUCT_ID' => 'ASC', 'CATALOG_GROUP_ID' => 'ASC')
280 );
281
282 $group = Catalog\GroupTable::getList(array(
283 'select' => array('ID'),
284 'filter' => array('=BASE'=>'Y')
285 ))->fetch();
286 $basePriceId = (!empty($group) ? (int)$group['ID'] : 0);
287 unset($group);
288
289 $initialType = 0;
290 if (isset($this->userDialogParams['INITIAL_PRICE_TYPE']))
291 {
292 $id = (int)$this->userDialogParams['INITIAL_PRICE_TYPE'];
293 if ($id > 0)
294 $initialType = $id;
295 unset($id);
296 }
297
298 $targetType = 0;
299 if (isset($this->userDialogParams['PRICE_TYPE']))
300 {
301 $id = (int)$this->userDialogParams['PRICE_TYPE'];
302 if ($id > 0)
303 $targetType = $id;
304 unset($id);
305 }
306
307 if ($targetType == 0)
308 return $result;
309
310 if ($initialType > 0 && $targetType == $initialType)
311 return $result;
312
313 Catalog\Product\Sku::enableDeferredCalculation();
314 foreach ($priceElementsListSplitedByType as $typeElements => $priceElementsIdList)
315 {
316 $priceElementsIdList = array_chunk($priceElementsIdList, 500);
317 foreach ($priceElementsIdList as $productIdList)
318 {
319 $parameters['filter']['@PRODUCT_ID'] = $productIdList;
320
321 $cpriceResult = Catalog\Model\Price::getList($parameters);
322
323 $elementsCPriceList = array();
324
325 while ($row = $cpriceResult->fetch())
326 {
327 $row['PRODUCT_TYPE_CODE'] = $typeElements;
328 $productId = (int)$row['PRODUCT_ID'];
329 if (!isset($elementsCPriceList[$productId]))
330 $elementsCPriceList[$productId] = array(
331 'QUANTITY' => array(),
332 'SIMPLE' => array()
333 );
334 $priceType = (int)$row['CATALOG_GROUP_ID'];
335 if ($row['QUANTITY_FROM'] !== null || $row['QUANTITY_TO'] !== null)
336 {
337 $hash = ($row['QUANTITY_FROM'] === null ? 'ZERO' : $row['QUANTITY_FROM']).
338 '-'.($row['QUANTITY_TO'] === null ? 'INF' : $row['QUANTITY_TO']);
339 if (!isset($elementsCPriceList[$productId]['QUANTITY'][$hash]))
340 $elementsCPriceList[$productId]['QUANTITY'][$hash] = array();
341 $elementsCPriceList[$productId]['QUANTITY'][$hash][$priceType] = $row;
342 unset($hash);
343 }
344 else
345 {
346 $elementsCPriceList[$productId]['SIMPLE'][$priceType] = $row;
347 }
348 }
349
350 if (!empty($elementsCPriceList))
351 {
352 foreach ($elementsCPriceList as $productId => $prices)
353 {
354 foreach ($prices as $key => $data)
355 {
356 if (empty($data))
357 unset($prices[$key]);
358 }
359 unset($key, $data);
360
361 if (count($prices) !== 1)
362 continue;
363
364 if (!empty($prices['QUANTITY']))
365 {
366 foreach ($prices['QUANTITY'] as $hash => $rangePrices)
367 {
368 if (!empty($rangePrices))
369 $this->updatePriceBlock($productId, $rangePrices, $basePriceId);
370 }
371 unset($hash, $rangePrices);
372 }
373
374 if (!empty($prices['SIMPLE']))
375 {
376 $this->updatePriceBlock($productId, $prices['SIMPLE'], $basePriceId);
377 }
378 }
379 unset($productId, $prices);
380 }
381 unset($elementsCPriceList);
382 }
383 }
384 Catalog\Product\Sku::disableDeferredCalculation();
385 Catalog\Product\Sku::calculate();
386 Catalog\Model\Price::clearCache();
387
388 return $result;
389 }
390
391 private function updatePriceBlock($productId, array $prices, $basePriceId)
392 {
393 $result = new Main\Result();
394
395 $initialType = 0;
396 if (isset($this->userDialogParams['INITIAL_PRICE_TYPE']))
397 {
398 $id = (int)$this->userDialogParams['INITIAL_PRICE_TYPE'];
399 if ($id > 0)
400 $initialType = $id;
401 unset($id);
402 }
403
404 $targetType = 0;
405 if (isset($this->userDialogParams['PRICE_TYPE']))
406 {
407 $id = (int)$this->userDialogParams['PRICE_TYPE'];
408 if ($id > 0)
409 $targetType = $id;
410 unset($id);
411 }
412
413 if (!empty($prices))
414 {
415 $destinationPrice = null;
416 if ($initialType > 0)
417 {
418 if (isset($prices[$initialType]))
419 {
420 $sourcePrice = $prices[$initialType];
421 $destinationPrice = $prices[$initialType];
422 unset($destinationPrice['ID']);
423 $destinationPrice['EXTRA_ID'] = false;
424 $destinationPrice['CATALOG_GROUP_ID'] = $targetType;
425 if (isset($prices[$targetType]))
426 $destinationPrice = $prices[$targetType];
427 if (
428 $this->userDialogParams['UNITS'] != 'currency'
429 || (
430 $sourcePrice['CURRENCY'] == $this->userDialogParams['CURRENCY']
431 && $destinationPrice['CURRENCY'] == $this->userDialogParams['CURRENCY']
432 )
433 )
434 $destinationPrice['PRICE'] = $this->calculateResultPrice($sourcePrice['PRICE']);
435 else
436 $destinationPrice = null;
437 unset($sourcePrice);
438 }
439 }
440 else
441 {
442 if (isset($prices[$targetType]))
443 {
444 $destinationPrice = $prices[$targetType];
445 if (
446 $this->userDialogParams['UNITS'] != 'currency'
447 || $destinationPrice['CURRENCY'] == $this->userDialogParams['CURRENCY']
448 )
449 $destinationPrice['PRICE'] = $this->calculateResultPrice($destinationPrice['PRICE']);
450 else
451 $destinationPrice = null;
452 }
453 }
454 if (!empty($destinationPrice))
455 {
456 if ($destinationPrice['PRICE'] < 0)
457 {
458 $result->addError(
459 new Main\Error("IBLIST_CHPRICE_ERROR_WRONG_VALUE_".$destinationPrice['PRODUCT_TYPE_CODE'],
460 array(
461 '#ID#' => $destinationPrice['PRODUCT_ID'],
462 '#NAME#' => $destinationPrice['ELEMENT_NAME'],
463 )
464 )
465 );
466 }
467 elseif ($destinationPrice['EXTRA_ID'] > 0)
468 {
469 $result->addError(
470 new Main\Error("IBLIST_CHPRICE_ERROR_PRICE_WITH_EXTRA_".$destinationPrice['PRODUCT_TYPE_CODE'],
471 array(
472 '#ID#' => $destinationPrice['PRODUCT_ID'],
473 '#NAME#' => $destinationPrice['ELEMENT_NAME'],
474 )
475 )
476 );
477 }
478 else
479 {
480 if (!empty($destinationPrice['ID']))
481 {
482 $data = [
483 'fields' => [
484 'PRICE' => $destinationPrice['PRICE'],
485 'CURRENCY' => $destinationPrice['CURRENCY']
486 ],
487 'external_fields' => [
488 'IBLOCK_ID' => $destinationPrice['ELEMENT_IBLOCK_ID']
489 ]
490 ];
491 if ($basePriceId == $targetType)
492 {
493 $data['actions']['RECOUNT_PRICES'] = true;
494 }
495 $priceResult = Catalog\Model\Price::update($destinationPrice['ID'], $data);
496 unset($data);
497 }
498 else
499 {
500 $priceResult = Catalog\Model\Price::add([
501 'PRODUCT_ID' => $productId,
502 'CATALOG_GROUP_ID' => $targetType,
503 'PRICE' => $destinationPrice['PRICE'],
504 'CURRENCY' => $destinationPrice['CURRENCY'],
505 'EXTRA_ID' => $destinationPrice['EXTRA_ID'],
506 'QUANTITY_FROM' => $destinationPrice['QUANTITY_FROM'],
507 'QUANTITY_TO' => $destinationPrice['QUANTITY_TO']
508 ]);
509
510 }
511 if ($priceResult->isSuccess())
512 {
513 Iblock\PropertyIndex\Manager::updateElementIndex($destinationPrice['ELEMENT_IBLOCK_ID'], $destinationPrice['PRODUCT_ID']);
514 $ipropValues = new Iblock\InheritedProperty\ElementValues($destinationPrice['ELEMENT_IBLOCK_ID'], $destinationPrice['PRODUCT_ID']);
515 $ipropValues->clearValues();
516 unset($ipropValues);
517 }
518 unset($priceResult);
519 }
520 }
521 unset($destinationPrice);
522 }
523 }
524}
__construct(array $userDialogParams, $iblockId)