When a sales order item contains multiple quantities, we call this item a non-split item. The original idea of these items are for items which can not be split (non-splittable items), such as 5L water in a can. In these cases the assumption is that these items always have to stay together (delivered together, returned together, etc.).
However we prepared a solution where a non-split item gets split into 2 sales order items, but this solution is not part of the repositories - was much more like a validation of theory so far.
To be able to split a non-split item, all sales order item based row (spy_sales_*) has to contain the line prices (sum price).
- Copy-create a new sales order item.
- Divide the quantity between the 2 sales order items.
- Divide the prices (including subtotals, aggregations, etc.) linearly between the 2 sales order items using the quantity ratio (see linear division explained below).
- Quantity and Amount fields have to be divided linearly using the quantity ratio
- Those tables which refer to the specific sales order item or its related data (such as product option), have to duplicate their rows on that specific sales order item. The newly created rows have to refer to the newly created sales order item and if a dividable field is present (such as price fields or quantity) it has to be divided between them. If the table has no quantity specific data (such as oms tables), only the new reference has to be set for the new records.
You will end up with 2 separate sales order item which can be moved in the state machine separately. Due the “linear” division, the discounts and all calculation will be simply linearly divided. You need to verify if this fits your requirements (due discount recalculate on 2 separate sales order item might end up with different result).
Explanation of “linear division using quantity ratio”
When you divide linearly the prices it should happen the following way:
- quantity ratio = sales order item 1 new quantity / sales order item 1 old quantity
- sales order item 1 new price = natural_round(sales order item 1 old price * quantity ratio)
- sales order item 2 new price = sales order item 1 old price - sales order item 1 new price
This is necessary to make sure that no “cent” gets lost during the process.
Note: if the price is null for some reason (it’s a valid value in some price case), then both sales order item has to end up with null value on that field.
Let’s say that you have originally 5 quantities in sales order item 1 with a price of 87.23 EUR and you want to explode this into 2-3.
The quantity ratio will be either 2/5=0.4 or 3/5=0.6 (keep this as a float number - doesn’t matter when it’s an infinite float).
- sales order item 1 new price = round(87.23 * 0.6) = 5234 (52.34 EUR)
- sales order item 2 new price = 87.23 - 52.34 = 3489 (34.89 EUR)