# Splitting a Merged Order Item

This document explains the concept, functionality, and API operations associated with the **Merged Order Item** in Omnitron. It provides details on quantity management, split operations, conditions, error handling, and related models.

Splitting a merged order item in Omnitron provides flexibility and precision in managing order quantities, particularly for scenarios involving order modifications, fulfillment adjustments, or customer requests. Below are examples of why someone might need to use this feature:

**1. Order Amendments**

***Scenario**:*

A customer changes their mind and wants to cancel part of their order. For example, they ordered 5 units of a product but now want only 3.

***Solution**:*

Split the merged order item into two:

* One order item with a quantity of 3 (retained by the customer).
* Another order item with a quantity of 2 (processed for cancellation).

**2. Handling Returns or Replacements**

***Scenario**:*

A customer orders 6 units of a product, but 2 of the units are damaged and need replacement.

***Solution**:*

Split the merged order item into two:

* One order item with a quantity of 4 (undamaged units retained).
* Another order item with a quantity of 2 (processed for return or replacement).

## <mark style="color:red;">Merged Order Item</mark>

In **Omnitron**, each order item within an order is recorded with the quantity of the product. A single order item can represent multiple units of the same product. For example, if an order includes two units of the same product, one **merged order item** is created, and its quantity is recorded as 2.

### Quantity Key in Order Item Attributes

The quantity is defined using a keyword stored in the `attributes` field of the order item. This keyword, known as `ORDER_ITEM_QUANTITY_KEY`, is dynamic and must be defined in the environment configuration file.

**Example:** If `ORDER_ITEM_QUANTITY_KEY` is defined as `quantity`:

```json
"attributes": {
    "quantity": 4
}
```

### Calculation in Merged Order Item

Order items that represent multiple units of a product are referred to as **Merged Order Items**. The values of fields like `price`, `discount_amount`, `retail_price`, and `installment_interest_amount` in a merged order item are calculated based on the total quantity.

**Example Calculation:**

For a merged order item, the `price` is calculated by multiplying the unit price by the total quantity:

* **Unit Price**: 100₺
* **Quantity**: 3

**Total Price (price)** = Unit Price × Quantity = 100 × 3 = 300₺

## <mark style="color:red;">Splitting a Merged Order Item</mark>

A merged order item can be split into two order items based on the specified quantity. The first item is the updated version of the original order item, and the second is a new order item.

### `POST` Split Merged Order Item

**Path:** `api/v1/order_items/{pk}/split/`

#### **Example Request Body**

The `waiting_quantity` field in the request body is used to specify the quantity of items that should be split from the original order item. This integer value determines the number of items to be extracted from the merged order item and moved into a new order item. The remaining quantity after the split will stay in the original order item, and its `quantity` field will be updated accordingly.

For example,

* if the original order item has a `quantity` of 10,
* and the `waiting_quantity` is set to 2,\
  the split operation will create a new order item with a `quantity` of 2 while reducing the original order item's `quantity` to 8.

```
{
    "waiting_quantity": 2 <int>
}
```

{% hint style="warning" %}
The value of `waiting_quantity` must be less than the current `quantity` of the original order item.
{% endhint %}

#### **Example Response**

The example response illustrates the details of the newly created order item after a successful split operation. Key points of the response are as follows:

* pk: This is the unique identifier (primary key) for the newly created order item. In this example, the new order item has the ID `2`.
* order: Indicates the associated order ID to which the new order item belongs. It remains the same as the original order item's order ID (`3` in this example).
* product: Specifies the ID of the product associated with the new order item. This value is inherited from the original order item and remains consistent (`4` in this example).
* attributes:
  * quantity: Reflects the `waiting_quantity` value provided in the request body. This shows the number of items included in the newly created order item (`2` in this case).

```json
{
    "pk": 2,
    "order": 3,
    "product": 4,
    "attributes": {
        "quantity": 2
    },
    ...
}
```

### Pre-Split State

**Path:** `api/v1/order_items/{pk}`

#### **Response Body**

```json
{
    "pk": 1,
    "attributes": {
        "quantity": 10
    },
    "price": "150.00",
    ...
}
```

### Post-Split State

**Path:** `api/v1/order_items/{pk}`

**Updated Original Order Item:**

```json
{
    "pk": 1,
    "attributes": {
        "quantity": 8
    },
    "price": "120.00",
    ...
}
```

**New Order Item**:

```json
{
    "pk": 2,
    "attributes": {
        "quantity": 2
    },
    "price": "30.00",
    ...
}
```

### Proportional Value Distribution

When a merged order item is split, fields like `price`, `retail_price`, and `discount_amount` are distributed proportionally.

Let’s assume we have an initial order item consisting of 3 products with the following details:

* quantity: 3
* price: 300 ₺
* retail\_price: 330 ₺
* discount\_amount: 30 ₺
* installment\_interest\_amount: 15 ₺

When this order item is split into two new order items—one with 1 product and the other with 2 products—the values are distributed proportionally as follows:

**1. New Order Item (1 Product)**

* quantity: 1
* price: 100 ₺ (300 / 3 \* 1)
* retail\_price: 110 ₺ (330 / 3 \* 1)
* discount\_amount: 10 ₺ (30 / 3 \* 1)
* installment\_interest\_amount: 5 ₺ (15 / 3 \* 1)

**2. New Order Item (2 Products)**

* quantity: 2
* price: 200 ₺ (300 / 3 \* 2)
* retail\_price: 220 ₺ (330 / 3 \* 2)
* discount\_amount: 20 ₺ (30 / 3 \* 2)
* installment\_interest\_amount: 10 ₺ (15 / 3 \* 2)

### Conditions for Splitting

The following conditions must be met for the split operation:

1. `ORDER_ITEM_QUANTITY_KEY` **must be defined** in the environment file.
2. The **sales channel type** of the order must be **Web**.
3. The `waiting_quantity` must be **less than** the current quantity of the order item.
4. The order item **must not have an active Cancellation Plan**. (Cancellation Plans with a status other than *cancelled* or *rejected* are considered active.)
5. The order item **must not have an active Cancellation Request**. (Cancellation Requests with a status other than *rejected* are considered active.)

If any condition is not met, the operation is rolled back, and an error message is returned.

### Common Errors and Responses

1. `ORDER_ITEM_QUANTITY_KEY` not defined:

```json
{
    "non_field_errors": "OrderItem couldn't be split, because it is not enabled. Please consult your administrator.",
    "error_code": "order_item_103_10"
}

```

2. Channel type is not Web:

```json
{
    "non_field_errors": "OrderItem: {pk} can not be split. Channel type must be 'Web'.",
    "error_code": "order_item_103_1"
}

```

3. `waiting_quantity` is greater than or equal to the current quantity:

```json
{
    "non_field_errors": "OrderItem: {pk} can not be split. waiting_quantity: {int} must be smaller than OrderItem {ORDER_ITEM_QUANTITY_KEY}: {int}.",
    "error_code": "order_item_103_2"
}
```

4. Active Cancellation Plan exists:

```json
{
    "non_field_errors": "OrderItem: {pk} can not be split. There is a Cancellation Plan with status {status} on OrderItem.",
    "error_code": "order_item_103_3"
}
```

5. Active Cancellation Request exists:

```json
{
    "non_field_errors": "OrderItem: {pk} can not be split. There is a Cancellation Request with status {status} on OrderItem.",
    "error_code": "order_item_103_4"
}
```

### Additional Errors During Split Operation

If an error occurs during the split operation, the following error messages are provided to the user:

1. When the total quantity of the resulting order items after the split does not equal the original quantity:

```json
{
    "non_field_errors": "The initial Order Item {key} is not equal to the sum of the split Order Items {key}.",
    "error_code": "order_item_103_5"
}
```

2. When the split operation is successful, but the request to update Commerce fails:

```json
{
    "non_field_errors": "OrderItem: {pk} couldn't be split because it couldn't be updated on Commerce. Commerce error_message: {error}",
    "error_code": "order_item_103_6"
}
```

3. When the split operation and the update request to Commerce are successful, but the newly created order item cannot be transmitted to Commerce:

```json
{
    "non_field_errors": "OrderItem split operation is rolled back because split OrderItem couldn't be created on Commerce even though the OrderItem {} was updated on Commerce. Commerce error_message: {}",
    "error_code": "order_item_103_7"
}
```

4. When an error occurs while updating the model records during the split operation:

```json
{
    "non_field_errors": "OrderItem couldn't be split because of an error during the process of updating {model} fields. error_message: {error}",
    "error_code": "order_item_103_8"
}
```

5. When an error occurs while splitting records related to the order item during the split operation:

```json
{
    "non_field_errors": "OrderItem couldn't be split because of an error during the process of splitting {model}. error_message: {error}",
    "error_code": "order_item_103_9"
}
```
