• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/helpers/reservedproductcleaner.php
  • Класс: BitrixSaleHelpersReservedProductCleaner
  • Вызов: ReservedProductCleaner::execute
public function execute(array &$result)
{
	$processedRecords = 0;

	$registry = SaleRegistry::getInstance(SaleRegistry::REGISTRY_TYPE_ORDER);
	/** @var SaleOrder $orderClass */
	$orderClass = $registry->getOrderClassName();

	$days_ago = (int) Option::get("sale", "product_reserve_clear_period");

	if ($days_ago > 0)
	{
		global $USER;

		if (!is_object($USER))
		{
			$USER = new CUser;
		}

		$date = new DateTime();
		$parameters = [
			'select' => [
				'ORDER_ID' => 'ORDER.ID',
				'ID',
				'BASKET_ID'
			],
			'filter' => [
				'>QUANTITY' => 0,
				'<=DATE_RESERVE_END' => $date,
				'=ORDER.PAYED' => 'N',
				'=ORDER.CANCELED' => 'N',
			],
			'runtime' => [
				new MainEntityReferenceField(
					'BASKET',
					SaleInternalsBasketTable::class,
					[
						'=this.BASKET_ID' => 'ref.ID',
					],
					['join_type' => 'inner']
				),
				new MainEntityReferenceField(
					'ORDER',
					SaleInternalsOrderTable::class,
					[
						'=this.BASKET.ORDER_ID' => 'ref.ID',
					],
					['join_type' => 'inner']
				),
			],
			'limit' => self::RECORD_LIMIT,
		];

		$orderList = [];
		$res = SaleReserveQuantityCollection::getList($parameters);
		while ($data = $res->fetch())
		{
			if (!isset($orderList[$data['ORDER_ID']]))
			{
				$orderList[$data['ORDER_ID']] = [];
			}

			if (!isset($orderList[$data['ORDER_ID']][$data['BASKET_ID']]))
			{
				$orderList[$data['ORDER_ID']][$data['BASKET_ID']] = [];
			}

			$orderList[$data['ORDER_ID']][$data['BASKET_ID']][] = $data['ID'];
		}

		foreach ($orderList as $orderId => $basketItemIds)
		{
			$order = $orderClass::load($orderId);
			if (!$order)
			{
				continue;
			}

			$basket = $order->getBasket();
			foreach ($basketItemIds as $basketItemId => $reserveIds)
			{
				/** @var SaleBasketItem $basketItem */
				$basketItem = $basket->getItemById($basketItemId);
				if (!$basketItem)
				{
					continue;
				}

				foreach ($reserveIds as $reserveId)
				{
					/** @var ReserveQuantityCollection $reserveCollection */
					$reserveCollection = $basketItem->getReserveQuantityCollection();
					if (!$reserveCollection)
					{
						continue;
					}

					$reserve = $reserveCollection->getItemById($reserveId);
					if (!$reserve)
					{
						continue;
					}

					$reserve->delete();

					$processedRecords++;
				}
			}

			$r = $order->save();
			if (!$r->isSuccess())
			{
				$errorText = (string)$order->getField('REASON_MARKED');
				if ($errorText !== '')
				{
					$errorText .= "n";
				}

				foreach($r->getErrorMessages() as $error)
				{
					if ((string)$error !== '')
					{
						$errorText .= $error."n";
					}
				}

				SaleInternalsOrderTable::update($order->getId(), [
					"MARKED" => "Y",
					"REASON_MARKED" => $errorText
				]);
			}
		}

		// crutch for #120087
		if (!is_object($USER) || $USER->GetID() <= 0)
		{
			ORMEntity::destroy(SaleInternalsOrderTable::getEntity());
		}
	}

	if ($processedRecords < self::RECORD_LIMIT)
	{
		return self::FINISH_EXECUTION;
	}

	return self::CONTINUE_EXECUTION;
}