/**
  * @internal
  * @param Shipment $parentShipment
  * @param Shipment $childShipment
  * @return Result
  * @throws Main\ArgumentOutOfRangeException
  */
 public function cloneShipment(Shipment $parentShipment, Shipment $childShipment)
 {
     foreach (static::getClonedFields() as $fieldName) {
         /** @var Result $r */
         $childShipment->setFieldNoDemand($fieldName, $parentShipment->getField($fieldName));
     }
     $childShipment->setExtraServices($parentShipment->getExtraServices());
     $childShipment->setStoreId($parentShipment->getStoreId());
     return new Result();
 }
Exemple #2
0
 /**
  * Modify shipment collection.
  *
  * @param string $action				Action code.
  * @param Shipment $shipment			Shipment.
  * @param null|string $name					Field name.
  * @param null|string|int|float $oldValue				Old value.
  * @param null|string|int|float $value					New value.
  * @return bool
  *
  * @throws Main\NotImplementedException
  * @throws \Bitrix\Main\ArgumentException
  * @throws \Bitrix\Main\ArgumentOutOfRangeException
  * @throws \Bitrix\Main\NotSupportedException
  * @throws \Exception
  */
 public function onShipmentCollectionModify($action, Shipment $shipment, $name = null, $oldValue = null, $value = null)
 {
     global $USER;
     $result = new Result();
     if ($action == EventActions::DELETE) {
         if ($this->getField('DELIVERY_ID') == $shipment->getDeliveryId()) {
             /** @var ShipmentCollection $shipmentCollection */
             if (!($shipmentCollection = $shipment->getCollection())) {
                 throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
             }
             $foundShipment = false;
             /** @var Shipment $entityShipment */
             foreach ($shipmentCollection as $entityShipment) {
                 if ($entityShipment->isSystem()) {
                     continue;
                 }
                 if (intval($entityShipment->getField('DELIVERY_ID')) > 0) {
                     $foundShipment = true;
                     $this->setFieldNoDemand('DELIVERY_ID', $entityShipment->getField('DELIVERY_ID'));
                     break;
                 }
             }
             if (!$foundShipment && !$shipment->isSystem()) {
                 /** @var Shipment $systemShipment */
                 if (($systemShipment = $shipmentCollection->getSystemShipment()) && intval($systemShipment->getField('DELIVERY_ID')) > 0) {
                     $this->setFieldNoDemand('DELIVERY_ID', $systemShipment->getField('DELIVERY_ID'));
                 }
             }
         }
     }
     if ($action != EventActions::UPDATE) {
         return $result;
     }
     // PRICE_DELIVERY, ALLOW_DELIVERY, DEDUCTED, MARKED
     // CANCELED, DELIVERY_ID
     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()) {
             $event = new Main\Event('sale', EventActions::EVENT_ON_SHIPMENT_DELIVER, array('ENTITY' => $shipment));
             $event->send();
         } else {
             $result->addErrors($r->getErrors());
         }
         if (Configuration::getProductReservationCondition() == Configuration::RESERVE_ON_ALLOW_DELIVERY) {
             if ($value == "Y") {
                 /** @var Result $r */
                 $r = $shipment->tryReserve();
                 if (!$r->isSuccess()) {
                     $shipment->setField('MARKED', 'Y');
                     if (is_array($r->getErrorMessages())) {
                         $oldErrorText = $shipment->getField('REASON_MARKED');
                         foreach ($r->getErrorMessages() as $error) {
                             $oldErrorText .= (strval($oldErrorText) != '' ? "\n" : "") . $error;
                         }
                         $shipment->setField('REASON_MARKED', $oldErrorText);
                     }
                     $result->addErrors($r->getErrors());
                 }
             } else {
                 if (!$shipment->isShipped()) {
                     /** @var Result $r */
                     $r = $shipment->tryUnreserve();
                     if (!$r->isSuccess()) {
                         $result->addErrors($r->getErrors());
                     }
                 }
             }
             if (!$result->isSuccess()) {
                 return $result;
             }
         }
         if ($oldValue == "N") {
             $orderStatus = Config\Option::get('sale', 'status_on_allow_delivery', '');
             if (strval($orderStatus) != '') {
                 if ($USER && $USER->isAuthorized()) {
                     $statusesList = OrderStatus::getAllowedUserStatuses($USER->getID(), $this->getField('STATUS_ID'));
                 } else {
                     $statusesList = OrderStatus::getAllStatuses();
                 }
                 if ($this->getField('STATUS_ID') != $orderStatus && array_key_exists($orderStatus, $statusesList)) {
                     /** @var Result $r */
                     $r = $this->setField('STATUS_ID', $orderStatus);
                     if (!$r->isSuccess()) {
                         $result->addErrors($r->getErrors());
                         return $result;
                     }
                 }
             }
         }
         if (Configuration::needShipOnAllowDelivery() && $value == "Y") {
             $shipment->setField("DEDUCTED", "Y");
         }
         /** @var ShipmentCollection $shipmentCollection */
         if (!($shipmentCollection = $this->getShipmentCollection())) {
             throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
         }
         if ($shipmentCollection->isAllowDelivery() && $this->getField('ALLOW_DELIVERY') == 'N') {
             $this->setFieldNoDemand('DATE_ALLOW_DELIVERY', new Type\DateTime());
         }
         $this->setFieldNoDemand('ALLOW_DELIVERY', $shipmentCollection->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::getProductReservationCondition() == Configuration::RESERVE_ON_SHIP) {
             if ($value == "Y") {
                 /** @var Result $r */
                 $r = $shipment->tryReserve();
                 if (!$r->isSuccess()) {
                     $shipment->setField('MARKED', 'Y');
                     if (is_array($r->getErrorMessages())) {
                         $oldErrorText = $shipment->getField('REASON_MARKED');
                         foreach ($r->getErrorMessages() as $error) {
                             $oldErrorText .= (strval($oldErrorText) != '' ? "\n" : "") . $error;
                         }
                         $shipment->setField('REASON_MARKED', $oldErrorText);
                     }
                     $result->addErrors($r->getErrors());
                     return $result;
                 }
             } else {
                 $shipment->tryUnreserve();
             }
         }
         if ($value == "Y") {
             /** @var Result $r */
             $r = $shipment->tryShip();
             if (!$r->isSuccess()) {
                 $shipment->setField('MARKED', 'Y');
                 if (is_array($r->getErrorMessages())) {
                     $oldErrorText = $shipment->getField('REASON_MARKED');
                     foreach ($r->getErrorMessages() as $error) {
                         $oldErrorText .= (strval($oldErrorText) != '' ? "\n" : "") . $error;
                     }
                     $shipment->setField('REASON_MARKED', $oldErrorText);
                 }
                 $result->addErrors($r->getErrors());
                 return $result;
             }
         } elseif ($oldValue == 'Y') {
             /** @var Result $r */
             $r = $shipment->tryUnship();
             if (!$r->isSuccess()) {
                 /** @var Result $resultShipment */
                 $resultShipment = $shipment->setField('MARKED', 'Y');
                 if (!$resultShipment->isSuccess()) {
                     $result->addErrors($r->getErrors());
                 }
                 if (is_array($r->getErrorMessages())) {
                     $oldErrorText = $shipment->getField('REASON_MARKED');
                     foreach ($r->getErrorMessages() as $error) {
                         $oldErrorText .= (strval($oldErrorText) != '' ? "\n" : "") . $error;
                     }
                     /** @var Result $resultShipment */
                     $resultShipment = $shipment->setField('REASON_MARKED', $oldErrorText);
                     if (!$resultShipment->isSuccess()) {
                         $result->addErrors($r->getErrors());
                     }
                 }
                 $result->addErrors($r->getErrors());
                 return $result;
             }
         }
         /** @var ShipmentCollection $shipmentCollection */
         $shipmentCollection = $shipment->getCollection();
         $this->setFieldNoDemand('DEDUCTED', $shipmentCollection->isShipped() ? "Y" : "N");
         if ($shipmentCollection->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") {
         if (!empty($value)) {
             $orderReasonMarked = $this->getField('REASON_MARKED');
             if (is_array($value)) {
                 $newOrderReasonMarked = '';
                 foreach ($value as $err) {
                     $newOrderReasonMarked .= (strval($newOrderReasonMarked) != '' ? "\n" : "") . $err;
                 }
             } else {
                 $newOrderReasonMarked = $value;
             }
             /** @var Result $r */
             $r = $this->setField('REASON_MARKED', $orderReasonMarked . (strval($orderReasonMarked) != '' ? "\n" : "") . $newOrderReasonMarked);
             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;
         }
         /** @var ShipmentCollection $shipmentCollection */
         if (!($shipmentCollection = $shipment->getCollection())) {
             throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
         }
         $discount = $this->getDiscount();
         $discount->setCalculateShipments($shipment);
         $r = $shipment->setField('PRICE_DELIVERY', $value);
         if (!$r->isSuccess()) {
             $result->addErrors($r->getErrors());
         }
     } 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;
         }
         /** @var ShipmentCollection $shipmentCollection */
         if (!($shipmentCollection = $shipment->getCollection())) {
             throw new Main\ObjectNotFoundException('Entity "ShipmentCollection" not found');
         }
         $this->setFieldNoDemand("PRICE_DELIVERY", $this->getField("PRICE_DELIVERY") - $oldValue + $value);
         /** @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'));
     }
     return $result;
 }
 /**
  * @param Order $order
  * @param array $shipments
  * @return Result
  * @throws SystemException
  */
 public static function updateData(Order &$order, array $shipments)
 {
     global $USER;
     $result = new Result();
     $data = array();
     $basketResult = null;
     if (!$order) {
         $result->addError(new EntityError(Loc::getMessage('SALE_ORDER_SHIPMENT_ERROR_ORDER_NOT_FOUND')));
         return $result;
     }
     $shipmentCollection = $order->getShipmentCollection();
     $isStartField = $shipmentCollection->isStartField();
     foreach ($shipments as $item) {
         $shipmentId = intval($item['SHIPMENT_ID']);
         $isNew = $shipmentId <= 0;
         if ($isNew) {
             self::$shipment = $shipmentCollection->createItem();
         } else {
             self::$shipment = $shipmentCollection->getItemById($shipmentId);
             if (!self::$shipment) {
                 $result->addError(new EntityError(Loc::getMessage('SALE_ORDER_SHIPMENT_ERROR_SHIPMENT_NOT_FOUND')));
                 continue;
             }
         }
         self::$defaultFields = self::$shipment->getFieldValues();
         /** @var \Bitrix\Sale\BasketItem $product */
         $countItems = count(self::$shipment->getShipmentItemCollection());
         $systemShipment = $shipmentCollection->getSystemShipment();
         $systemShipmentItemCollection = $systemShipment->getShipmentItemCollection();
         $products = array();
         if (!isset($item['PRODUCT']) && self::$shipment->getId() <= 0) {
             $basket = $order->getBasket();
             if ($basket) {
                 $basketItems = $basket->getBasketItems();
                 foreach ($basketItems as $product) {
                     $systemShipmentItem = $systemShipmentItemCollection->getItemByBasketCode($product->getBasketCode());
                     if ($product->isBundleChild() || !$systemShipmentItem || $systemShipmentItem->getQuantity() <= 0) {
                         continue;
                     }
                     $products[] = array('AMOUNT' => $product->getQuantity(), 'BASKET_CODE' => $product->getBasketCode());
                 }
             }
         } else {
             $products = $item['PRODUCT'];
         }
         if ($item['DEDUCTED'] == 'Y') {
             $basketResult = OrderBasketShipment::updateData($order, self::$shipment, $products);
             if (!$basketResult->isSuccess()) {
                 $result->addErrors($basketResult->getErrors());
             }
         }
         $extraServices = $item['EXTRA_SERVICES'] ? $item['EXTRA_SERVICES'] : array();
         $shipmentFields = array('COMPANY_ID' => isset($item['COMPANY_ID']) && $item['COMPANY_ID'] > 0 ? $item['COMPANY_ID'] : 0, 'DEDUCTED' => $item['DEDUCTED'], 'DELIVERY_DOC_NUM' => $item['DELIVERY_DOC_NUM'], 'TRACKING_NUMBER' => $item['TRACKING_NUMBER'], 'CURRENCY' => $order->getCurrency(), 'COMMENTS' => $item['COMMENTS'], 'STATUS_ID' => $isNew ? DeliveryStatus::getInitialStatus() : $item['STATUS_ID']);
         if ($item['DELIVERY_DOC_DATE']) {
             try {
                 $shipmentFields['DELIVERY_DOC_DATE'] = new Date($item['DELIVERY_DOC_DATE']);
             } catch (Main\ObjectException $exception) {
                 $result->addError(new EntityError(Loc::getMessage('SALE_ORDER_SHIPMENT_ERROR_UNCORRECT_FORM_DATE')));
             }
         }
         $shipmentFields['DELIVERY_ID'] = $item['PROFILE'] > 0 ? $item['PROFILE'] : $item['DELIVERY_ID'];
         try {
             $service = Services\Manager::getService($shipmentFields['DELIVERY_ID']);
             if ($service->getParentService()) {
                 $shipmentFields['DELIVERY_NAME'] = $service->getParentService()->getName() . ':' . $service->getName();
             } else {
                 $shipmentFields['DELIVERY_NAME'] = $service->getName();
             }
         } catch (Main\ArgumentNullException $e) {
             $result->addError(new EntityError(Loc::getMessage('SALE_ORDER_SHIPMENT_ERROR_NO_DELIVERY_SERVICE')));
         }
         $responsibleId = self::$shipment->getField('RESPONSIBLE_ID');
         if ($item['RESPONSIBLE_ID'] != $responsibleId || empty($responsibleId)) {
             if (isset($item['RESPONSIBLE_ID'])) {
                 $shipmentFields['RESPONSIBLE_ID'] = $item['RESPONSIBLE_ID'];
             } else {
                 $shipmentFields['RESPONSIBLE_ID'] = $order->getField('RESPONSIBLE_ID');
             }
             if (!empty($shipmentFields['RESPONSIBLE_ID'])) {
                 $shipmentFields['EMP_RESPONSIBLE_ID'] = $USER->getID();
                 $shipmentFields['DATE_RESPONSIBLE_ID'] = new DateTime();
             }
         }
         if ($extraServices) {
             self::$shipment->setExtraServices($extraServices);
         }
         $setFieldsResult = self::$shipment->setFields($shipmentFields);
         if (!$setFieldsResult->isSuccess()) {
             $result->addErrors($setFieldsResult->getErrors());
         }
         self::$shipment->setStoreId($item['DELIVERY_STORE_ID']);
         if ($item['DEDUCTED'] == 'N') {
             $basketResult = OrderBasketShipment::updateData($order, self::$shipment, $products);
             if (!$basketResult->isSuccess()) {
                 $result->addErrors($basketResult->getErrors());
             }
         }
         try {
             $priceDeliveryInfo = array();
             if ($item['CUSTOM_PRICE_DELIVERY'] != 'Y') {
                 $totalPrice = self::getDeliveryPrice(self::$shipment);
             } else {
                 $totalPrice = (double) str_replace(',', '.', $item['BASE_PRICE_DELIVERY']);
             }
         } catch (\Exception $e) {
             $totalPrice = 0;
         }
         $priceDeliveryInfo['CUSTOM_PRICE_DELIVERY'] = $item['CUSTOM_PRICE_DELIVERY'];
         $priceDeliveryInfo['BASE_PRICE_DELIVERY'] = $totalPrice;
         self::$shipment->setFields($priceDeliveryInfo);
         self::$shipment->setField('ALLOW_DELIVERY', $item['ALLOW_DELIVERY']);
         $data['SHIPMENT'][] = self::$shipment;
     }
     if ($isStartField) {
         $hasMeaningfulFields = $shipmentCollection->hasMeaningfulField();
         /** @var Result $r */
         $r = $shipmentCollection->doFinalAction($hasMeaningfulFields);
         if (!$r->isSuccess()) {
             $result->addErrors($r->getErrors());
         }
     }
     $result->setData($data);
     return $result;
 }