- Модуль: sale
- Путь к файлу: ~/bitrix/modules/sale/lib/providerbase.php
- Класс: BitrixSaleProviderBase
- Вызов: ProviderBase::tryReserveShipmentItem
static function tryReserveShipmentItem(ShipmentItem $shipmentItem)
{
$result = new Result();
if (floatval($shipmentItem->getQuantity()) == floatval($shipmentItem->getReservedQuantity()))
{
return $result;
}
/** @var ShipmentItemCollection $shipmentItemCollection */
if (!$shipmentItemCollection = $shipmentItem->getCollection())
{
throw new ObjectNotFoundException('Entity "ShipmentItemCollection" not found');
}
/** @var Shipment $shipment */
if (!$shipment = $shipmentItemCollection->getShipment())
{
throw new ObjectNotFoundException('Entity "Shipment" not found');
}
/** @var ShipmentCollection $shipmentCollection */
if (!$shipmentCollection = $shipment->getCollection())
{
throw new ObjectNotFoundException('Entity "ShipmentCollection" not found');
}
/** @var Order $order */
if (!$order = $shipmentCollection->getOrder())
{
throw new ObjectNotFoundException('Entity "Order" not found');
}
/** @var BasketItem $basketItem */
if (!$basketItem = $shipmentItem->getBasketItem())
{
$result->addError(new ResultError(
Loc::getMessage(
'SALE_PROVIDER_BASKET_ITEM_NOT_FOUND',
[
'#BASKET_ITEM_ID#' => $shipmentItem->getBasketId(),
'#SHIPMENT_ID#' => $shipment->getId(),
'#SHIPMENT_ITEM_ID#' => $shipmentItem->getId(),
]
),
'PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_BASKET_ITEM')
);
return $result;
}
if ($basketItem->isBundleParent())
{
return $result;
}
$needQuantity = ($shipmentItem->getQuantity() - $shipmentItem->getReservedQuantity());
$canReserve = false;
$providerName = $basketItem->getProvider();
if (class_exists($providerName))
{
if (empty($context))
{
if ($order)
{
$context = array(
'USER_ID' => $order->getUserId(),
'SITE_ID' => $order->getSiteId(),
'CURRENCY' => $order->getCurrency(),
);
}
else
{
global $USER;
$context = array(
'USER_ID' => $USER->getId(),
'SITE_ID' => SITE_ID,
'CURRENCY' => CurrencyCurrencyManager::getBaseCurrency(),
);
}
}
$availableQuantityData = array();
$providerClass = new $providerName($context);
if ($providerClass instanceof SaleProviderBase)
{
$creator = InternalsProviderCreator::create($context);
$shipmentProductData = $creator->createItemForReserveByShipmentItem($shipmentItem);
$creator->addProductData($shipmentProductData);
$r = $creator->getAvailableQuantity();
if ($r->isSuccess())
{
$resultData = $r->getData();
if (!empty($resultData['AVAILABLE_QUANTITY_LIST']))
{
$productId = $basketItem->getProductId();
$resultAvailableQuantityList = $resultData['AVAILABLE_QUANTITY_LIST'];
if (mb_substr($providerName, 0, 1) == "\")
{
$providerName = mb_substr($providerName, 1);
}
if (isset($resultAvailableQuantityList[$providerName]) && isset($resultAvailableQuantityList[$providerName][$productId]))
{
$availableQuantityData = array(
'HAS_PROVIDER' => true,
'AVAILABLE_QUANTITY' => $resultAvailableQuantityList[$providerName][$productId]
);
}
}
}
else
{
$result->addErrors($r->getErrors());
return $result;
}
}
else
{
/** @var Result $r */
$r = static::tryReserveBasketItem($basketItem, $needQuantity);
$availableQuantityData = $r->getData();
}
}
else
{
/** @var Result $r */
$r = static::tryReserveBasketItem($basketItem, $needQuantity);
$availableQuantityData = $r->getData();
}
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
return $result;
}
elseif ($r->hasWarnings())
{
$result->addWarnings($r->getWarnings());
return $result;
}
if (array_key_exists('AVAILABLE_QUANTITY', $availableQuantityData))
{
$availableQuantity = $availableQuantityData['AVAILABLE_QUANTITY'];
}
else
{
$result->addWarning( new ResultWarning(Loc::getMessage('SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY', array(
'#PRODUCT_NAME#' => $basketItem->getField('NAME')
)), 'SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_WRONG_AVAILABLE_QUANTITY') );
return $result;
}
if (array_key_exists('HAS_PROVIDER', $availableQuantityData))
{
$canReserve = $availableQuantityData['HAS_PROVIDER'];
}
if ($canReserve && array_key_exists('QUANTITY_TRACE', $availableQuantityData))
{
$canReserve = $availableQuantityData['QUANTITY_TRACE'];
}
if ($canReserve)
{
if ($r->isSuccess() && ($needQuantity > 0) && ($needQuantity > $availableQuantity)
/*|| ($needReserved < 0) && ($availableQuantity < $needReserved) */)
{
$result->addWarning(new ResultWarning(Loc::getMessage("SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_QUANTITY_NOT_ENOUGH", array(
'#PRODUCT_NAME#' => $basketItem->getField('NAME')
)), "SALE_PROVIDER_RESERVE_SHIPMENT_ITEM_QUANTITY_NOT_ENOUGH"));
return $result;
}
// is not completely correct, but will be processed in real reservations while saving
if (($availableQuantity < 0) && ($shipmentItem->getReservedQuantity() + $availableQuantity < 0))
{
$availableQuantity = -1 * $shipmentItem->getReservedQuantity();
}
if (Configuration::getProductReservationCondition() != ReserveCondition::ON_SHIP)
{
$reservedQuantity = ($availableQuantity >= $needQuantity ? $needQuantity : $availableQuantity);
static::addReservationPoolItem($order->getInternalId(), $shipmentItem->getBasketItem(), $reservedQuantity);
$r = $shipmentItem->setField('RESERVED_QUANTITY', $shipmentItem->getReservedQuantity() + $reservedQuantity);
if (!$r->isSuccess())
{
$result->addErrors($r->getErrors());
}
}
}
$result->addData([
'CAN_RESERVE' => $canReserve,
]);
return $result;
}