%PDF- %PDF-
| Direktori : /proc/self/root/home/bitrix/www/bitrix/modules/sale/lib/internals/catalog/ |
| Current File : //proc/self/root/home/bitrix/www/bitrix/modules/sale/lib/internals/catalog/provider.php |
<?php
namespace Bitrix\Sale\Internals\Catalog;
use Bitrix\Main;
use Bitrix\Sale;
use Bitrix\Sale\Internals\PoolQuantity;
use Bitrix\Sale\Internals\ShipmentRules;
/**
* Class Provider
*
* @package Bitrix\Sale\Internals
*/
final class Provider
{
const SALE_TRANSFER_PROVIDER_SHIPMENT_NEED_SHIP = true;
const SALE_TRANSFER_PROVIDER_SHIPMENT_NEED_NOT_SHIP = false;
const SALE_TRANSFER_PROVIDER_SHIPMENT_NEED_EMPTY = null;
private static $ignoreErrors = false;
/**
* @param $basketList
* @param array $context
*
* @return Sale\Result
* @throws Main\ArgumentNullException
* @throws Main\ArgumentTypeException
*/
public static function getProductData($basketList, array $context)
{
$result = new Sale\Result();
if (empty($context))
{
throw new Main\ArgumentNullException('context');
}
if (!is_array($basketList) && !($basketList instanceof Sale\BasketBase))
{
throw new Main\ArgumentTypeException('basketList');
}
$creator = Sale\Internals\ProviderCreator::create($context);
/** @var Sale\BasketItem $basketItem */
foreach ($basketList as $basketItem)
{
$creator->addBasketItem($basketItem);
}
$r = $creator->getProductData();
if ($r->isSuccess())
{
$data = $r->getData();
if (array_key_exists('PRODUCT_DATA_LIST', $data))
{
$result->setData($data);
}
}
else
{
$result->addErrors($r->getErrors());
}
return $result;
}
/**
* @param Sale\BasketItemBase $basketItem
* @param array $context
*
* @return Sale\Result
* @throws Main\ArgumentNullException
*/
public static function getBundleItems(Sale\BasketItemBase $basketItem, array $context)
{
if (empty($context))
{
throw new Main\ArgumentNullException('context');
}
$result = new Sale\Result();
$creator = Sale\Internals\ProviderCreator::create($context);
/** @var Sale\BasketItem $basketItem */
$creator->addBasketItem($basketItem);
$r = $creator->getBundleItems();
if ($r->isSuccess())
{
return $r;
}
else
{
$result->addErrors($r->getErrors());
}
return $result;
}
/**
* @param Sale\BasketItemBase $basketItem
* @param array|null $context
*
* @return Sale\Result
* @throws Main\ObjectNotFoundException
* @throws Main\SystemException
*/
public static function checkAvailableQuantityByBasketItem(Sale\BasketItemBase $basketItem, array $context = array())
{
$result = new Sale\Result();
/** @var \Bitrix\Sale\Basket $basket */
if (!$basket = $basketItem->getCollection())
{
throw new Main\ObjectNotFoundException('Entity "Basket" not found');
}
$order = $basket->getOrder();
if (empty($context) && $order)
{
$context = static::prepareContext($order, $context);
}
$r = static::checkContext($context);
if (!$r->isSuccess())
{
return $r;
}
$quantity = $basketItem->getQuantity();
$productId = $basketItem->getProductId();
$deltaQuantity = $basketItem->getDeltaQuantity();
$poolQuantity = 0;
if ($order)
{
if ($deltaQuantity <= 0)
{
$result->setData(
array(
'AVAILABLE_QUANTITY' => $quantity
)
);
return $result;
}
$pool = PoolQuantity::getInstance($order->getInternalId());
$poolQuantity = $pool->get(PoolQuantity::POOL_RESERVE_TYPE, $productId);
if (!empty($poolQuantity))
{
$tryQuantity = $quantity + $poolQuantity;
if ($tryQuantity == 0)
{
$result->setData(array(
'AVAILABLE_QUANTITY' => $quantity
));
return $result;
}
}
}
$resultList = array();
$creator = Sale\Internals\ProviderCreator::create($context);
/** @var Sale\BasketItem $basketItem */
$creator->addBasketItem($basketItem);
$r = $creator->getAvailableQuantity();
if ($r->isSuccess())
{
$providerName = null;
$providerName = $basketItem->getProviderName();
if (strval(trim($providerName)) == '')
{
$providerName = $basketItem->getCallbackFunction();
}
if (!empty($providerName) && $providerName[0] == "\\")
{
$providerName = ltrim($providerName, '\\');
}
$checkProviderName = $providerName;
$data = $r->getData();
if (array_key_exists('AVAILABLE_QUANTITY_LIST', $data) && isset($data['AVAILABLE_QUANTITY_LIST'][$checkProviderName]))
{
$resultList = $data['AVAILABLE_QUANTITY_LIST'][$checkProviderName];
}
}
else
{
$result->addErrors($r->getErrors());
}
if (isset($resultList[$productId]))
{
// $availableQuantity = $deltaQuantity;
$result->setData(
array(
'AVAILABLE_QUANTITY' => $resultList[$productId] - $poolQuantity
)
);
}
return $result;
}
/**
* @param Sale\BasketItemBase $basketItem
* @param array|null $context
*
* @return Sale\Result
* @throws Main\ObjectNotFoundException
* @throws Main\SystemException
*/
public static function getAvailableQuantityAndPriceByBasketItem(Sale\BasketItemBase $basketItem, array $context = array())
{
$result = new Sale\Result();
/** @var \Bitrix\Sale\Basket $basket */
if (!$basket = $basketItem->getCollection())
{
throw new Main\ObjectNotFoundException('Entity "Basket" not found');
}
$order = $basket->getOrder();
if (empty($context) && !$order)
{
$context = $basket->getContext();
}
if (empty($context) && $order)
{
$context = static::prepareContext($order, $context);
}
$r = static::checkContext($context);
if (!$r->isSuccess())
{
return $r;
}
$resultData = array();
$creator = Sale\Internals\ProviderCreator::create($context);
/** @var Sale\BasketItem $basketItem */
$creator->addBasketItem($basketItem);
$r = $creator->getAvailableQuantityAndPrice();
if ($r->isSuccess())
{
$providerName = $basketItem->getProviderName();
if (strval($providerName) == '')
{
$providerName = $basketItem->getCallbackFunction();
}
$providerName = static::clearProviderName($providerName);
$checkProviderName = $providerName;
$data = $r->getData();
if (array_key_exists('PRODUCT_DATA_LIST', $data) && isset($data['PRODUCT_DATA_LIST'][$checkProviderName]))
{
$productData = $data['PRODUCT_DATA_LIST'][$checkProviderName];
if (isset($productData['PRICE_LIST'][$basketItem->getProductId()][$basketItem->getBasketCode()]))
{
$resultData['PRICE_DATA'] = $productData['PRICE_LIST'][$basketItem->getProductId()][$basketItem->getBasketCode()];
}
if (isset($productData['AVAILABLE_QUANTITY_LIST'][$basketItem->getProductId()]))
{
$resultData['AVAILABLE_QUANTITY'] = $productData['AVAILABLE_QUANTITY_LIST'][$basketItem->getProductId()];
}
}
}
else
{
$result->addErrors($r->getErrors());
}
if (isset($resultData))
{
$result->setData(
$resultData
);
}
return $result;
}
/**
* @param Sale\Shipment $shipment
* @param array $context
*
* @return Sale\Result
* @throws Main\ArgumentNullException
* @throws Main\ObjectNotFoundException
*/
public static function tryReserveShipment(Sale\Shipment $shipment, array $context = array())
{
$result = new Sale\Result();
/** @var Sale\ShipmentCollection $shipmentCollection */
if (!$shipmentCollection = $shipment->getCollection())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Order $order */
$order = $shipmentCollection->getOrder();
if (!$order)
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$context = static::prepareContext($order, $context);
$r = static::checkContext($context);
if (!$r->isSuccess())
{
return $r;
}
$pool = PoolQuantity::getInstance($order->getInternalId());
/** @var Sale\ShipmentItemCollection $shipmentCollection */
$shipmentItemCollection = $shipment->getShipmentItemCollection();
$availableQuantityList = array();
$needQuantityList = array();
/** @var Sale\Result $r */
$r = static::getNeedQuantityByShipmentItemCollection($shipmentItemCollection);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
else
{
$data = $r->getData();
if (!empty($data['NEED_QUANTITY_LIST']))
{
$needQuantityList = $data['NEED_QUANTITY_LIST'];
}
}
if ($r->hasWarnings())
{
$result->addWarnings($r->getWarnings());
}
if ($shipmentItemCollection->count() == 0)
{
return $result;
}
$creator = Sale\Internals\ProviderCreator::create($context);
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
$shipmentProductData = $creator->createItemForReserve($shipmentItem);
$creator->addShipmentProductData($shipmentProductData);
}
$r = $creator->getAvailableQuantity();
if ($r->isSuccess())
{
$data = $r->getData();
if (array_key_exists('AVAILABLE_QUANTITY_LIST', $data))
{
$availableQuantityList = $data['AVAILABLE_QUANTITY_LIST'] + $availableQuantityList;
}
}
else
{
$result->addErrors($r->getErrors());
}
if ($r->hasWarnings())
{
$result->addWarnings($r->getWarnings());
}
if (!empty($needQuantityList) && $result->isSuccess())
{
$applyItemsList = array();
foreach ($availableQuantityList as $providerName => $productAvailableQuantityList)
{
$providerName = trim($providerName);
foreach ($productAvailableQuantityList as $productId => $productAvailableQuantity)
{
if (array_key_exists($productId, $needQuantityList[$providerName]))
{
if (Sale\Configuration::getProductReservationCondition() != Sale\Configuration::RESERVE_ON_SHIP)
{
$poolQuantity = 0;
if ($order->getId() > 0)
{
$poolQuantity = (float)$pool->get(PoolQuantity::POOL_RESERVE_TYPE, $productId);
}
$needQuantity = $needQuantityList[$providerName][$productId];
$productAvailableQuantity -= $poolQuantity;
$reservedQuantity = ($needQuantity >= $productAvailableQuantity ? $productAvailableQuantity : $needQuantity);
$applyItemsList[$providerName][$productId] = $reservedQuantity;
}
}
else
{
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
$basketItem = $shipmentItem->getBasketItem();
if ($basketItem->getProductId() == $productId)
{
$result->addWarning( new Sale\ResultWarning(Main\Localization\Loc::getMessage('SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY', array(
'#PRODUCT_NAME#' => $basketItem->getField('NAME')
)), 'SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY') );
break;
}
}
}
}
}
if (!empty($applyItemsList))
{
$shipmentProductIndex = static::createProductShipmentItemMapByShipmentItemCollection($shipmentItemCollection);
/** @var Sale\Shipment $shipment */
if (!$shipment = $shipmentItemCollection->getShipment())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollectionCollection" not found');
}
/** @var Sale\ShipmentCollection $shipmentCollection */
if (!$shipmentCollection = $shipment->getCollection())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Order $order */
if (!$order = $shipmentCollection->getOrder())
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$pool = PoolQuantity::getInstance($order->getInternalId());
static::setAvailableQuantityToShipmentItemCollection($pool, $shipmentProductIndex, $applyItemsList);
}
}
return $result;
}
/**
* @param Sale\ShipmentItem $shipmentItem
* @param array $context
*
* @return Sale\Result
* @throws Main\ArgumentNullException
* @throws Main\ArgumentOutOfRangeException
* @throws Main\NotSupportedException
* @throws Main\ObjectNotFoundException
* @throws \Exception
*/
public static function tryReserveShipmentItem(Sale\ShipmentItem $shipmentItem, array $context = array())
{
$result = new Sale\Result();
/** @var Sale\ShipmentItemCollection $shipmentItemCollection */
$shipmentItemCollection = $shipmentItem->getCollection();
if (!$shipmentItemCollection)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
}
/** @var Sale\Shipment $shipment */
$shipment = $shipmentItemCollection->getShipment();
if (!$shipment)
{
throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
}
/** @var Sale\ShipmentCollection $shipmentCollection */
$shipmentCollection = $shipment->getCollection();
if (!$shipmentCollection)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Order $order */
$order = $shipmentCollection->getOrder();
if (!$order)
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$context = static::prepareContext($order, $context);
$r = static::checkContext($context);
if (!$r->isSuccess())
{
return $r;
}
$pool = PoolQuantity::getInstance($order->getInternalId());
/** @var Sale\ShipmentItemCollection $shipmentCollection */
$shipmentItemCollection = $shipment->getShipmentItemCollection();
$availableQuantityList = [];
$needQuantityList = [];
$r = static::getNeedQuantityByShipmentItem($shipmentItem);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
else
{
$data = $r->getData();
if (!empty($data['NEED_QUANTITY_LIST']))
{
$needQuantityList = $data['NEED_QUANTITY_LIST'];
}
}
$creator = Sale\Internals\ProviderCreator::create($context);
$shipmentProductData = $creator->createItemForReserve($shipmentItem);
$creator->addShipmentProductData($shipmentProductData);
$r = $creator->getAvailableQuantity();
if ($r->isSuccess())
{
$data = $r->getData();
if (array_key_exists('AVAILABLE_QUANTITY_LIST', $data))
{
$availableQuantityList = $data['AVAILABLE_QUANTITY_LIST'];
}
}
else
{
$result->addErrors($r->getErrors());
}
if ($r->hasWarnings())
{
$result->addWarnings($r->getWarnings());
}
if (!empty($needQuantityList) && $result->isSuccess())
{
$applyItemsList = [];
foreach ($availableQuantityList as $providerName => $productAvailableQuantityList)
{
$providerName = trim($providerName);
foreach ($productAvailableQuantityList as $productId => $productAvailableQuantity)
{
if (array_key_exists($productId, $needQuantityList[$providerName]))
{
if (Sale\Configuration::getProductReservationCondition() != Sale\Configuration::RESERVE_ON_SHIP)
{
$poolQuantity = 0;
if ($order->getId() > 0)
{
$poolQuantity = (float)$pool->get(PoolQuantity::POOL_RESERVE_TYPE, $productId);
}
$needQuantity = $needQuantityList[$providerName][$productId];
$productAvailableQuantity -= $poolQuantity;
$reservedQuantity = ($needQuantity >= $productAvailableQuantity ? $productAvailableQuantity : $needQuantity);
$applyItemsList[$providerName][$productId] = $reservedQuantity;
}
}
else
{
/** @var Sale\ShipmentItem $shipmentItem */
$basketItem = $shipmentItem->getBasketItem();
if ($basketItem->getProductId() == $productId)
{
$result->addWarning( new Sale\ResultWarning(Main\Localization\Loc::getMessage('SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY', array(
'#PRODUCT_NAME#' => $basketItem->getField('NAME')
)), 'SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY') );
break;
}
}
}
}
if (!empty($applyItemsList))
{
$shipmentProductIndex = static::createProductShipmentItemMapByShipmentItem($shipmentItem);
/** @var Sale\Shipment $shipment */
if (!$shipment = $shipmentItemCollection->getShipment())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollectionCollection" not found');
}
/** @var Sale\ShipmentCollection $shipmentCollection */
if (!$shipmentCollection = $shipment->getCollection())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Order $order */
if (!$order = $shipmentCollection->getOrder())
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$pool = PoolQuantity::getInstance($order->getInternalId());
static::setAvailableQuantityToShipmentItemCollection($pool, $shipmentProductIndex, $applyItemsList);
}
}
return $result;
}
/**
* @param Sale\ShipmentItem $shipmentItem
*
* @return Sale\Result
* @throws Main\ArgumentOutOfRangeException
* @throws Main\NotSupportedException
* @throws Main\ObjectNotFoundException
* @throws \Exception
*/
public static function tryUnreserveShipmentItem(Sale\ShipmentItem $shipmentItem)
{
$result = new Sale\Result();
/** @var Sale\ShipmentItemCollection $shipmentItemCollection */
$shipmentItemCollection = $shipmentItem->getCollection();
if (!$shipmentItemCollection)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
}
/** @var Sale\Shipment $shipment */
$shipment = $shipmentItemCollection->getShipment();
if (!$shipment)
{
throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
}
/** @var Sale\ShipmentCollection $shipmentCollection */
$shipmentCollection = $shipment->getCollection();
if (!$shipmentCollection)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Order $order */
$order = $shipmentCollection->getOrder();
if (!$order)
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$pool = PoolQuantity::getInstance($order->getInternalId());
/** @var Sale\BasketItem $basketItem */
$basketItem = $shipmentItem->getBasketItem();
if (!$basketItem)
{
throw new Main\ObjectNotFoundException('Entity "BasketItem" not found');
}
$productId = $basketItem->getProductId();
$reservedQuantity = $shipmentItem->getReservedQuantity();
if ($reservedQuantity == 0)
{
return $result;
}
$pool->add(Sale\Internals\PoolQuantity::POOL_RESERVE_TYPE, $productId, -1 * $reservedQuantity);
if ($shipmentItem)
{
$foundItem = false;
$poolItems = Sale\Internals\ItemsPool::get($order->getInternalId(), $productId);
if (!empty($poolItems))
{
/** @var Sale\Shipment $poolItem */
foreach ($poolItems as $poolItem)
{
if ($poolItem->getInternalIndex() == $shipmentItem->getInternalIndex())
{
$foundItem = true;
break;
}
}
}
if (!$foundItem)
{
Sale\Internals\ItemsPool::add($order->getInternalId(), $productId, $shipmentItem);
}
}
$r = $shipmentItem->setField('RESERVED_QUANTITY', $shipmentItem->getReservedQuantity() + -1 * $reservedQuantity);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
return $result;
}
/**
* @param Sale\ShipmentItemCollection $shipmentItemCollection
*
* @return Sale\Result
*/
private static function getNeedQuantityByShipmentItemCollection(Sale\ShipmentItemCollection $shipmentItemCollection)
{
$result = new Sale\Result();
if ($shipmentItemCollection->count() == 0)
{
return $result;
}
$needQuantityList = array();
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
$basketItem = $shipmentItem->getBasketItem();
if (!$basketItem)
{
continue;
}
$productId = $basketItem->getProductId();
$providerName = $basketItem->getProviderName();
$providerName = static::clearProviderName($providerName);
$needQuantity = ($shipmentItem->getQuantity() - $shipmentItem->getReservedQuantity());
if (!isset($needQuantityList[$providerName]) || !array_key_exists($productId, $needQuantityList[$providerName]))
{
$needQuantityList[$providerName][$productId] = 0;
}
$needQuantityList[$providerName][$productId] += $needQuantity;
}
if (!empty($needQuantityList))
{
$result->setData(
array(
'NEED_QUANTITY_LIST' => $needQuantityList,
)
);
}
return $result;
}
/**
* @param Sale\ShipmentItem $shipmentItem
*
* @return Sale\Result
*/
private static function getNeedQuantityByShipmentItem(Sale\ShipmentItem $shipmentItem)
{
$result = new Sale\Result();
$needQuantityData = array();
$basketItem = $shipmentItem->getBasketItem();
$productId = $basketItem->getProductId();
$providerName = $basketItem->getProviderName();
$providerName = static::clearProviderName($providerName);
$needQuantityData[$providerName][$productId] = ($shipmentItem->getQuantity() - $shipmentItem->getReservedQuantity());
$result->setData(
array(
'NEED_QUANTITY_LIST' => $needQuantityData,
)
);
return $result;
}
/**
* @param Sale\Shipment $shipment
*
* @return Sale\Result
* @throws Main\ArgumentOutOfRangeException
* @throws Main\NotSupportedException
* @throws Main\ObjectNotFoundException
* @throws \Exception
*/
public static function tryUnreserveShipment(Sale\Shipment $shipment)
{
$result = new Sale\Result();
/** @var Sale\ShipmentCollection $shipmentCollection */
if (!$shipmentCollection = $shipment->getCollection())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Order $order */
if (!$order = $shipmentCollection->getOrder())
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$pool = PoolQuantity::getInstance($order->getInternalId());
/** @var Sale\ShipmentItemCollection $shipmentCollection */
$shipmentItemCollection = $shipment->getShipmentItemCollection();
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
/** @var Sale\BasketItem $basketItem */
if (!$basketItem = $shipmentItem->getBasketItem())
{
throw new Main\ObjectNotFoundException('Entity "BasketItem" not found');
}
$productId = $basketItem->getProductId();
$reservedQuantity = $shipmentItem->getReservedQuantity();
if ($reservedQuantity == 0)
continue;
$pool->add(Sale\Internals\PoolQuantity::POOL_RESERVE_TYPE, $productId, -1 * $reservedQuantity);
if ($shipmentItem)
{
$foundItem = false;
$poolItems = Sale\Internals\ItemsPool::get($order->getInternalId(), $productId);
if (!empty($poolItems))
{
/** @var Sale\Shipment $poolItem */
foreach ($poolItems as $poolItem)
{
if ($poolItem->getInternalIndex() == $shipmentItem->getInternalIndex())
{
$foundItem = true;
break;
}
}
}
if (!$foundItem)
{
Sale\Internals\ItemsPool::add($order->getInternalId(), $productId, $shipmentItem);
}
}
$r = $shipmentItem->setField('RESERVED_QUANTITY', $shipmentItem->getReservedQuantity() + -1 * $reservedQuantity);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
}
return $result;
}
/**
* @param $needQuantity
* @param $reservedQuantity
*
* @return float|int
*/
private static function countNeedQuantity($needQuantity, $reservedQuantity)
{
$setQuantity = $needQuantity;
if ($needQuantity >= $reservedQuantity)
{
$setQuantity = $reservedQuantity;
}
return $setQuantity;
}
/**
* @param Sale\ShipmentItemCollection $shipmentItemCollection
*
* @return array
*/
private static function createProductShipmentItemMapByShipmentItemCollection(Sale\ShipmentItemCollection $shipmentItemCollection)
{
static $shipmentProductIndex = array();
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
$shipmentProductIndexData = static::createProductShipmentItemMapByShipmentItem($shipmentItem);
$shipmentProductIndex = array_merge($shipmentProductIndex, $shipmentProductIndexData);
}
return $shipmentProductIndex;
}
/**
* @param Sale\ShipmentItem $shipmentItem
*
* @return array
*/
private static function createProductShipmentItemMapByShipmentItem(Sale\ShipmentItem $shipmentItem)
{
static $shipmentProductIndex = array();
/** @var Sale\ShipmentItem $shipmentItem */
$basketItem = $shipmentItem->getBasketItem();
$providerName = $basketItem->getProviderName();
$providerName = static::clearProviderName($providerName);
$productId = $basketItem->getProductId();
$index = $shipmentItem->getInternalIndex();
$shipmentProductIndex[$providerName][$productId][$index] = $shipmentItem;
return $shipmentProductIndex;
}
/**
* @param PoolQuantity $pool
* @param array $shipmentProductIndex
* @param array $items
*
* @return Sale\Result
* @throws Main\ArgumentOutOfRangeException
* @throws Main\NotSupportedException
* @throws Main\ObjectNotFoundException
* @throws \Exception
*/
private static function setAvailableQuantityToShipmentItemCollection(PoolQuantity $pool, array $shipmentProductIndex, array $items)
{
$result = new Sale\Result();
foreach ($items as $providerName => $productsList)
{
foreach ($productsList as $productId => $reservedQuantity)
{
if (empty($shipmentProductIndex[$providerName][$productId]))
continue;
/**
* @var $shipmetnItemIndex
* @var Sale\ShipmentItem $shipmentItem
*/
foreach ($shipmentProductIndex[$providerName][$productId] as $shipmetnItemIndex => $shipmentItem)
{
$needQuantity = ($shipmentItem->getQuantity() - $shipmentItem->getReservedQuantity());
$setQuantity = static::countNeedQuantity($needQuantity, $reservedQuantity);
if ($needQuantity == 0 || $setQuantity == 0 )
continue;
$reservedQuantity -= $setQuantity;
$pool->add(Sale\Internals\PoolQuantity::POOL_RESERVE_TYPE, $productId, $setQuantity);
/** @var Sale\ShipmentItemCollection $shipmentItemCollection */
$shipmentItemCollection = $shipmentItem->getCollection();
if (!$shipmentItemCollection)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Shipment $shipment */
$shipment = $shipmentItemCollection->getShipment();
if (!$shipment)
{
throw new Main\ObjectNotFoundException('Entity "Shipment" not found');
}
/** @var Sale\ShipmentCollection $shipmentCollection */
if (!$shipmentCollection = $shipment->getCollection())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Sale\Order $order */
if (!$order = $shipmentCollection->getOrder())
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$foundItem = false;
$poolItems = Sale\Internals\ItemsPool::get($order->getInternalId(), $productId);
if (!empty($poolItems))
{
/** @var Sale\Shipment $poolItem */
foreach ($poolItems as $poolItem)
{
if ($poolItem->getInternalIndex() == $shipmentItem->getInternalIndex())
{
$foundItem = true;
break;
}
}
}
if (!$foundItem)
{
Sale\Internals\ItemsPool::add($order->getInternalId(), $productId, $shipmentItem);
}
$r = $shipmentItem->setField('RESERVED_QUANTITY', $shipmentItem->getReservedQuantity() + $setQuantity);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
}
}
}
return $result;
}
/**
* @param Sale\Shipment $shipment
* @param array $context
*
* @return Sale\Result
* @throws Main\ObjectNotFoundException
*/
public static function tryShipShipment(Sale\Shipment $shipment, array $context = array())
{
$result = new Sale\Result();
$context = static::prepareContextByShipment($shipment, $context);
/** @var Sale\ShipmentCollection $shipmentCollection */
$shipmentCollection = $shipment->getCollection();
if (!$shipmentCollection)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
$order = $shipmentCollection->getOrder();
if (!$order)
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
$pool = PoolQuantity::getInstance($order->getInternalId());
/** @var Sale\ShipmentItemCollection $shipmentCollection */
$shipmentItemCollection = $shipment->getShipmentItemCollection();
$needShipList = array();
$creator = Sale\Internals\ProviderCreator::create($context);
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
$creator->addShipmentItem($shipmentItem);
}
$r = $creator->isNeedShip();
if ($r->isSuccess())
{
$data = $r->getData();
if (array_key_exists('IS_NEED_SHIP', $data))
{
$needShipList = $data['IS_NEED_SHIP'] + $needShipList;
}
}
$creator = Sale\Internals\ProviderCreator::create($context);
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
$shipmentProductData = $creator->createItemForShip($shipmentItem, $needShipList);
$creator->addShipmentProductData($shipmentProductData);
}
$tryShipProductList = array();
$isIgnoreErrors = false;
$r = $creator->tryShip();
$needSetAfterResult = false;
if ($r->isSuccess())
{
if ($r->hasWarnings())
{
$result->addWarnings($r->getWarnings());
}
else
{
$needSetAfterResult = true;
}
}
else
{
$result->addWarnings($r->getErrors());
if (static::isIgnoreErrors())
{
$isIgnoreErrors = true;
$needSetAfterResult = true;
}
else
{
$result->addErrors($r->getErrors());
}
}
$data = $r->getData();
if (array_key_exists('TRY_SHIP_PRODUCTS_LIST', $data))
{
$tryShipProductList = $data['TRY_SHIP_PRODUCTS_LIST'] + $tryShipProductList;
}
if ($needSetAfterResult && !empty($tryShipProductList))
{
if ($isIgnoreErrors)
{
foreach ($tryShipProductList as $providerName => &$productList)
{
$productList = array_fill_keys(array_keys($productList), true);
}
}
$creator->setItemsResultAfterTryShip($pool, $tryShipProductList);
}
return $result;
}
/**
* @param Sale\ShipmentItemCollection $shipmentItemCollection
*
* @return array
* @throws Main\LoaderException
* @throws Main\ObjectNotFoundException
*/
public static function createProviderItemsMap(Sale\ShipmentItemCollection $shipmentItemCollection)
{
$providerProductList = array();
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemCollection as $shipmentItem)
{
$basketItem = $shipmentItem->getBasketItem();
if (!$basketItem)
{
throw new Main\ObjectNotFoundException('Entity "BasketItem" not found');
}
if ($basketItem->isBundleParent())
{
continue;
}
$productId = $basketItem->getProductId();
$providerName = $basketItem->getProvider();
if (!isset($providerProductList[$providerName][$productId]))
{
$fields = array(
'PRODUCT_ID' => $productId,
'QUANTITY' => floatval($shipmentItem->getQuantity()),
'SHIPMENT_ITEM_LIST' => array(),
'IS_BUNDLE_CHILD' => $basketItem->isBundleChild(),
);
}
else
{
$fields = $providerProductList[$providerName][$productId];
$fields['QUANTITY'] += floatval($shipmentItem->getQuantity());
}
$shipmentItemIndex = $shipmentItem->getInternalIndex();
$barcodeStoreData = static::createMapShipmentItemStoreData($shipmentItem);
if (!empty($barcodeStoreData))
{
$fields['STORE'][$shipmentItemIndex] = $barcodeStoreData;
// $fields['STORE'][$shipmentItemIndex]['IS_BARCODE_MULTI'] = $basketItem->isBarcodeMulti();
}
$fields['SHIPMENT_ITEM_LIST'][$shipmentItemIndex] = $shipmentItem;
$providerProductList[$providerName][$productId] = $fields;
}
return $providerProductList;
}
/**
* @param array $rulesProducts
*
* @return array
* @throws Main\ObjectNotFoundException
*/
public static function createProviderItemsMapByRules(array $rulesProducts)
{
$providerProductList = array();
foreach ($rulesProducts as $ruleData)
{
/** @var Sale\ShipmentItem $shipmentItem */
$shipmentItem = $ruleData['SHIPMENT_ITEM'];
if (!$shipmentItem)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentItem" not found');
}
$productId = $ruleData['PRODUCT_ID'];
$providerName = $ruleData['PROVIDER_NAME'];
$shipmentItemIndex = $shipmentItem->getInternalIndex();
if (!isset($providerProductList[$providerName][$productId]))
{
$fields = $ruleData;
unset($fields['SHIPMENT_ITEM']);
unset($fields['STORE']);
unset($fields['NEED_RESERVE']);
unset($fields['NEED_SHIP']);
$fields['SHIPMENT_ITEM_LIST'] = array();
}
else
{
$fields = $providerProductList[$providerName][$productId];
$fields['QUANTITY'] += $ruleData['QUANTITY'];
}
if (array_key_exists('NEED_RESERVE', $ruleData))
{
$fields['NEED_RESERVE'][$shipmentItemIndex] = $ruleData['NEED_RESERVE'];
}
if (array_key_exists('NEED_SHIP', $ruleData))
{
$fields['NEED_SHIP'][$shipmentItemIndex] = $ruleData['NEED_SHIP'];
}
if (!empty($ruleData['STORE']))
{
$fields['STORE'][$shipmentItemIndex] = $ruleData['STORE'][$shipmentItemIndex];
}
$fields['SHIPMENT_ITEM_LIST'][$shipmentItemIndex] = $shipmentItem;
$providerProductList[$providerName][$productId] = $fields;
}
return $providerProductList;
}
/**
* @internal
* @param Sale\ShipmentItem $shipmentItem
*
* @return array|bool
* @throws Main\ObjectNotFoundException
*/
public static function createMapShipmentItemStoreData(Sale\ShipmentItem $shipmentItem)
{
$resultList = array();
/** @var Sale\BasketItem $basketItem */
if (!$basketItem = $shipmentItem->getBasketItem())
{
throw new Main\ObjectNotFoundException('Entity "BasketItem" not found');
}
if ($basketItem->isBundleParent())
{
return false;
}
/** @var Sale\ShipmentItemStoreCollection $shipmentItemStoreCollection */
if (!$shipmentItemStoreCollection = $shipmentItem->getShipmentItemStoreCollection())
{
throw new Main\ObjectNotFoundException('Entity "ShipmentItemStoreCollection" not found');
}
if ($shipmentItemStoreCollection->count() > 0)
{
$countBarcode = 0;
/** @var Sale\ShipmentItemStore $shipmentItemStore */
foreach ($shipmentItemStoreCollection as $shipmentItemStore)
{
/** @var Sale\BasketItem $basketItem */
if (!$basketItem = $shipmentItemStore->getBasketItem())
{
throw new Main\ObjectNotFoundException('Entity "BasketItem" not found');
}
// $basketCode = $basketItem->getBasketCode();
$productId = $basketItem->getProductId();
$storeId = $shipmentItemStore->getStoreId();
if (!isset($resultList[$storeId]))
{
$resultList[$storeId] = array(
'PRODUCT_ID' => $productId,
'QUANTITY' => 0,
'STORE_ID' => $storeId,
'IS_BARCODE_MULTI' => $basketItem->isBarcodeMulti(),
'BARCODE' => array()
);
}
$barcodeId = ($shipmentItemStore->getId() > 0)? $shipmentItemStore->getId() : 'n'.$countBarcode;
$countBarcode++;
$resultList[$storeId]['QUANTITY'] += $basketItem->isBarcodeMulti()? 1 : $shipmentItemStore->getQuantity();
$resultList[$storeId]['BARCODE'][$barcodeId] = $shipmentItemStore->getBarcode();
}
}
return $resultList;
}
/**
* @internal
* @param $shipmentItemList
*
* @return array
* @throws Main\ObjectNotFoundException
* @throws Main\SystemException
*/
public static function createMapShipmentItemCollectionStoreData($shipmentItemList)
{
$resultList = array();
/** @var Sale\ShipmentItem $shipmentItem */
foreach ($shipmentItemList as $shipmentItem)
{
$basketCode = $shipmentItem->getBasketCode();
if (!isset($resultList[$basketCode]))
{
$resultList[$basketCode] = array();
}
$map = static::createMapShipmentItemStoreData($shipmentItem);
if (!empty($map) && is_array($map))
{
$resultList[$basketCode] = $map + $resultList[$basketCode];
}
}
return $resultList;
}
/**
* @param Sale\Order $order
* @param array|null $context
*
* @return Sale\Result
* @throws Main\SystemException
*/
public static function save(Sale\Order $order, array $context = array())
{
$result = new Sale\Result();
$context = static::prepareContext($order, $context);
$r = static::checkContext($context);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
return $result;
}
$pool = PoolQuantity::getInstance($order->getInternalId());
/** @var array $poolQuantitiesList */
$poolQuantitiesList = $pool->getQuantities(PoolQuantity::POOL_QUANTITY_TYPE);
/** @var array $poolReservationList */
$poolReservationList = $pool->getQuantities(PoolQuantity::POOL_RESERVE_TYPE);
if (empty($poolQuantitiesList) && empty($poolReservationList))
return $result;
$rulesMap = ShipmentRules::createOrderRuleMap($order, $pool);
if (empty($rulesMap))
{
return $result;
}
$r = ShipmentRules::saveRules($rulesMap, $context);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
if ($r->hasWarnings())
{
$result->addWarnings($r->getWarnings());
}
$pool->reset(PoolQuantity::POOL_QUANTITY_TYPE);
$pool->reset(PoolQuantity::POOL_RESERVE_TYPE);
return $result;
}
/**
* @param Sale\Shipment $shipment
*
* @return Sale\Order
* @throws Main\ObjectNotFoundException
*/
public static function getOrderByShipment(Sale\Shipment $shipment)
{
/** @var Sale\ShipmentCollection $shipmentCollection */
$shipmentCollection = $shipment->getCollection();
if (!$shipmentCollection)
{
throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
$order = $shipmentCollection->getOrder();
if (!$order)
{
throw new Main\ObjectNotFoundException('Entity "Order" not found');
}
return $order;
}
/**
* @param Sale\Shipment $shipment
* @param array $context
*
* @return array
* @throws Main\ObjectNotFoundException
*/
private static function prepareContextByShipment(Sale\Shipment $shipment, array $context = array())
{
$order = static::getOrderByShipment($shipment);
if (empty($context))
{
$context = array(
'SITE_ID' => $order->getSiteId(),
'USER_ID' => $order->getUserId(),
'CURRENCY' => $order->getCurrency(),
);
}
else
{
if (empty($context['SITE_ID']))
{
$context['SITE_ID'] = $order->getSiteId();
}
if (empty($context['USER_ID']) && $order->getUserId() > 0)
{
$context['USER_ID'] = $order->getUserId();
}
if (empty($context['CURRENCY']))
{
$context['CURRENCY'] = $order->getCurrency();
}
}
return $context;
}
/**
* @param Sale\OrderBase $order
* @param array $context
*
* @return array
*/
private static function prepareContext(Sale\OrderBase $order, array $context = array())
{
if (empty($context))
{
$context = array(
'SITE_ID' => $order->getSiteId(),
'USER_ID' => $order->getUserId(),
'CURRENCY' => $order->getCurrency(),
);
}
if (!empty($context))
{
if (empty($context['SITE_ID']))
{
$context['SITE_ID'] = $order->getSiteId();
}
if (empty($context['USER_ID']) && $order->getUserId() > 0)
{
$context['USER_ID'] = $order->getUserId();
}
if (empty($context['CURRENCY']))
{
$context['CURRENCY'] = $order->getCurrency();
}
}
return $context;
}
/**
* @param array $context
*
* @return Sale\Result
* @throws Main\ArgumentNullException
*/
private static function checkContext(array $context)
{
$result = new Sale\Result();
if (empty($context['SITE_ID']))
{
throw new Main\ArgumentNullException('SITE_ID');
}
if (empty($context['CURRENCY']))
{
throw new Main\ArgumentNullException('CURRENCY');
}
return $result;
}
/**
* @param $module
* @param $name
*
* @return string|null
* @throws Main\LoaderException
*/
public static function getProviderName($module, $name)
{
static $providerProxy = array();
$code = $module."|".$name;
if (array_key_exists($code, $providerProxy))
{
return $providerProxy[$code];
}
$providerName = null;
if (strval($module) != '' && Main\Loader::includeModule($module) && class_exists($name))
{
$provider = static::getProviderEntity($name);
if ($provider)
{
$providerName = $name;
}
}
if ($providerName !== null)
{
$providerProxy[$code] = $providerName;
}
return $providerName;
}
/**
* @param $name
*
* @return mixed|null
*/
public static function getProviderEntity($name)
{
static $providerEntityProxy = array();
if (array_key_exists($name, $providerEntityProxy))
{
return $providerEntityProxy[$name];
}
if (class_exists($name))
{
$productProvider = new $name();
if ($productProvider instanceof Sale\SaleProviderBase || array_key_exists("IBXSaleProductProvider", class_implements($name)))
{
$providerEntityProxy[$name] = $productProvider;
return $productProvider;
}
}
return null;
}
/**
* @param $name
*
* @return bool
*/
public static function isProviderCallbackFunction($name)
{
return (array_key_exists("IBXSaleProductProvider", class_implements($name)));
}
/**
* @param $providerName
*
* @return string
*/
private static function clearProviderName($providerName)
{
if (substr($providerName, 0, 1) == "\\")
{
$providerName = substr($providerName, 1);
}
return trim($providerName);
}
/**
* @internal
* @param $value
*/
public static function setIgnoreErrors($value)
{
static::$ignoreErrors = ($value === true);
}
/**
* @internal
* @return bool
*/
public static function isIgnoreErrors()
{
return static::$ignoreErrors;
}
}