Частичная скидка — это скидка, которая распространяется не на все позиции в заказе, а только на некоторые. Чтобы понять, на какие именно позиции действует частичная скидка, используется параметр discount_order_lines_ids. Этот параметр является массивом идентификаторов позиций заказа (order_line.id), которые могут быть заданы в числовом или строковом представлении. Если скидка действует сразу на все позиции (не является частичной), то указанный параметр discount_order_lines_ids либо содержит идентификаторы всех позиций, либо его значение отсутствует вовсе.
Кроме массива discount_order_lines_ids в ответах на запросы присутствует еще один параметр - discount_products_ids — массив, содержащий идентификаторы товаров, на которые действует скидка. Параметр discount_products_ids будет правильно обработан и в запросах, если указать его вместо discount_order_lines_ids.
К сожалению, существует ряд случаев, когда невозможно установить взаимно-однозначное соответсвие между идентификаторами в массивах discount_order_lines_ids и discount_products_ids. Самым простым примером является случай, когда в заказе присутствуют две модификации одного и того же товара, но скидка должна распространяться только на одну из этих модификаций.
Однако есть и более сложные ситуации, когда в заказе присутствуют две позиции с одинаковыми product_id и variant_id, а скидка, при этом, распространяется только на одну из этих позиций. И это — штатное поведение, а подобные случаи встречаются на практике не так уж и редко, особенно, если магазин использует комплекты.
Предположим, что у нас есть комплект K состоящий из двух товаров (A и B). Этот комплект уценен, и скидки на него не распространяются. А на товары A и B — распространяются (если покупать их вне комплекта). Покупатель кладет в корзину комплекты К и товар A. У клиента есть накопительная скидка. Она применяется только к товару А. К товару K скидка не применяется, так как он уценен. Казалось бы, все хорошо, ведь в корзине два разных товара К и A. Но при создании заказа (в ходе расщепления комплекта) К превращается в A и B. Вот такой у нас получится заказ:
1. A - на эту позицию действует скидка.
2. A из комплекта К, у него другая цена, и скидка на него не распространяется.
3. B из комплекта К, на него тоже не распространяется скидка.
Выводы:
1. Нельзя идентифицировать позицию по variant_id (и уж тем более по product_id).
2. Если вы использовали discount_products_ids, то надо переходить на discount_order_lines_ids.
3. Если вы не хотите знать как InSales распределяет скидку по позициям, то достаточно использовать full_total_price у позиций заказа order_lines, там уже всё посчитано.
Важно: по идеологическим соображениям внешние частичные скидки пока не поддерживают discount_order_lines_ids, и для них по-прежнему необходимо передавать discount_products_ids. Если же попробовать их применить к уже созданному заказу, то приложение получит расщепленный состав заказа. Так как в большинстве случаев внешние скидки нужны при создании заказа, то данный нюанс на данный момент не реализован другим способом.
Другим важным моментом является то, что одновременное указание в параметрах обоих массивов discount_order_lines_ids и discount_products_ids (в т.ч. с противоречивыми значениями) не приведет к ошибке, но это крайне нежелательно, т.к. результат расчета скидки в случаях, когда нет взаимно-однозначного соответствия идентификаторов, сложно предсказать. Поэтому не следует этого делать даже в тех случаях, когда есть необходимость использовать параметр discount_products_ids.
API InSales не предоставляет средств для применения к заказу частичных скидок во время создания заказа с помощью параметра discount_order_lines_ids, а параметр discount_products_ids по описанным выше причинам использовать не следует. Однако API позволяет создать или добавить частичную скидку к уже созданному заказу, либо сделать частичной ранее примененную скидку (в т.ч. скидочный купон). Для этого необходимо при обновлении заказа указать параметр discounts_attributes — массив хешей, содержащих атрибуты применяемых к заказу скидок, в т.ч. discount_order_lines_ids.
Параметр discounts в ответе на запрос обновления заказа содержит атрибуты всех примененных скидок. Параметр discount (в единственном числе) — псевдоним для первого элемента массива discounts, он используется для обратной совместимости и не рекомендуется к использованию в новом программном коде.