Bitrix-D7  20.5.0
providercreator.php
См. документацию.
1 <?php
2 
3 namespace Bitrix\Sale\Internals;
4 
5 use Bitrix\Main;
6 use Bitrix\Sale;
7 
8 /**
9  * Class ProviderCreator
10  * @package Bitrix\Sale\Internals
11  */
13 {
14  private $context = array();
15  private $pool = array();
16 
17  /**
18  * @param array $context
19  *
20  * @return static
21  */
22  public static function create(array $context)
23  {
24  $creator = new static();
25  $creator->context = $context;
26 
27  return $creator;
28  }
29 
30  /**
31  * @param Sale\BasketItemBase $basketItem
32  */
33  public function addBasketItem(Sale\BasketItemBase $basketItem)
34  {
35  $providerName = $basketItem->getProviderName();
36  if (empty($providerName))
37  {
38  $providerName = $basketItem->getCallbackFunction();
39  }
40  $builder = $this->createBuilder($providerName);
41  $builder->addProductByBasketItem($basketItem);
42  }
43 
44  /**
45  * @param Sale\ShipmentItem $shipmentItem
46  */
47  public function addShipmentItem(Sale\ShipmentItem $shipmentItem)
48  {
49  $basketItem = $shipmentItem->getBasketItem();
50  if (!$basketItem)
51  {
52  return;
53  }
54 
55  $providerName = $basketItem->getProviderName();
56  if (empty($providerName))
57  {
58  $providerName = $basketItem->getCallbackFunction();
59  }
60  $builder = $this->createBuilder($providerName);
61 
62  $builder->addProductByShipmentItem($shipmentItem);
63  }
64 
65  /**
66  * @param array $shipmentProductData
67  */
68  public function addShipmentProductData(array $shipmentProductData)
69  {
70  $builder = $this->createBuilder($shipmentProductData['PROVIDER_NAME']);
71  $builder->addProductByShipmentProductData($shipmentProductData);
72  }
73 
74  /**
75  * @param array $productData
76  *
77  * @throws Main\ArgumentNullException
78  */
79  public function addProductData(array $productData)
80  {
81  if (empty($productData['PRODUCT_ID']))
82  {
83  throw new Main\ArgumentNullException('PRODUCT_ID');
84  }
85 
86  if (empty($productData['PROVIDER_NAME']))
87  {
88  throw new Main\ArgumentNullException('PROVIDER_NAME');
89  }
90 
91  $builder = $this->createBuilder($productData['PROVIDER_NAME']);
92  $builder->addProductById($productData['PRODUCT_ID']);
93  }
94 
95  /**
96  * @param Sale\BasketItem $basketItem
97  * @param array $barcodeParams
98  */
99  public function addBasketItemBarcodeData(Sale\BasketItem $basketItem, array $barcodeParams)
100  {
101  $providerName = $basketItem->getProviderName();
102  if (empty($providerName))
103  {
104  $providerName = $basketItem->getCallbackFunction();
105  }
106  $builder = $this->createBuilder($providerName);
107  $builder->addBasketItemBarcodeData($barcodeParams);
108  }
109  /**
110  * @param Sale\ShipmentItem $shipmentItem
111  * @param array $needShipList
112  *
113  * @return array
114  * @throws Main\ObjectNotFoundException
115  */
116  public function createItemForShip(Sale\ShipmentItem $shipmentItem, array $needShipList = [])
117  {
118  $basketItem = $shipmentItem->getBasketItem();
119 
120  /** @var Sale\ShipmentItemCollection $shipmentItemCollection */
121  $shipmentItemCollection = $shipmentItem->getCollection();
122 
123  if (!$shipmentItemCollection)
124  {
125  throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
126  }
127 
128  $shipment = $shipmentItemCollection->getShipment();
129  if (!$shipment)
130  {
131  throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
132  }
133 
134  $quantity = floatval($shipmentItem->getQuantity());
135 
136  if ($shipment->needShip() == Sale\Internals\Catalog\Provider::SALE_TRANSFER_PROVIDER_SHIPMENT_NEED_SHIP)
137  {
138  if ($quantity > 0)
139  {
140  $quantity *= -1;
141  }
142  }
143 
144  $providerName = $basketItem->getProviderName();
145  $providerName = static::clearProviderName($providerName);
146  if (empty($needShipList[$providerName]) && $shipmentItem->getReservedQuantity() > 0)
147  {
148  $quantity = 0;
149  }
150 
151  return array(
152  'PROVIDER_NAME' => $basketItem->getProviderName(),
153  'SHIPMENT_ITEM' => $shipmentItem,
154  'QUANTITY' => $quantity,
155  'RESERVED_QUANTITY' => $shipmentItem->getReservedQuantity(),
156  'NEED_RESERVE' => $shipmentItem->needReserve(),
157  );
158  }
159 
160  /**
161  * @param Sale\ShipmentItem $shipmentItem
162  *
163  * @return array
164  * @throws Main\ObjectNotFoundException
165  */
166  public function createItemForReserve(Sale\ShipmentItem $shipmentItem)
167  {
168  return $this->createMapForReserve($shipmentItem);
169  }
170 
171  /**
172  * @param Sale\ShipmentItem $shipmentItem
173  *
174  * @return array
175  * @throws Main\ObjectNotFoundException
176  */
177  public function createItemForUnreserve(Sale\ShipmentItem $shipmentItem)
178  {
179  return $this->createMapForReserve($shipmentItem, false);
180  }
181 
182  /**
183  * @param Sale\ShipmentItem $shipmentItem
184  * @param bool $reserve
185  *
186  * @return array
187  * @throws Main\ObjectNotFoundException
188  */
189  private function createMapForReserve(Sale\ShipmentItem $shipmentItem, $reserve = true)
190  {
191  $basketItem = $shipmentItem->getBasketItem();
192 
193  /** @var Sale\ShipmentItemCollection $shipmentItemCollection */
194  $shipmentItemCollection = $shipmentItem->getCollection();
195  if (!$shipmentItemCollection)
196  {
197  throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
198  }
199 
200  $shipment = $shipmentItemCollection->getShipment();
201  if (!$shipment)
202  {
203  throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
204  }
205 
206  $quantity = floatval($shipmentItem->getQuantity() - $shipmentItem->getReservedQuantity());
207 
208  if (!$reserve)
209  {
210  $quantity = -1 * $shipmentItem->getReservedQuantity();
211  }
212 
213  return array(
214  'PROVIDER_NAME' => $basketItem->getProviderName(),
215  'SHIPMENT_ITEM' => $shipmentItem,
216  'QUANTITY' => $quantity,
217  'RESERVED_QUANTITY' => $shipmentItem->getReservedQuantity(),
218  );
219  }
220 
221 
222  /**
223  * @return Sale\Result
224  */
225  public function getProductData()
226  {
227  return $this->callBuilderMethod('getProductData', 'PRODUCT_DATA_LIST');
228  }
229 
230  /**
231  * @return Sale\Result
232  */
233  public function getAvailableQuantity()
234  {
235  return $this->callBuilderMethod('getAvailableQuantity', 'AVAILABLE_QUANTITY_LIST');
236  }
237 
238  /**
239  * @return Sale\Result
240  */
242  {
243  return $this->callBuilderMethod('getAvailableQuantityAndPrice', 'PRODUCT_DATA_LIST');
244  }
245 
246  /**
247  * @param PoolQuantity $pool
248  * @param array $productTryShipList
249  *
250  * @return Sale\Result
251  */
252  public function setItemsResultAfterTryShip(PoolQuantity $pool, array $productTryShipList)
253  {
254  $result = new Sale\Result();
255 
256  /** @var ProviderBuilderBase $builder */
257  foreach ($this->pool as $builder)
258  {
259  $providerName = $builder->getProviderName();
260 
261  if (!$productTryShipList[$providerName])
262  {
263  continue;
264  }
265 
266  $r = $builder->setItemsResultAfterTryShip($pool, $productTryShipList[$providerName]);
267  if (!$r->isSuccess())
268  {
269  $result->addErrors($r->getErrors());
270  }
271  }
272 
273  return $result;
274  }
275 
276  /**
277  * @param Sale\Result $resultAfterReserve
278  *
279  * @return Sale\Result
280  */
281  public function setItemsResultAfterReserve(Sale\Result $resultAfterReserve)
282  {
283  return $this->callBuilderMethod('setItemsResultAfterReserve', 'RESULT_AFTER_RESERVE_LIST', $resultAfterReserve);
284  }
285 
286  /**
287  * @param Sale\Result $resultAfterShip
288  *
289  * @return Sale\Result
290  */
291  public function setItemsResultAfterShip(Sale\Result $resultAfterShip)
292  {
293  return $this->callBuilderMethod('setItemsResultAfterShip', 'RESULT_AFTER_SHIP_LIST', $resultAfterShip);
294  }
295 
296  /**
297  * @param Sale\Result $resultAfterDeliver
298  *
299  * @return Sale\Result
300  */
301  public function createItemsResultAfterDeliver(Sale\Result $resultAfterDeliver)
302  {
303  return $this->callBuilderMethod('createItemsResultAfterDeliver', 'RESULT_AFTER_DELIVER_LIST', $resultAfterDeliver);
304  }
305 
306 
307  /**
308  * @return Sale\Result
309  */
310  public function tryShip()
311  {
312  return $this->callBuilderMethod('tryShip', 'TRY_SHIP_PRODUCTS_LIST');
313  }
314 
315  /**
316  * @return Sale\Result
317  */
318  public function isNeedShip()
319  {
320  return $this->callBuilderMethod('isNeedShip', 'IS_NEED_SHIP');
321  }
322 
323 
324  /**
325  * @return Sale\Result
326  */
327  public function checkBarcode()
328  {
329  return $this->callBuilderMethod('checkBarcode', 'BARCODE_CHECK_LIST');
330  }
331 
332  /**
333  * @return Sale\Result
334  */
335  public function reserve()
336  {
337  return $this->callBuilderMethod('reserve', 'RESERVED_PRODUCTS_LIST');
338  }
339 
340  /**
341  * @return Sale\Result
342  */
343  public function ship()
344  {
345  return $this->callBuilderMethod('ship', 'SHIPPED_PRODUCTS_LIST');
346  }
347 
348  /**
349  * @return Sale\Result
350  */
351  public function getBundleItems()
352  {
353  return $this->callBuilderMethod('getBundleItems', 'BUNDLE_LIST');
354  }
355 
356  /**
357  * @return Sale\Result
358  */
359  public function deliver()
360  {
361  return $this->callBuilderMethod('deliver', 'DELIVER_PRODUCTS_LIST');
362  }
363 
364  /**
365  * @return Sale\Result
366  */
367  public function viewProduct()
368  {
369  return $this->callBuilderMethod('viewProduct', 'VIEW_PRODUCTS_LIST');
370  }
371 
372  /**
373  * @return Sale\Result
374  */
375  public function getProductStores()
376  {
377  return $this->callBuilderMethod('getProductStores', 'PRODUCT_STORES_LIST');
378  }
379 
380  /**
381  * @return Sale\Result
382  */
383  public function recurring()
384  {
385  return $this->callBuilderMethod('recurring', 'RECURRING_PRODUCTS_LIST');
386  }
387 
388  /**
389  * @param Sale\Result $resultAfterDeliver
390  *
391  * @return Sale\Result
392  */
393  public function createItemsResultAfterRecurring(Sale\Result $resultAfterDeliver)
394  {
395  return $this->callBuilderMethod('createItemsResultAfterDeliver', 'RESULT_AFTER_DELIVER_LIST', $resultAfterDeliver);
396  }
397 
398  /**
399  * @param $method
400  * @param $outputName
401  * @param null $methodParameters
402  *
403  * @return Sale\Result
404  * @throws Main\ArgumentOutOfRangeException
405  */
406  private function callBuilderMethod($method, $outputName, $methodParameters = null)
407  {
408  $result = new Sale\Result();
409 
410  $resultList = array();
411 
412  /** @var ProviderBuilderBase $builder */
413  foreach ($this->pool as $builder)
414  {
415  if (!method_exists($builder, $method))
416  {
417  throw new Main\ArgumentOutOfRangeException('method');
418  }
419 
420  if (!$methodParameters)
421  {
422  /** @var Sale\Result $r */
423  $r = $builder->$method($outputName);
424  }
425  else
426  {
427  /** @var Sale\Result $r */
428  $r = $builder->$method($methodParameters);
429  }
430 
431  if (!$r->isSuccess())
432  {
433  $result->addErrors($r->getErrors());
434  }
435 
436  if ($r->hasWarnings())
437  {
438  $result->addWarnings($r->getWarnings());
439  }
440 
441  $data = $r->getData();
442  if (!empty($data))
443  {
444  $providerName = null;
445 
446  $providerClass = $builder->getProviderClass();
447  if ($providerClass)
448  {
449  $reflect = new \ReflectionClass($providerClass);
450  $providerName = $this->clearProviderName($reflect->getName());
451  }
452 
453  if (strval($providerName) == '')
454  {
455  $providerName = $builder->getCallbackFunction();
456  }
457 
458  if (!empty($data[$outputName]))
459  {
460  $resultList[$providerName] = $data[$outputName];
461  }
462  }
463  }
464 
465  if (!empty($resultList))
466  {
467  $result->setData(
468  array(
469  $outputName => $resultList
470  )
471  );
472  }
473 
474  return $result;
475  }
476 
477  /**
478  * @param $providerName
479  *
480  * @return ProviderBuilderBase
481  */
482  private function createBuilder($providerName)
483  {
484  if (!$this->isExistsProvider($providerName))
485  {
486  $providerClass = null;
487 
488  if (class_exists($providerName))
489  {
490  $providerClass = new $providerName($this->getContext());
491  }
492 
493  if (!$providerClass)
494  {
495  $providerClass = $providerName;
496  }
497 
498  $builder = ProviderBuilderBase::createBuilder($providerClass, $this->getContext());
499 
500  $this->addBuilder($providerName, $builder);
501  }
502  else
503  {
504  $builder = $this->getBuilder($providerName);
505  }
506 
507  return $builder;
508  }
509 
510  /**
511  * @param string $providerName
512  * @param ProviderBuilderBase $builder
513  */
514  private function addBuilder($providerName, ProviderBuilderBase $builder)
515  {
516  $providerName = $this->clearProviderName($providerName);
517 
518  $this->pool[$providerName] = $builder;
519  }
520 
521  /**
522  * @param $providerName
523  *
524  * @return ProviderBuilderBase|bool
525  */
526  private function getBuilder($providerName)
527  {
528  $providerName = $this->clearProviderName($providerName);
529 
530  if ($this->isExistsProvider($providerName))
531  {
532  return $this->pool[$providerName];
533  }
534 
535  return false;
536  }
537  /**
538  * @param $providerName
539  *
540  * @return bool
541  */
542  private function isExistsProvider($providerName)
543  {
544  $providerName = $this->clearProviderName($providerName);
545  return (isset($this->pool[$providerName]));
546  }
547 
548  /**
549  * @return array
550  */
551  private function getContext()
552  {
553  return $this->context;
554  }
555 
556  /**
557  * @param $providerName
558  *
559  * @return string
560  */
561  private function clearProviderName($providerName)
562  {
563  if (!empty($providerName) && $providerName[0] == "\\")
564  {
565  $providerName = ltrim($providerName, '\\');
566  }
567 
568  return $providerName;
569  }
570 }
Exception is thrown when "empty" value is passed to a function that does not accept it as a valid arg...
Exception is thrown when the value of an argument is outside the allowable range of values.
Exception is thrown when an object is not present.
static createBuilder($providerClass, $context)
createItemForReserve(Sale\ShipmentItem $shipmentItem)
addShipmentItem(Sale\ShipmentItem $shipmentItem)
setItemsResultAfterTryShip(PoolQuantity $pool, array $productTryShipList)
setItemsResultAfterShip(Sale\Result $resultAfterShip)
setItemsResultAfterReserve(Sale\Result $resultAfterReserve)
addBasketItem(Sale\BasketItemBase $basketItem)
addShipmentProductData(array $shipmentProductData)
createItemsResultAfterDeliver(Sale\Result $resultAfterDeliver)
addBasketItemBarcodeData(Sale\BasketItem $basketItem, array $barcodeParams)
createItemForShip(Sale\ShipmentItem $shipmentItem, array $needShipList=[])
createItemsResultAfterRecurring(Sale\Result $resultAfterDeliver)
createItemForUnreserve(Sale\ShipmentItem $shipmentItem)
Class RestHandler \Handlers\PaySystem.