Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
providercreator.php
1<?php
2
4
8
14{
15 private $context = array();
16 private $pool = array();
17
23 public static function create(array $context)
24 {
25 $creator = new static();
26 $creator->context = $context;
27
28 return $creator;
29 }
30
34 public function addBasketItem(Sale\BasketItemBase $basketItem)
35 {
36 $providerName = $basketItem->getProviderName();
37 if (empty($providerName))
38 {
39 $providerName = $basketItem->getCallbackFunction();
40 }
41 $builder = $this->createBuilder($providerName);
42 $builder->addProductByBasketItem($basketItem);
43 }
44
48 public function addShipmentItem(Sale\ShipmentItem $shipmentItem)
49 {
50 $basketItem = $shipmentItem->getBasketItem();
51 if (!$basketItem)
52 {
53 return;
54 }
55
56 $providerName = $basketItem->getProviderName();
57 if (empty($providerName))
58 {
59 $providerName = $basketItem->getCallbackFunction();
60 }
61 $builder = $this->createBuilder($providerName);
62
63 $builder->addProductByShipmentItem($shipmentItem);
64 }
65
69 public function addProductData(array $productData)
70 {
71 $builder = $this->createBuilder($productData['PROVIDER_NAME']);
72 $builder->addProductData($productData);
73 }
74
79 public function addBasketItemBarcodeData(Sale\BasketItem $basketItem, array $barcodeParams)
80 {
81 $providerName = $basketItem->getProviderName();
82 if (empty($providerName))
83 {
84 $providerName = $basketItem->getCallbackFunction();
85 }
86 $builder = $this->createBuilder($providerName);
87 $builder->addBasketItemBarcodeData($barcodeParams);
88 }
96 public function createItemForShip(Sale\ShipmentItem $shipmentItem, array $needShipList = [])
97 {
98 $basketItem = $shipmentItem->getBasketItem();
99
100 $shipment = $shipmentItem->getCollection()->getShipment();
101
102 $quantity = $shipmentItem->getQuantity();
103
104 if ($shipment->needShip() == Sale\Internals\Catalog\Provider::SALE_TRANSFER_PROVIDER_SHIPMENT_NEED_SHIP)
105 {
106 if ($quantity > 0)
107 {
108 $quantity *= -1;
109 }
110 }
111
112 $needUseReserve = $quantity < 0 || Sale\Configuration::isEnableAutomaticReservation();
113
114 $providerName = $basketItem->getProviderName();
115 $providerName = $this->clearProviderName($providerName);
116 if (empty($needShipList[$providerName]) && $shipmentItem->getReservedQuantity() > 0)
117 {
118 $quantity = 0;
119 }
120
121 $item = [
122 'PROVIDER_NAME' => $basketItem->getProviderName(),
123 'SHIPMENT_ITEM' => $shipmentItem,
124 'BASKET_ITEM' => $basketItem,
125 'QUANTITY' => $quantity,
126 'RESERVED_QUANTITY_BY_STORE' => [
127 $shipmentItem->getInternalIndex() => []
128 ],
129 ];
130
131 $storeData = Sale\Internals\Catalog\Provider::createMapShipmentItemStoreData($shipmentItem, $needUseReserve);
132 if ($storeData)
133 {
134 $item['STORE_DATA'] = $storeData;
135
136 $needReserveByStore = [];
137 foreach ($storeData as $data)
138 {
139 $item['RESERVED_QUANTITY_BY_STORE'][$shipmentItem->getInternalIndex()][$data['STORE_ID']] = $data['RESERVED_QUANTITY'];
140
141 $needReserveByStore[$data['STORE_ID']] = $data['RESERVED_QUANTITY'] > 0;
142 }
143
144 $item['RESERVED_QUANTITY'] = array_sum($item['RESERVED_QUANTITY_BY_STORE'][$shipmentItem->getInternalIndex()]);
145 $item['NEED_RESERVE'] = $item['RESERVED_QUANTITY'] > 0;
146 $item['NEED_RESERVE_BY_STORE'] = [
147 $shipmentItem->getInternalIndex() => $needReserveByStore
148 ];
149 }
150 else
151 {
152 $item['RESERVED_QUANTITY'] = $needUseReserve ? $basketItem->getReservedQuantity() : 0;
153 $item['NEED_RESERVE'] = $item['RESERVED_QUANTITY'] > 0;
154 }
155
156 return $item;
157 }
158
165 public function createItemForReserveByShipmentItem(Sale\ShipmentItem $shipmentItem) : array
166 {
167 $basketItem = $shipmentItem->getBasketItem();
168
169 $result = [
170 'PROVIDER_NAME' => $basketItem->getProviderName(),
171 'BASKET_ITEM' => $basketItem,
172 'SHIPMENT_ITEM' => $shipmentItem,
173 'QUANTITY' => 0,
174 'RESERVED_QUANTITY' => 0,
175 ];
176
177 if (!$basketItem->isReservableItem())
178 {
179 return $result;
180 }
181
182 $shipmentItemQuantity = $shipmentItem->getQuantity();
183 if ($shipmentItemQuantity == 0)
184 {
185 $storeId = Sale\Configuration::getDefaultStoreId();
186
187 $result['QUANTITY_BY_STORE'][$storeId] = $shipmentItemQuantity - $shipmentItem->getReservedQuantity();
188 $result['QUANTITY'] += $result['QUANTITY_BY_STORE'][$storeId];
189
190 $result['RESERVED_QUANTITY_BY_STORE'][$storeId] = $shipmentItem->getReservedQuantity();
191 $result['RESERVED_QUANTITY'] += $result['RESERVED_QUANTITY_BY_STORE'][$storeId];
192 }
193 else
194 {
195 $quantityStoreList = [];
196
198 $shipmentItemStoreCollection = $shipmentItem->getShipmentItemStoreCollection();
199 if ($shipmentItemStoreCollection)
200 {
202 foreach ($shipmentItemStoreCollection as $itemStore)
203 {
204 $storeId = $itemStore->getStoreId();
205 if (!isset($quantityStoreList[$storeId]))
206 {
207 $quantityStoreList[$storeId] = 0;
208 }
209
210 $quantityStoreList[$storeId] += $itemStore->getQuantity();
211 $shipmentItemQuantity -= $itemStore->getQuantity();
212 }
213 }
214
215 if ($shipmentItemQuantity > 0)
216 {
217 $storeId = Sale\Configuration::getDefaultStoreId();
218 if (!isset($quantityStoreList[$storeId]))
219 {
220 $quantityStoreList[$storeId] = 0;
221 }
222
223 $quantityStoreList[$storeId] += $shipmentItemQuantity;
224 }
225
226 $result['QUANTITY_BY_STORE'] = [];
227 $result['RESERVED_QUANTITY_BY_STORE'] = [];
228
229 $shipmentItemReservedQuantity = $shipmentItem->getReservedQuantity();
230 foreach ($quantityStoreList as $storeId => $quantity)
231 {
232 $reserveQuantity = 0;
233
235 $reserveQuantityCollection = $basketItem->getReserveQuantityCollection();
236
237 if ($reserveQuantityCollection && $shipmentItemReservedQuantity > 0)
238 {
239 $reserveQuantity = $reserveQuantityCollection->getQuantityByStoreId($storeId);
240 if ($reserveQuantity > $shipmentItemReservedQuantity)
241 {
242 $reserveQuantity = $shipmentItemReservedQuantity;
243 }
244
245 $shipmentItemReservedQuantity -= $reserveQuantity;
246 }
247
248 $result['QUANTITY_BY_STORE'][$storeId] = $quantity - $reserveQuantity;
249 $result['QUANTITY'] += $result['QUANTITY_BY_STORE'][$storeId];
250
251 $result['RESERVED_QUANTITY_BY_STORE'][$storeId] = $reserveQuantity;
252 $result['RESERVED_QUANTITY'] += $result['RESERVED_QUANTITY_BY_STORE'][$storeId];
253 }
254 }
255
256 return $result;
257 }
258
264 public function createItemForReserve(Sale\ReserveQuantity $reserve)
265 {
266 $basketItem = $reserve->getCollection()->getBasketItem();
267
268 $originalFields = $reserve->getFields()->getOriginalValues();
269 $reservedQuantity = $originalFields['QUANTITY'] ?? 0;
270 $quantity = $reserve->getField('QUANTITY') - $reservedQuantity;
271
272 return [
273 'PROVIDER_NAME' => $basketItem->getProviderName(),
274 'RESERVE_ITEM' => $reserve,
275 'BASKET_ITEM' => $basketItem,
276 'QUANTITY' => $quantity,
277 'QUANTITY_BY_STORE' => [
278 $reserve->getStoreId() => $quantity
279 ],
280 'RESERVED_QUANTITY' => $reservedQuantity,
281 'RESERVED_QUANTITY_BY_STORE' => [
282 $reserve->getStoreId() => $reservedQuantity
283 ]
284 ];
285 }
286
290 public function getProductData()
291 {
292 return $this->callBuilderMethod('getProductData', ['PRODUCT_DATA_LIST']);
293 }
294
298 public function getAvailableQuantity()
299 {
300 return $this->callBuilderMethod('getAvailableQuantity', ['AVAILABLE_QUANTITY_LIST']);
301 }
302
307 {
308 return $this->callBuilderMethod('getAvailableQuantityByStore', ['AVAILABLE_QUANTITY_LIST_BY_STORE']);
309 }
310
315 {
316 return $this->callBuilderMethod('getAvailableQuantityAndPrice', ['PRODUCT_DATA_LIST']);
317 }
318
325 public function setItemsResultAfterTryShip(PoolQuantity $pool, array $productTryShipList)
326 {
327 $result = new Sale\Result();
328
330 foreach ($this->pool as $builder)
331 {
332 $providerName = $builder->getProviderName();
333
334 if (!$productTryShipList[$providerName])
335 {
336 continue;
337 }
338
339 $r = $builder->setItemsResultAfterTryShip($pool, $productTryShipList[$providerName]);
340 if (!$r->isSuccess())
341 {
342 $result->addErrors($r->getErrors());
343 }
344 }
345
346 return $result;
347 }
348
354 public function setItemsResultAfterShip(Sale\Result $resultAfterShip)
355 {
356 return $this->callBuilderMethod('setItemsResultAfterShip', ['RESULT_AFTER_SHIP_LIST'], $resultAfterShip);
357 }
358
364 public function createItemsResultAfterDeliver(Sale\Result $resultAfterDeliver)
365 {
366 return $this->callBuilderMethod('createItemsResultAfterDeliver', ['RESULT_AFTER_DELIVER_LIST'], $resultAfterDeliver);
367 }
368
369
373 public function tryShip()
374 {
375 return $this->callBuilderMethod('tryShip', ['TRY_SHIP_PRODUCTS_LIST']);
376 }
377
381 public function isNeedShip()
382 {
383 return $this->callBuilderMethod('isNeedShip', ['IS_NEED_SHIP']);
384 }
385
386
390 public function checkBarcode()
391 {
392 return $this->callBuilderMethod('checkBarcode', ['BARCODE_CHECK_LIST']);
393 }
394
398 public function reserve()
399 {
400 return $this->callBuilderMethod('reserve', ['RESERVED_PRODUCTS_LIST']);
401 }
402
406 public function ship()
407 {
408 return $this->callBuilderMethod('ship', ['SHIPPED_PRODUCTS_LIST']);
409 }
410
414 public function getBundleItems()
415 {
416 return $this->callBuilderMethod('getBundleItems', ['BUNDLE_LIST']);
417 }
418
422 public function deliver()
423 {
424 return $this->callBuilderMethod('deliver', ['DELIVER_PRODUCTS_LIST']);
425 }
426
430 public function viewProduct()
431 {
432 return $this->callBuilderMethod('viewProduct', ['VIEW_PRODUCTS_LIST']);
433 }
434
438 public function getProductStores()
439 {
440 return $this->callBuilderMethod('getProductStores', ['PRODUCT_STORES_LIST']);
441 }
442
446 public function recurring()
447 {
448 return $this->callBuilderMethod('recurring', ['RECURRING_PRODUCTS_LIST']);
449 }
450
456 public function createItemsResultAfterRecurring(Sale\Result $resultAfterDeliver)
457 {
458 return $this->callBuilderMethod('createItemsResultAfterDeliver', ['RESULT_AFTER_DELIVER_LIST'], $resultAfterDeliver);
459 }
460
466 {
467 return $this->callBuilderMethod('returnProductBatches', []);
468 }
469
475 {
476 return $this->callBuilderMethod('writeOffProductBatches', []);
477 }
478
487 private function callBuilderMethod($method, array $outputNames, $methodParameters = null)
488 {
489 $result = new Sale\Result();
490
491 $resultList = array();
492
494 foreach ($this->pool as $builder)
495 {
496 if (!method_exists($builder, $method))
497 {
498 throw new Main\ArgumentOutOfRangeException('method');
499 }
500
501 if (!$methodParameters)
502 {
504 $compatibilityOutputName = $outputNames[0];
506 $r = $builder->$method($compatibilityOutputName);
507 }
508 else
509 {
511 $r = $builder->$method($methodParameters);
512 }
513
514 if (!$r->isSuccess())
515 {
516 $result->addErrors($r->getErrors());
517 }
518
519 if ($r->hasWarnings())
520 {
521 $result->addWarnings($r->getWarnings());
522 }
523
524 $data = $r->getData();
525 if (!empty($data))
526 {
527 $providerName = null;
528
529 $providerClass = $builder->getProviderClass();
530 if ($providerClass)
531 {
532 $reflect = new \ReflectionClass($providerClass);
533 $providerName = $this->clearProviderName($reflect->getName());
534 }
535
536 if (empty($providerName))
537 {
538 $providerName = $builder->getCallbackFunction();
539 }
540
541 foreach ($outputNames as $outputName)
542 {
543 if (!empty($data[$outputName]))
544 {
545 $resultList[$outputName] = [
546 $providerName => $data[$outputName],
547 ];
548 }
549 }
550 }
551 }
552
553 if (!empty($resultList))
554 {
555 $result->setData($resultList);
556 }
557
558 return $result;
559 }
560
566 private function createBuilder($providerName)
567 {
568 if (!$this->isExistsProvider($providerName))
569 {
570 $providerClass = null;
571
572 if (!empty($providerName) && class_exists($providerName))
573 {
574 $providerClass = new $providerName($this->getContext());
575 }
576
577 if (!$providerClass)
578 {
579 $providerClass = $providerName;
580 }
581
582 $builder = ProviderBuilderBase::createBuilder($providerClass, $this->getContext());
583
584 $this->addBuilder($providerName, $builder);
585 }
586 else
587 {
588 $builder = $this->getBuilder($providerName);
589 }
590
591 return $builder;
592 }
593
598 private function addBuilder($providerName, ProviderBuilderBase $builder)
599 {
600 $providerName = $this->clearProviderName($providerName);
601
602 $this->pool[$providerName] = $builder;
603 }
604
610 private function getBuilder($providerName)
611 {
612 $providerName = $this->clearProviderName($providerName);
613
614 if ($this->isExistsProvider($providerName))
615 {
616 return $this->pool[$providerName];
617 }
618
619 return false;
620 }
626 private function isExistsProvider($providerName)
627 {
628 $providerName = $this->clearProviderName($providerName);
629 return (isset($this->pool[$providerName]));
630 }
631
635 private function getContext()
636 {
637 return $this->context;
638 }
639
645 private function clearProviderName($providerName)
646 {
647 if (!empty($providerName) && $providerName[0] == "\\")
648 {
649 $providerName = ltrim($providerName, '\\');
650 }
651
652 return $providerName;
653 }
654}
static createBuilder($providerClass, $context)
addShipmentItem(Sale\ShipmentItem $shipmentItem)
setItemsResultAfterShip(Sale\Result $resultAfterShip)
createItemForReserve(Sale\ReserveQuantity $reserve)
addBasketItem(Sale\BasketItemBase $basketItem)
createItemsResultAfterDeliver(Sale\Result $resultAfterDeliver)
addBasketItemBarcodeData(Sale\BasketItem $basketItem, array $barcodeParams)
createItemForShip(Sale\ShipmentItem $shipmentItem, array $needShipList=[])
createItemsResultAfterRecurring(Sale\Result $resultAfterDeliver)