> For the complete documentation index, see [llms.txt](https://docs.akinon.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.akinon.com/technical-guides/oms/cancel-old-oos-packages.md).

# Cancel Old OOS Packages

`CANCEL_OLD_OOS_PACKAGES` is the env variable that enables the periodic Celery task (`cancel_old_oos_packages`) that automatically cancels package items that have been out of stock (OOS) for a long time via Omnitron. It is disabled by default; when enabled with the default settings, items that have been in the out of stock/defective/unavailable state for more than **30 days** are cancelled.

## <mark style="color:red;">How to activate it and who can change it</mark>

The feature has two layers: the **env** enables the task, and **Application Settings** determine its behavior. No item is cancelled unless all three conditions are met.

| Setting                                            | Type                | Value / format                                                                                                                   | Default                                    | Who changes it                              |
| -------------------------------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------- |
| `CANCEL_OLD_OOS_PACKAGES`                          | env                 | `true` / `false`                                                                                                                 | `false` (disabled)                         | An authorized user via Console              |
| `CANCEL_OLD_OOS_PACKAGES_CRONTAB`                  | env                 | `minute,hour,day_of_week,day_of_month,month` — UTC, e.g., `0,3,*,*,*` = every day at 03:00 UTC (06:00 TR)                        | none                                       | An authorized user via Console              |
| `CANCEL_OLD_OOS_PACKAGES_SCHEDULE`                 | env                 | Interval in seconds, minimum 20; used if CRONTAB is not set. Randomized once within ±10 seconds when beat starts and stays fixed | none                                       | An authorized user via Console              |
| `CANCELLATION_REASON_ID_FOR_OOS_CANCELLATION_PLAN` | application setting | Omnitron cancellation reason ID, integer ≥ 1                                                                                     | undefined → the task runs but does nothing | A user with Application Settings permission |
| `OOS_ITEM_MAX_AGE_FOR_CANCELLATION_PLAN`           | application setting | Days, decimal ≥ 0                                                                                                                | `30`                                       | A user with Application Settings permission |
| `MAX_LOOKBACK_DAYS`                                | application setting | Days, integer ≥ 1 (shared with OOS transfer tasks)                                                                               | `15`                                       | A user with Application Settings permission |

**Activation steps:**

1. Determine the cancellation reason to use in Omnitron and enter its ID as `CANCELLATION_REASON_ID_FOR_OOS_CANCELLATION_PLAN`.
2. If needed, set `OOS_ITEM_MAX_AGE_FOR_CANCELLATION_PLAN` to the period agreed with the partner.
3. An authorized user adds `CANCEL_OLD_OOS_PACKAGES=true` and, **without exception**, `CANCEL_OLD_OOS_PACKAGES_CRONTAB` (or `_SCHEDULE`) to the env via Console. Env settings are not updated by DevOps.
4. Restart Celery beat; the env is read only when beat starts.

Application settings are changed from the **Application Settings** screen in the OMS interface or via the `application_settings` API; permission depends on the `application-settings-v2` permission group in Omnitron (ApplicationSettings List POST / Update PUT). When a setting is saved, the cache is also updated immediately, and the change takes effect on the task's next run. Env variables, on the other hand, are updated by an authorized user via Console and take effect when Celery beat is restarted.

## <mark style="color:red;">OOS Item Max Age</mark>

`OOS_ITEM_MAX_AGE_FOR_CANCELLATION_PLAN` is the minimum number of **days** a package item must remain in the OOS state to be considered a cancellation candidate. The default is **30 days**; decimal values are allowed (e.g., `0.5` = 12 hours), and `0` targets all OOS items updated within the last `MAX_LOOKBACK_DAYS` days.

The age is calculated from the item's `modified_date` field. This field is not "the moment the item became OOS" but the moment the record was **last updated**; if another field of the item is updated while it is OOS, the counter resets.

The task only considers items within the following range (`MAX_LOOKBACK_DAYS` defaults to 15):

```
now − (max_age + MAX_LOOKBACK_DAYS)  ≤  modified_date  <  now − max_age
```

With the defaults, this means items last modified **between 30 and 45 days ago**. OOS items older than 45 days are **not cancelled** by this task.

## <mark style="color:red;">Which packages, when, and to which status</mark>

The target is the **package item** (PackageItem), not the package. Eligible items are cancelled in Omnitron; the final status in OMS is set when the cancellation plan created by Omnitron is processed.

| Step                   | What happens                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1. Trigger             | Celery beat runs the task at the `CANCEL_OLD_OOS_PACKAGES_CRONTAB` / `_SCHEDULE` time. The task is locked, so two copies never run at the same time.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| 2. Selection           | Package items with the status **Unavailable (500)**, **Defective Product (510)**, or **Out of Stock (520)** whose age falls within the range above are grouped by order.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| 3. Cancellation reason | If the item has a denial reason (`PackageDenialReason`), its Omnitron ID is used; otherwise, `CANCELLATION_REASON_ID_FOR_OOS_CANCELLATION_PLAN` is used.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| 4. Omnitron call       | For each order, a request containing only these items is sent to the Omnitron `cancel_order` endpoint (partial cancellation, `"forced_refund_amount": "0.0"`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| 5. Reflection in OMS   | Omnitron creates a cancellation plan; when OMS processes the plan, the order item becomes **Cancelled (100)** and the package item becomes **Cancelled (600)**. If all items in the package are cancelled, the package becomes **Packaging Canceled (900)**. If the package has items that are not cancelled, the package does not move to 900: the remaining items and the package are moved to the waiting-for-replanning status and replanned (at the same location if `CANCEL_RESUME_SAME_LOCATION` is enabled; otherwise, the order is planned from scratch). If the package was in the *stale waiting* state before the cancellation plan, it is not replanned and goes to the stale waiting flow instead. |

If the Omnitron call fails with an Omnitron-originated error (an HTTP error or a communication error), the error is logged, the cancellation request is written to the audit record, and the task continues with the next order; if the item is still within the range, it is retried on the next run. Any other unexpected error stops the task, and the remaining orders are not processed in that run.

Manual trigger: `POST /api/v1/oms/cancel_order/cancel_old_oos_packages/` with optional `max_age` and `reason_id` in the body runs the same job synchronously; it works even if the env is disabled. This endpoint has no permission mapping in `application_permissions_fe_be.json`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.akinon.com/technical-guides/oms/cancel-old-oos-packages.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
