%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/sale/lib/delivery/requests/
Upload File :
Create Path :
Current File : //home/bitrix/www/bitrix/modules/sale/lib/delivery/requests/manager.php

<?
namespace Bitrix\Sale\Delivery\Requests;

use Bitrix\Main;
use Bitrix\Sale\Order;
use Bitrix\Sale\ResultWarning;
use Bitrix\Sale\Shipment;
use Bitrix\Sale\Internals;
use Bitrix\Sale\EntityMarker;
use Bitrix\Main\Localization\Loc;
use Bitrix\Sale\Delivery\Services;

Loc::loadMessages(__FILE__);

/**
 * Class Manager
 * @package Bitrix\Sale\Delivery\Requests
 * Manages the lifecycle of delivery requests items
 */
final class Manager
{
	const STATUS_PREPARED = 0;
	const STATUS_SENT = 10;
	const STATUS_PROCESSED = 20;

	const FORM_FIELDS_TYPE_CREATE = 10;
	const FORM_FIELDS_TYPE_ADD = 20;
	const FORM_FIELDS_TYPE_ACTION = 30;

	/**
	 * @param int $shipmentId
	 * @param int $requestId
	 * @return Result
	 * @throws Main\ArgumentException
	 */
	public static function getDeliveryRequestShipmentContent($requestId, $shipmentId)
	{
		$result = new Result();

		if(intval($shipmentId) <= 0)
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHIPMENT_ID')));
			return $result;
		}

		$res = ShipmentTable::getList(array(
			'filter' => array(
				'=SHIPMENT_ID' => $shipmentId
			),
			'select' => array(
				'*',
				'DELIVERY_ID' => 'SHIPMENT.DELIVERY_ID'
			)
		));

		if(!($row = $res->fetch()))
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_ERROR_SHIPMENT_NOT_IN_REQUEST',
						array('#SHIPMENT_ID#' => $shipmentId)
			)));

			return $result;
		}

		$deliveryId = intval($row['DELIVERY_ID']);

		if($deliveryId <= 0)
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_ERROR_DELIVERY_NOT_FOUND',
						array('#SHIPMENT_LINK#' => Helper::getShipmentEditLink($shipmentId)))));

			return $result;
		}

		$deliveryRequestHandler = self::getDeliveryRequestHandlerByDeliveryId($deliveryId);

		if(!$deliveryRequestHandler)
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_ERROR_DELIVERY_NOT_SUPPORT',
						array('#DELIVERY_LINK#' => Helper::getDeliveryEditLink($deliveryId)))));

			return $result;
		}

		return $deliveryRequestHandler->getShipmentContent($requestId, $shipmentId);
	}

	/**
	 * @param Shipment $shipment
	 * @return array Shipment actions
	 * @throws Main\ArgumentNullException
	 */
	public static function getDeliveryRequestShipmentActions(Shipment $shipment)
	{
		$deliveryId = $shipment->getDeliveryId();

		if($deliveryId <= 0)
			return array();

		if(!($delivery = Services\Manager::getObjectById($deliveryId)))
			return array();

		if(!($deliveryRequestHandler = $delivery->getDeliveryRequestHandler()))
			return array();

		return $deliveryRequestHandler->getShipmentActions($shipment);
	}

	/**
	 * @param int $requestId
	 * @return array Request actions
	 * @throws Main\ArgumentNullException
	 */
	public static function getDeliveryRequestActions($requestId)
	{
		$result = array();
		$deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId);

		if($deliveryRequestHandler)
			$result = $deliveryRequestHandler->getActions($requestId);

		return $result;
	}

	/**
	 * @param int $requestId
	 * @return HandlerBase|null  Delivery request handler
	 * @throws Main\ArgumentNullException
	 */
	protected static function getDeliveryRequestHandlerByRequestId($requestId)
	{
		if(intval($requestId) <= 0)
			return null;

		if(!($requestFields = RequestTable::getById($requestId)->fetch()))
			return null;

		if(intval($requestFields['DELIVERY_ID']) <= 0)
			return null;

		return self::getDeliveryRequestHandlerByDeliveryId($requestFields['DELIVERY_ID']);
	}

	/**
	 * @param int $deliveryId
	 * @return HandlerBase|null Delivery request handler
	 * @throws Main\ArgumentNullException
	 * @throws Main\SystemException
	 */

	public static function getDeliveryRequestHandlerByDeliveryId($deliveryId)
	{
		if(intval($deliveryId) <= 0)
			return null;

		if(!($delivery = Services\Manager::getObjectById($deliveryId)))
			return null;

		return $delivery->getDeliveryRequestHandler();
	}

	/**
	 * @param int $deliveryId
	 * @param int[] $shipmentIds
	 * @param array $additional Additional info required for creation. Depends on delivery service.
	 * @return Result
	 * @throws Main\ArgumentException
	 * @throws Main\ArgumentNullException
	 * @throws Main\SystemException
	 * @throws \Exception
	 */

	public static function createDeliveryRequest($deliveryId, array $shipmentIds, array $additional = array())
	{
		$result = new Result();

		if(!($deliveryRequestHandler = self::getDeliveryRequestHandlerByDeliveryId($deliveryId)))
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_ERROR_NOT_SUPPORT',
						array('#DELIVERY_LINK#' => Helper::getDeliveryEditLink($deliveryId))
			)));

			return $result;
		}

		/** @var ShipmentResult[] $checkResults */
		$checkResults = self::checkShipmentIdsBeforeAdd($shipmentIds);

		foreach($checkResults as $res)
		{
			if($res->isSuccess())
				continue;

			$result->addResult(
				self::processShipmentResult(
					$res
			));

			unset($shipmentIds[array_search($res->getInternalId(), $shipmentIds)]);
		}

		if(empty($shipmentIds))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHP_ABSENT')));
			return $result;
		}

		$res = $deliveryRequestHandler->create($shipmentIds, $additional);

		if($res->isSuccess())
		{
			$result->addResults($res->getResults());
		}
		else
		{
			$result->addErrors($res->getErrors());

			foreach($res->getShipmentResults() as $sRes)
				$result->addResult(self::processShipmentResult($sRes));

			return $result;
		}

		$results = $result->getResults();

		if(!is_array($results) || empty($results))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_RES_UNKNOWN')));
			return $result;
		}

		/** @var  ShipmentResult|RequestResult $requestResult */
		foreach($results as $resId => $requestResult)
		{
			if($requestResult instanceof ShipmentResult)
			{
				$requestResult = self::processShipmentResult($requestResult);
			}
			elseif($requestResult instanceof RequestResult)
			{
				$requestId = 0;
				/** @var RequestResult  $requestResult*/
				if($requestResult->isSuccess())
				{
					$res = RequestTable::add(array(
						'DELIVERY_ID' => $deliveryRequestHandler->getHandlingDeliveryServiceId(),
						'EXTERNAL_ID' => $requestResult->getExternalId(),
						'STATUS' => Manager::STATUS_SENT
					));

					if(!$res->isSuccess())
					{
						$requestResult->addErrors($res->getErrors());
						continue;
					}

					$requestId = $res->getId();

					if($requestId > 0)
						$requestResult->setInternalId($requestId);
				}

				$shipmentsResults = $requestResult->getShipmentResults();

				if(empty($shipmentsResults))
					continue;

				foreach($shipmentsResults as $sResIdx => $shipmentResult)
					$shipmentsResults[$sResIdx] = self::processShipmentResult($shipmentResult, $requestId);

				$requestResult->setResults($shipmentsResults);
			}
			else
			{
				$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_ANSW_TYPE').' "'.get_class($requestResult).'"'));
				continue;
			}

			$results[$resId] = $requestResult;
		}

		$result->setResults($results);
		return $result;
	}

	/**
	 * @param ShipmentResult $result
	 * @param int $requestId
	 * @return ShipmentResult
	 */
	protected static function processShipmentResult($result, $requestId = 0)
	{
		if(!($result instanceof ShipmentResult))
			return $result;

		$shipmentId = $result->getInternalId();

		if(intval($shipmentId) <= 0)
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SAVE_SHIPMENT_ID')));
			return $result;
		}

		$extShipmentId = $result->getExternalId();

		if($result->isSuccess())
		{
			if(intval($requestId) > 0)
			{
				$res = ShipmentTable::setShipment(array(
					'REQUEST_ID' => $requestId,
					'SHIPMENT_ID' => $shipmentId,
					'EXTERNAL_ID' => $extShipmentId,
					'ERROR_DESCRIPTION' => ''
				));

				if(!$res->isSuccess())
					$result->addErrors($res->getErrors());

				$res = self::saveShipmentResult($shipmentId, $result);

				if(!$res->isSuccess())
					$result->addErrors($res->getErrors());
			}
		}
		else
		{
			ShipmentTable::setShipment(array(
				'SHIPMENT_ID' => $shipmentId,
				'ERROR_DESCRIPTION' => implode("\n", $result->getErrorMessages())
			));
		}

		return $result;
	}

	/**
	 * @param int $deliveryId
	 * @param int $formFieldsType FORM_FIELDS_TYPE_ACTION | FORM_FIELDS_TYPE_ADD | FORM_FIELDS_TYPE_CREATE
	 * @param int[] $shipmentIds
	 * @param array $additional
	 * @return array Form fields
	 * @throws Main\ArgumentNullException
	 */
	public static function getDeliveryRequestFormFields($deliveryId, $formFieldsType, array $shipmentIds, array $additional = array())
	{
		if(!$deliveryRequestHandler = self::getDeliveryRequestHandlerByDeliveryId($deliveryId))
			return array();

		return $deliveryRequestHandler->getFormFields($formFieldsType, $shipmentIds, $additional);
	}

	/**
	 * @param int $requestId
	 * @return Result
	 * @throws \Exception
	 */
	public static function deleteDeliveryRequest($requestId)
	{
		$result = new Result();

		if(empty($requestId))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_ID')));
			return $result;
		}

		if($deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId))
		{
			$res = $deliveryRequestHandler->delete($requestId);

			if(!$res->isSuccess())
				$result->addErrors($res->getErrors());
		}

		if($result->isSuccess())
		{
			$con = Main\Application::getConnection();
			$con->queryExecute("DELETE FROM ".ShipmentTable::getTableName()." WHERE REQUEST_ID=".intval($requestId));
			$res = RequestTable::delete($requestId);

			if(!$res->isSuccess())
				$result->addErrors($res->getErrors());
		}

		return $result;
	}

	/**
	 * @param int $requestId
	 * @param int[] $shipmentIds
	 * @return Result
	 */
	public static function deleteShipmentsFromDeliveryRequest($requestId, array $shipmentIds)
	{
		$result = new Result();

		if(empty($requestId))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_ID')));
			return $result;
		}

		if(empty($shipmentIds))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHP_ID_LIST_EMPTY')));
			return $result;
		}

		if(!($deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId)))
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_ERROR_REQ_OBJ'
			)));

			return $result;
		}

		$checkResults = self::checkShipmentIdsBeforeDelete($shipmentIds);

		foreach($checkResults as $res)
		{
			if(!$res->isSuccess())
			{
				$result->addErrors($res->getErrors());
				unset($shipmentIds[array_search($res->getInternalId(), $shipmentIds)]);
			}
		}

		if(empty($shipmentIds))
			return $result;

		$res = $deliveryRequestHandler->deleteShipments($requestId, $shipmentIds);
		$result->setResults($res->getResults());

		if(!$res->isSuccess())
		{
			$result->addErrors($res->getErrors());
			return $result;
		}

		$results = $result->getResults();

		if(!is_array($results) || empty($results))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_RES_UNKNOWN')));
			return $result;
		}

		$con = Main\Application::getConnection();

		/** @var  ShipmentResult $shpRes */
		foreach($results as $resId => $shpRes)
		{
			if(!($shpRes instanceof ShipmentResult))
			{
				$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_ANSW_TYPE').' "'.get_class($shpRes).'"'));
				continue;
			}

			if($shpRes->isSuccess())
			{
				$shpId = intval($shpRes->getInternalId());

				if($shpId <= 0)
				{
					$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_SHP_ID_LESS_ZERO')));
					continue;
				}

				$con->queryExecute("DELETE FROM ".ShipmentTable::getTableName()." WHERE REQUEST_ID=".intval($requestId)." AND SHIPMENT_ID=".intval($shpId));
				//Unset mark about changed shipment
				self::unSetMarkerShipmentChanged($shpId);

				//If there is no more shipments in this request
				if(!ShipmentTable::getList(array('filter' => array('=REQUEST_ID' => $requestId)))->fetch())
				{
					$res = RequestTable::delete($requestId);

					if($res->isSuccess())
					{
						$result->addMessage(
							new Message(
								Loc::getMessage(
									'SALE_DLVR_REQ_MNGR_EMPTY_REQ_DELETED',
									array('#REQUEST_ID#' => $requestId)
						)));
					}
					else
					{
						$result->addError(
							new Main\Error(
								Loc::getMessage(
									'SALE_DLVR_REQ_MNGR_EMPTY_REQ_NOT_DELETED',
									array('#REQUEST_LINK#' => Helper::getRequestViewLink($requestId))
								).implode('; ',$result->getErrorMessages())
						));
					}
				}
			}

			$results[$resId] = $shpRes;
		}

		$result->setResults($results);
		return $result;
	}

	/**
	 * @param int $requestId
	 * @return Result
	 */
	public static function getDeliveryRequestContent($requestId)
	{
		$deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId);

		if(!$deliveryRequestHandler)
		{
			$result= new Result();
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_OBJ')));
			return $result;
		}

		return $deliveryRequestHandler->getContent($requestId);
	}

	/**
	 * @param int $requestId
	 * @param string $actionType
	 * @param array $additional
	 * @return Result
	 */
	public static function executeDeliveryRequestAction($requestId, $actionType, array $additional = array())
	{
		$deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId);

		if(!$deliveryRequestHandler)
		{
			$result = new Result();
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_ACTION_EXEC').'. '.Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_OBJ')));
			return $result;
		}

		return $deliveryRequestHandler->executeAction($requestId, $actionType, $additional);
	}

	/**
	 * @param int $requestId
	 * @param int $shipmentId
	 * @param string $actionType
	 * @param array $additional
	 * @return Result
	 */
	public static function executeDeliveryRequestShipmentAction($requestId, $shipmentId, $actionType, array $additional = array())
	{
		$deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId);

		if(!$deliveryRequestHandler)
		{
			$result = new Result();
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_ACTION_EXEC').'. '.Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_OBJ')));
			return $result;
		}

		return $deliveryRequestHandler->executeShipmentAction($requestId, $shipmentId, $actionType, $additional);
	}

	/**
	 * @param int[] $shipmentIds
	 * @return ShipmentResult[]
	 * @throws \Bitrix\Main\ArgumentException
	 */
	protected static function checkShipmentIdsBeforeAdd(array $shipmentIds)
	{
		$result = array();
		$positiveIds = self::filterPositiveIds($shipmentIds);

		foreach(array_diff($shipmentIds, $positiveIds) as $id)
		{
			$shpRes = new ShipmentResult($id);
			$shpRes->addError(
				new Main\Error(
					Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHIPMENT_ID').' "'.$id.'"',
					$id
			));
			$result[] = $shpRes;
		}

		$addedIds = self::filterAddedIds($positiveIds);

		foreach(array_intersect($positiveIds, $addedIds) as $id)
		{
			$shpRes = new ShipmentResult($id);
			$shpRes->addError(
				new Main\Error(
					Loc::getMessage('SALE_DLVR_REQ_MNGR_ALREADY_ADDED')
			));
			$result[] = $shpRes;
		}

		$existingIds = self::filterExistIds($addedIds);

		foreach(array_diff($addedIds, $existingIds) as $id)
		{
			$shpRes = new ShipmentResult($id);
			$shpRes->addError(
				new Main\Error(
					Loc::getMessage('SALE_DLVR_REQ_MNGR_SHP_NOT_FOUND', array('#SHIPMENT_ID#' => $id)
			)));
			$result[] = $shpRes;
		}

		return $result;
	}

	/**
	 * @param int[] $shipmentIds
	 * @return int[] Choose ids only for existing shipments.
	 * @throws Main\ArgumentException
	 */
	protected static function filterExistIds(array $shipmentIds)
	{
		$result = array();

		$res = Internals\ShipmentTable::getList(array(
			'filter' => array(
				'=ID' => $shipmentIds,
			)
		));

		while($row = $res->fetch())
			$result[] = $row['ID'];

		return $result;
	}

	/**
	 * @param int[] $shipmentIds
	 * @return int[]
	 * @throws \Bitrix\Main\ArgumentException
	 */
	protected static function filterAddedIds(array $shipmentIds)
	{
		$result = array();

		$res = ShipmentTable::getList(array(
			'filter' => array(
				'=SHIPMENT_ID' => $shipmentIds,
				'!=REQUEST_ID' => false
			)
		));

		while($row = $res->fetch())
			$result[] = $row['SHIPMENT_ID'];

		return $result;
	}

	/**
	 * @param int[] $shipmentIds
	 * @return int[]
	 */
	protected static function filterPositiveIds(array $shipmentIds)
	{
		$result = array();

		foreach($shipmentIds as $id)
			if(intval($id) > 0)
				$result[] = $id;

		return $result;
	}

	/**
	 * @param int[] $shipmentIds
	 * @return ShipmentResult[]
	 */
	protected static function checkShipmentIdsBeforeDelete(array $shipmentIds)
	{
		return self::checkShipmentIdsBeforeUpdate($shipmentIds);
	}

	/**
	 * @param int[] $shipmentIds
	 * @return ShipmentResult[]
	 * @throws \Bitrix\Main\ArgumentException
	 */
	protected static function checkShipmentIdsBeforeUpdate(array $shipmentIds)
	{
		$result = array();
		$positiveIds = self::filterPositiveIds($shipmentIds);

		foreach(array_diff($shipmentIds, $positiveIds) as $id)
		{
			$shpRes = new ShipmentResult($id);
			$shpRes->addError(
				new Main\Error(
					Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHIPMENT_ID').' "'.$id.'"')
			);
			$result[] = $shpRes;
		}

		$addedIds = self::filterAddedIds($positiveIds);

		foreach(array_diff($positiveIds, $addedIds) as $id)
		{
			$shpRes = new ShipmentResult($id);
			$shpRes->addError(
				new Main\Error(
					Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHIPMENT_NOT_IN_REQUEST', array('#SHIPMENT_ID#' => $id)
			)));
			$result[] = $shpRes;
		}

		$existingIds = self::filterExistIds($addedIds);

		foreach(array_diff($addedIds, $existingIds) as $id)
		{
			$shpRes = new ShipmentResult($id);
			$shpRes->addError(
				new Main\Error(
					Loc::getMessage('SALE_DLVR_REQ_MNGR_SHP_NOT_FOUND', array('#SHIPMENT_ID#' => $id)
			)));
			$result[] = $shpRes;
		}

		return $result;
	}

	/**
	 * @param int $shipmentId
	 * @return bool
	 */
	public static function isShipmentSent($shipmentId)
	{
		return intval(self::getRequestIdByShipmentId($shipmentId)) > 0;
	}

	/**
	 * @param int $shipmentId
	 * @return int Request ID
	 * @throws Main\ArgumentException
	 */
	public static function getRequestIdByShipmentId($shipmentId)
	{
		$result = 0;

		$res = ShipmentTable::getList(array(
			'filter' => array(
				'=SHIPMENT_ID' => $shipmentId,
			)
		));

		if($row = $res->fetch())
			$result = $row['REQUEST_ID'];

		return $result;
	}

	/**
	 * @param int $requestId
	 * @param int [] $shipmentIds
	 * @return Result
	 * @throws \Exception
	 */
	public static function addShipmentsToDeliveryRequest($requestId, array $shipmentIds)
	{
		$result = new Result();

		if(empty($requestId))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_ID')));
			return $result;
		}

		if(empty($shipmentIds))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHP_ID_LIST_EMPTY')));
			return $result;
		}

		if(!($deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId)))
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHP_ADD2').'. '.
					Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_OBJ',
						"",
						$requestId
			)));
			return $result;
		}

		$checkResults = self::checkShipmentIdsBeforeAdd($shipmentIds);

		foreach($checkResults as $res)
		{
			if($res->isSuccess())
				continue;

			$result->addResult(
				self::processShipmentResult(
					$res
				));

			unset($shipmentIds[array_search($res->getInternalId(), $shipmentIds)]);
		}

		if(empty($shipmentIds))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHP_ABSENT')));
			return $result;
		}

		$res = $deliveryRequestHandler->addShipments($requestId, $shipmentIds);

		if($res->isSuccess())
		{
			$result->addResults($res->getResults());
		}
		else
		{
			$result->addErrors($res->getErrors());

			foreach($res->getShipmentResults() as $sRes)
				$result->addResult(self::processShipmentResult($sRes));

			return $result;
		}

		$results = $result->getResults();

		if(!is_array($results) || empty($results))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_RES_UNKNOWN')));
			return $result;
		}

		$successResCount = 0;

		/** @var RequestResult $reqRes */
		foreach($results as $resId => $reqRes)
		{
			if($reqRes instanceof ShipmentResult)
			{
				$results[$resId] = self::processShipmentResult($reqRes, $requestId);
			}
			elseif($reqRes instanceof RequestResult)
			{
				$reqShpResults = $reqRes->getShipmentResults();

				foreach($reqShpResults as $id => $shpRes)
				{
					$reqShpResults[$id] = self::processShipmentResult($shpRes, $requestId);

					if($shpRes->isSuccess())
						$successResCount++;
				}

				$reqRes->setResults($reqShpResults);
				$results[$resId] = $reqRes;
			}
			else
			{
				$result->addError(
					new Main\Error(
						Loc::getMessage(
							'SALE_DLVR_REQ_MNGR_RES_WRONG',
							array(
								'#CLASS_NAME#' => get_class($reqRes),
								'#REQUEST_ID#' => $requestId
							)
						)
					)
				);

				continue;
			}
		}

		if($successResCount <= 0)
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHP_ABSENT2')));

		$result->setResults($results);
		return $result;
	}

	/**
	 * @param int $requestId
	 * @param int [] $shipmentIds
	 * @return Result
	 * @throws \Exception
	 */
	public static function updateShipmentsFromDeliveryRequest($requestId, array $shipmentIds)
	{
		$result = new Result();

		if(empty($requestId))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_ID')));
			return $result;
		}

		if(empty($shipmentIds))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SHP_ID_LIST_EMPTY')));
			return $result;
		}

		$checkResults = self::checkShipmentIdsBeforeUpdate($shipmentIds);

		foreach($checkResults as $res)
		{
			if($res->isSuccess())
				continue;

			$result->addResult(
				self::processShipmentResult($res, $requestId)
			);

			unset($shipmentIds[array_search($res->getInternalId(), $shipmentIds)]);
		}

		if(empty($shipmentIds))
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_ERROR_SHP_UPD',
						array('#REQUEST_LINK#' => Helper::getRequestViewLink($requestId))
			)));
			return $result;
		}

		$deliveryRequestHandler = self::getDeliveryRequestHandlerByRequestId($requestId);

		if(!$deliveryRequestHandler)
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_ERROR_SHP_UPD',
						array('#REQUEST_LINK#' => Helper::getRequestViewLink($requestId))
					).'. '.
					Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_REQ_OBJ')
			));

			return $result;
		}

		$res = $deliveryRequestHandler->updateShipments($requestId, $shipmentIds);
		$result->addResults($res->getResults());

		if(!$res->isSuccess())
		{
			$result->addErrors($res->getErrors());
			return $result;
		}

		$results = $res->getResults();

		if(empty($results))
		{
			$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_RES_EMPTY')));
			return $result;
		}

		$resultsFinal = array();

		foreach($results as $res)
		{
			if($res instanceof ShipmentResult)
			{
				$resultsFinal[] = self::processShipmentResult($res, $requestId);
			}
			elseif($res instanceof RequestResult)
			{
				$reqShpResults = $res->getShipmentResults();

				foreach($reqShpResults as $id => $shpRes)
				{
					$shpRes = self::processShipmentResult($shpRes, $requestId);

					if($shpRes->isSuccess())
					{
						$shpInternalId = intval($shpRes->getInternalId());
						//Unset mark about changed shipments
						self::unSetMarkerShipmentChanged($shpInternalId);

						$dbRes = self::saveShipmentResult($shpRes->getInternalId(), $shpRes);

						if(!$dbRes->isSuccess())
							$shpRes->addErrors($dbRes->getErrors());
					}

					$resultsFinal[] = $shpRes;
				}
			}
			else
			{
				$result->addError(
					new Main\Error(
						Loc::getMessage('SALE_DLVR_REQ_MNGR_RES_WRONG_UPD')
				));

				continue;
			}
		}

		$result->setResults($resultsFinal);
		return $result;
	}

	/**
	 * @param $shipmentId
	 * @param ShipmentResult $shipmentResult
	 * @return Result
	 * @throws Main\ArgumentException
	 * @throws Main\ArgumentNullException
	 * @throws Main\ArgumentOutOfRangeException
	 * @throws Main\NotSupportedException
	 * @throws Main\ObjectNotFoundException
	 * @throws \Exception
	 */
	protected static function saveShipmentResult($shipmentId, ShipmentResult $shipmentResult)
	{
		$result = new Result();
		$shipments = Helper::getShipmentsByIds(array($shipmentId));

		if($shipments[$shipmentId])
		{
			$shipments[$shipmentId]->setFields(array(
				'TRACKING_NUMBER' => $shipmentResult->getTrackingNumber(),
				'DELIVERY_DOC_NUM' => $shipmentResult->getDeliveryDocNum(),
				'DELIVERY_DOC_DATE' => $shipmentResult->getDeliveryDocDate()
			));

			$res = $shipments[$shipmentId]->save();

			if(!$res->isSuccess())
				$result->addError(new Main\Error(Loc::getMessage('SALE_DLVR_REQ_MNGR_ERROR_SAVE_SHIPMENT').'"'.$shipmentId.'"'));
		}
		else
		{
			$result->addError(
				new Main\Error(
					Loc::getMessage(
						'SALE_DLVR_REQ_MNGR_SHP_NOT_FOUND',
						array('#SHIPMENT_ID#' => $shipmentId)
			)));
		}

		return $result;
	}

	/**
	 * @param Order $order
	 * @param Shipment $shipment
	 */
	public static function onBeforeShipmentSave(&$order, &$shipment)
	{
		if(self::isShipmentSent($shipment->getId()))
		{
			self::setMarkerShipmentChanged($order, $shipment);
		}
	}

	/**
	 * @param Shipment $shipment
	 */
	public static function onBeforeShipmentDelete(&$shipment)
	{
		$shipmentId = $shipment->getId();

		if(self::isShipmentSent($shipmentId))
		{
			self::deleteShipmentsFromDeliveryRequest(
				self::getRequestIdByShipmentId($shipmentId),
				array($shipmentId)
			);
		}
	}

	/**
	 * @param Order $order
	 * @param Shipment $shipment
	 */
	protected static function setMarkerShipmentChanged(&$order, &$shipment)
	{
		$r = new \Bitrix\Sale\Result();

		$r->addWarning(
			new ResultWarning(
				Loc::getMessage(
					'SALE_DLVR_REQ_MNGR_NOT_UPDATED'
				),
				'DELIVERY_REQUEST_NOT_UPDATED'
		));

		EntityMarker::addMarker($order, $shipment, $r);
		$shipment->setField('MARKED', 'Y');
	}

	/**
	 * @param int  $shipmentId
	 */
	protected static function unSetMarkerShipmentChanged($shipmentId)
	{
		EntityMarker::deleteByFilter(array(
			'=ENTITY_TYPE' => EntityMarker::ENTITY_TYPE_SHIPMENT,
			'=ENTITY_ID' => $shipmentId,
			'=CODE' => 'DELIVERY_REQUEST_NOT_UPDATED'
		));
	}

	public static function initJs()
	{
		\CJSCore::RegisterExt('sale_delivery_requests', array(
			'js' => '/bitrix/js/sale/delivery_request.js',
			'lang' => '/bitrix/modules/sale/lang/' . LANGUAGE_ID . '/admin/js/sale_delivery_requests.php',
			'rel' => array('core', 'ajax')
		));

		\CUtil::InitJSCore(array('sale_delivery_requests'));
	}
}

Zerion Mini Shell 1.0