How to implement the binding of the coupon to the order in Bitrix?

When ordering you need to add each product in your shipment, with the entire functionality of the coupons should be saved?

The problem is that when you remove the shipment or item of the shipment in the event onSaleComponentOrderCreated (runs with object is not created order) flies the binding of the coupon to the order. ie it runs but not put in the order

Event onSaleComponentOrderCreated works in sale.order.ajax, ie, the order exists only as an object
/** @var Sale\ShipmentCollection $shipmentCollection */
 $shipmentCollection = $order->getShipmentCollection();
 $service = Sale\Delivery\Services\Manager::getById(Sale\Delivery\Services\EmptyDeliveryService::getEmptyDeliveryServiceId());
 /** @var Sale\Shipment $shipment */
 foreach ($shipmentCollection as $shipment)
{

if($shipment->isSystem())
continue;

 $shipmentItemCollection = $shipment->getShipmentItemCollection();
 $firstProduct = true;
 if($shipmentItemCollection->count() > 1)
{
 //Loop through all items on the shipment and the addition of new shipments
 /** @var Sale\ShipmentItem $item */
 foreach ($shipmentItemCollection as $key=>$item)
{
 $basketItem = $item->getBasketItem();

if($basketItem->isBundleChild())
continue;

 if($firstProduct == true)
 { //The first product is not removed from the shipment
 $firstProduct = false;
continue;
}
$item->delete();

 $newShipment = $shipmentCollection->createItem();
 $newShipmentItemCollection = $newShipment->getShipmentItemCollection();
 $newShipment->setField('CURRENCY', $order->getCurrency());
 /** @var Sale\ShipmentItem $shipmentItem */
 $shipmentItem = $newShipmentItemCollection->createItem($basketItem);
$shipmentItem->setQuantity($basketItem->getQuantity());

$newShipment->setFields(array(
 'DELIVERY_ID' => $service['ID'],
 'DELIVERY_NAME' => $service['NAME'],
 'CURRENCY' => $order->getCurrency()
));
}
}
 }
June 3rd 19 at 20:21
1 answer
June 3rd 19 at 20:23
I found the reason for such a behavior, namely:

1. it is necessary to recalculate the discount and the basket method
$order->getDiscount()->calculate();
2. class Discount method loadShipment

if ($this->isOrderNew())
{
 foreach ($orderShipmentList as $shipment)
{
 if ($shipment->isSystem())
continue;


 if (!$loadDelivery)
{
 $this->shipment = $shipment;
 $loadDelivery = true;
}
else
{
 $result->addError(new Main\Entity\EntityError(
Loc::getMessage('BX_SALE_DISCOUNT_ERR_TOO_MANY_SHIPMENT'),
self::ERROR_ID
));


 return $result;
}
}
}


Which suggests that new (created) order with only one shipping will be calculated.

That says TP Bitrix - 23.07.2018

Based on the information from this treatment was created in the application development Department.
Deadlines are established in the Department of development and depend on the current work plan. To call some time solutions is currently not possible.
"With the implementation of $shipment->delete(); and use in the basket of Coupons In the created order there is no reference to the Coupons."
Application number: 102288

Find more questions by tags 1C-Bitrix