• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/order.php
  • Класс: BitrixSaleOrder
  • Вызов: Order::onShipmentCollectionModify
public function onShipmentCollectionModify($action, Shipment $shipment, $name = null, $oldValue = null, $value = null)
{
	$result = new Result();

	$registry = Registry::getInstance(static::getRegistryType());

	$optionClassName = $registry->get(Registry::ENTITY_OPTIONS);

	/** @var EntityMarker $entityMarker */
	$entityMarker = $registry->getEntityMarkerClassName();

	if ($action === EventActions::DELETE)
	{
		if ((int)$this->getField('DELIVERY_ID') === $shipment->getDeliveryId())
		{
			$foundShipment = false;

			/** @var Shipment $entityShipment */
			foreach ($this->getShipmentCollection()->getNotSystemItems() as $entityShipment)
			{
				if ((int)$entityShipment->getField('DELIVERY_ID') > 0)
				{
					$foundShipment = true;
					$this->setFieldNoDemand('DELIVERY_ID', $entityShipment->getField('DELIVERY_ID'));
					break;
				}
			}

			if (!$foundShipment && !$shipment->isSystem())
			{
				$systemShipment = $this->getShipmentCollection()->getSystemShipment();

				if ((int)$systemShipment->getField('DELIVERY_ID') > 0)
				{
					$this->setFieldNoDemand('DELIVERY_ID', $systemShipment->getField('DELIVERY_ID'));
				}
			}
		}
	}
	elseif ($action === EventActions::ADD)
	{
		if ($shipment->getId() === 0)
		{
			$this->getPropertyCollection()->refreshRelated();
		}

		if (!$shipment->isSystem())
		{
			$this->setFieldNoDemand('DELIVERY_ID', $shipment->getDeliveryId());
		}
	}

	if ($action !== EventActions::UPDATE)
	{
		return $result;
	}

	if ($name === "ALLOW_DELIVERY")
	{
		if ($this->isCanceled())
		{
			$result->addError(new ResultError(Loc::getMessage('SALE_ORDER_ALLOW_DELIVERY_ORDER_CANCELED'), 'SALE_ORDER_ALLOW_DELIVERY_ORDER_CANCELED'));
			return $result;
		}

		$r = $shipment->deliver();
		if ($r->isSuccess())
		{
			$eventManager = MainEventManager::getInstance();
			if ($eventManager->findEventHandlers('sale', EventActions::EVENT_ON_SHIPMENT_DELIVER))
			{
				$event = new MainEvent('sale', EventActions::EVENT_ON_SHIPMENT_DELIVER, array(
					'ENTITY' =>$shipment
				));
				$event->send();
			}
		}
		else
		{
			$result->addErrors($r->getErrors());
		}

		if (
			Configuration::isEnableAutomaticReservation()
			&& Configuration::getProductReservationCondition() === ReserveCondition::ON_ALLOW_DELIVERY
		)
		{
			if ($value === "Y")
			{
				$r = $shipment->tryReserve();
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
				}

				if ($r->hasWarnings())
				{
					$result->addWarnings($r->getWarnings());
					$entityMarker::addMarker($this, $shipment, $r);
					if (!$shipment->isSystem())
					{
						$shipment->setField('MARKED', 'Y');
					}
				}
			}
			elseif (!$shipment->isShipped())
			{
				$r = $shipment->tryUnreserve();
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
				}

				if ($r->hasWarnings())
				{
					$result->addWarnings($r->getWarnings());
					$entityMarker::addMarker($this, $shipment, $r);
					if (!$shipment->isSystem())
					{
						$shipment->setField('MARKED', 'Y');
					}
				}
			}

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

		$orderStatus = null;

		if ($oldValue === "N")
		{
			if ($this->getShipmentCollection()->isAllowDelivery())
			{
				$orderStatus = $optionClassName::get('sale', 'status_on_allow_delivery', '');
			}
			elseif ($this->getShipmentCollection()->hasAllowDelivery())
			{
				$orderStatus = $optionClassName::get('sale', 'status_on_allow_delivery_one_of', '');
			}
		}

		if ($orderStatus !== null && $this->getField('STATUS_ID') != static::getFinalStatus())
		{
			if ((string)$orderStatus != '')
			{
				$r = $this->setField('STATUS_ID', $orderStatus);
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
				}

				if ($r->hasWarnings())
				{
					$result->addWarnings($r->getWarnings());
					$entityMarker::addMarker($this, $this, $r);
					$this->setField('MARKED', 'Y');
				}
			}
		}

		if (Configuration::needShipOnAllowDelivery() && $value === "Y")
		{
			if (!$shipment->isEmpty())
			{
				$r = $shipment->setField("DEDUCTED", "Y");
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
				}

				if ($r->hasWarnings())
				{
					$result->addWarnings($r->getWarnings());
					$entityMarker::addMarker($this, $shipment, $r);
					if (!$shipment->isSystem())
					{
						$shipment->setField('MARKED', 'Y');
					}
				}
			}
		}

		$isAllowDelivery = $this->getShipmentCollection()->isAllowDelivery();
		if (
			$isAllowDelivery
			&& $this->getField('ALLOW_DELIVERY') === 'N'
		)
		{
			$this->setFieldNoDemand('DATE_ALLOW_DELIVERY', new TypeDateTime());
		}

		$this->setFieldNoDemand('ALLOW_DELIVERY', $isAllowDelivery ? "Y" : "N");
	}
	elseif ($name === "DEDUCTED")
	{
		if ($this->isCanceled())
		{
			$result->addError(new ResultError(Loc::getMessage('SALE_ORDER_SHIPMENT_ORDER_CANCELED'), 'SALE_ORDER_SHIPMENT_ORDER_CANCELED'));
			return $result;
		}

		if (
			Configuration::isEnableAutomaticReservation()
			&& Configuration::getProductReservationCondition() == ReserveCondition::ON_SHIP
		)
		{
			if ($value === "Y")
			{
				/** @var Result $r */
				$r = $shipment->tryReserve();
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
				}

				if ($r->hasWarnings())
				{
					$result->addWarnings($r->getWarnings());
					$entityMarker::addMarker($this, $shipment, $r);
					if (!$shipment->isSystem())
					{
						$shipment->setField('MARKED', 'Y');
					}
				}
			}
			else
			{
				$r = $shipment->tryUnreserve();
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
				}

				if ($r->hasWarnings())
				{
					$result->addWarnings($r->getWarnings());
					$entityMarker::addMarker($this, $shipment, $r);
					if (!$shipment->isSystem())
					{
						$shipment->setField('MARKED', 'Y');
					}
				}
			}
		}

		if ($value === "Y")
		{
			/** @var Result $r */
			$r = $shipment->tryShip();
			if (!$r->isSuccess())
			{
				$result->addErrors($r->getErrors());
			}

			if ($r->hasWarnings())
			{
				$result->addWarnings($r->getWarnings());
				$entityMarker::addMarker($this, $shipment, $r);
				if (!$shipment->isSystem())
				{
					$shipment->setField('MARKED', 'Y');
				}
			}

		}
		elseif ($oldValue === 'Y')
		{
			$r = $shipment->tryUnship();
			if (!$r->isSuccess())
			{
				$result->addErrors($r->getErrors());
			}

			if ($r->hasWarnings())
			{
				$result->addWarnings($r->getWarnings());
				$entityMarker::addMarker($this, $shipment, $r);
				if (!$shipment->isSystem())
				{
					$shipment->setField('MARKED', 'Y');
				}
			}

			if (
				Configuration::isEnableAutomaticReservation()
				&& $shipment->needReservation()
			)
			{
				$r = $shipment->tryReserve();
				if (!$r->isSuccess())
				{
					$result->addErrors($r->getErrors());
				}

				if ($r->hasWarnings())
				{
					$result->addWarnings($r->getWarnings());
					$entityMarker::addMarker($this, $shipment, $r);
					if (!$shipment->isSystem())
					{
						$shipment->setField('MARKED', 'Y');
					}
				}
			}
		}

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

		$orderStatus = null;

		$allowSetStatus = false;

		if ($oldValue === "N")
		{
			if ($this->getShipmentCollection()->isShipped())
			{
				$orderStatus = $optionClassName::get('sale', 'status_on_shipped_shipment', '');
			}
			elseif ($this->getShipmentCollection()->hasShipped())
			{
				$orderStatus = $optionClassName::get('sale', 'status_on_shipped_shipment_one_of', '');
			}
			$allowSetStatus = ($this->getField('STATUS_ID') != static::getFinalStatus());
		}
		else
		{
			$fields = $this->getFields();
			$originalValues = $fields->getOriginalValues();
			if (!empty($originalValues['STATUS_ID']))
			{
				$orderStatus = $originalValues['STATUS_ID'];
				$allowSetStatus = true;
			}
		}

		if (
			(string)$orderStatus !== ''
			&& $allowSetStatus
		)
		{
			$r = $this->setField('STATUS_ID', $orderStatus);
			if (!$r->isSuccess())
			{
				$result->addErrors($r->getErrors());
			}
			elseif ($r->hasWarnings())
			{
				$result->addWarnings($r->getWarnings());
				$entityMarker::addMarker($this, $this, $r);
				$this->setField('MARKED', 'Y');
			}
		}

		$isShipped = $this->getShipmentCollection()->isShipped();
		$this->setFieldNoDemand('DEDUCTED', $isShipped ? "Y" : "N");

		if ($isShipped)
		{
			if (strval($shipment->getField('DATE_DEDUCTED')) != '')
			{
				$this->setFieldNoDemand('DATE_DEDUCTED', $shipment->getField('DATE_DEDUCTED'));
			}
			if (strval($shipment->getField('EMP_DEDUCTED_ID')) != '')
			{
				$this->setFieldNoDemand('EMP_DEDUCTED_ID', $shipment->getField('EMP_DEDUCTED_ID'));
			}
		}
	}
	elseif ($name == "MARKED")
	{
		if ($value == "Y")
		{
			/** @var Result $r */
			$r = $this->setField('MARKED', 'Y');
			if (!$r->isSuccess())
			{
				$result->addErrors($r->getErrors());
			}
		}
	}
	elseif ($name == "REASON_MARKED")
	{
		$r = $this->setReasonMarked($value);
		if (!$r->isSuccess())
		{
			$result->addErrors($r->getErrors());
		}
	}
	elseif ($name == "BASE_PRICE_DELIVERY")
	{
		if ($this->isCanceled())
		{
			$result->addError(new ResultError(Loc::getMessage('SALE_ORDER_PRICE_DELIVERY_ORDER_CANCELED'), 'SALE_ORDER_PRICE_DELIVERY_ORDER_CANCELED'));
			return $result;
		}

		$discount = $this->getDiscount();
		$discount->setCalculateShipments($shipment);
	}
	elseif ($name == "PRICE_DELIVERY")
	{
		if ($this->isCanceled())
		{
			$result->addError(new ResultError(Loc::getMessage('SALE_ORDER_PRICE_DELIVERY_ORDER_CANCELED'), 'SALE_ORDER_PRICE_DELIVERY_ORDER_CANCELED'));
			return $result;
		}

		$deliveryPrice = ($this->isNew()) ? $value : $this->getField("PRICE_DELIVERY") - $oldValue + $value;
		$this->setFieldNoDemand(
			"PRICE_DELIVERY",
			$deliveryPrice
		);

		/** @var Result $r */
		$r = $this->setField(
			"PRICE",
			$this->getField("PRICE") - $oldValue + $value
		);

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

	}
	elseif ($name == "DELIVERY_ID")
	{
		if ($shipment->isSystem() || intval($shipment->getField('DELIVERY_ID')) <= 0 )
		{
			return $result;
		}

		$this->setFieldNoDemand('DELIVERY_ID', $shipment->getField('DELIVERY_ID'));

		$this->getPropertyCollection()->refreshRelated();

	}
	elseif ($name == "TRACKING_NUMBER")
	{
		if ($shipment->isSystem())
		{
			return $result;
		}

		$this->setFieldNoDemand('TRACKING_NUMBER', $shipment->getField('TRACKING_NUMBER'));
	}

	if ($value != $oldValue)
	{
		$fields = $this->fields->getChangedValues();
		if (!empty($fields) && !array_key_exists("UPDATED_1C", $fields))
		{
			parent::setField("UPDATED_1C", "N");
		}
	}

	return $result;
}