# Configuration-Based Behavior

The Basket API behavior can be customized through various system settings. Below is a comprehensive list of all settings with their configuration methods:

#### Settings Configuration Methods

**Dynamic Settings (Configurable via Omnitron / Sales Channel Settings / Dynamic Settings):**

* `BASKET_MAX_ITEM_COUNT` - Can also be set via ENV or directly in settings.py
* `BASKET_ITEM_ATTRIBUTES_MAX_LENGTH_KB` - Dynamic setting only
* `IS_SUB_BASKET_ITEM_QUANTITY_SAME_AS_PARENT` - Can also be set via ENV or directly in settings.py
* `BASKET_VALIDATORS` - Can also be set via ENV or directly in settings.py
* `BASKET_ITEM_REMOTE_PRICE_CLIENT_CONF` - Dynamic setting only
* `BASKET_SERVICE_CONDITIONS` - Can also be set via ENV or directly in settings.py
* `BASKET_PRODUCT_MAX_QUANTITY_ATTRIBUTE` - Can also be set via ENV or directly in settings.py
* `BASKET_PRODUCT_USER_MAX_QUANTITY_ATTRIBUTE` - Can also be set via ENV or directly in settings.py
* `BASKET_NAMESPACE_VALIDATORS` - Can also be set via ENV or directly in settings.py
* `RESET_BASKET_ON_SEGMENT_CHANGE` - Can also be set via ENV or directly in settings.py
* `IS_MARKETPLACE` - Can also be set via ENV or directly in settings.py
* `OFFER_MISCELLANEOUS_ATTRIBUTE_KEY` - Can also be set via ENV or directly in settings.py
* `REMOTE_PRICE_ATTRIBUTE_KEY` - Can also be set via ENV or directly in settings.py

**Weight-Based Product Sales Settings:** These settings can also be configured via environment variables:

* `BASKET_UNIT_VALUE_ATTRIBUTE` - ENV: `BASKET_UNIT_VALUE_ATTRIBUTE` (default: 'basket\_unit\_value')
* `UNIT_STEP_VALUE_ATTRIBUTE` - ENV: `UNIT_STEP_VALUE_ATTRIBUTE` (default: 'unit\_step\_value')
* `UNIT_REFERENCE_VALUE_ATTRIBUTE` - ENV: `UNIT_REFERENCE_VALUE_ATTRIBUTE` (default: 'unit\_reference\_value')
* `UNIT_PRODUCT_FLAG_ATTRIBUTE` - ENV: `UNIT_PRODUCT_FLAG_ATTRIBUTE` (default: 'is\_unit\_product')
* `UNIT_MINIMUM_VALUE_ATTRIBUTE` - ENV: `UNIT_MINIMUM_VALUE_ATTRIBUTE` (default: 'unit\_minimum\_value')
* [Detailed Documentation about Weight Based Product Sales](https://docs.akinon.com/technical-guides/commerce/weight-based-product-sales)

#### Core Settings

**`IS_MARKETPLACE`** (boolean, default: false):

* When enabled, datasource field becomes required for all basket operations
* Products must be associated with a specific seller/datasource
* Extra product pricing and stock information is included in responses
* Enables multi-seller marketplace functionality

**`BASKET_ITEM_ATTRIBUTES_MAX_LENGTH_KB`** (integer, default: 0):

* Controls maximum size of custom attributes per basket item in kilobytes
* Default 0 means no limit, typical value is 10KB
* Prevents oversized data in gift notes, form fields, etc.
* Returns validation error if limit exceeded

**`OFFER_MISCELLANEOUS_ATTRIBUTE_KEY`** (string, default: "cannot\_be\_sold\_alone"):

* Determines which offer products can be added as miscellaneous sub-items
* Controls validation of sub-items in basket operations
* Used to identify promotional miscellaneous products

#### Basket Quantity Limits

**`BASKET_MAX_ITEM_COUNT`** (integer, default: 80):

* Total quantity limit of all items in the cart
* Prevents baskets from becoming too large
* Checked when adding/updating items

**`BASKET_PRODUCT_MAX_QUANTITY_ATTRIBUTE`** (string, default: ""):

* Product attribute key that defines maximum quantity per product
* Applied globally across all users
* Example: Product with `max_quantity: 10` attribute cannot exceed 10 units in basket

**`BASKET_PRODUCT_USER_MAX_QUANTITY_ATTRIBUTE`** (string, default: ""):

* Product attribute key for maximum quantity per user within time window
* Combined with `BASKET_PRODUCT_USER_MAX_QUANTITY_GAP_HOUR` (default: 24h)
* Includes both basket and recent orders in calculation
* Prevents single user from purchasing excessive quantities

#### Sub-Item Behavior

**`IS_SUB_BASKET_ITEM_QUANTITY_SAME_AS_PARENT`** (boolean, default: false):

* When true, sub-product quantities automatically match parent product quantity
* Affects extra products and miscellaneous items
* When false, sub-items maintain independent quantities

#### Basket Validators

**`BASKET_VALIDATORS`** (list of validator configurations, default: \[]):

* Custom validation rules applied to basket before checkout
* Each validator has: `condition_klass`, `kwargs`, `message` (multi-language)
* Available validators:
  * `BasketItemQuantityValidator`: Validates quantity based on product attributes
  * `BasketItemBaseCodeQuantityValidator`: Validates quantity by product base code based on product attributes
  * `BasketItemSteppedQuantityValidator`: Enforces quantity steps (e.g., multiples of 6)
  * `AttributeValidator`: Validates product attribute values
  * `SingleDataSourceValidator`: Ensures all items from same seller (marketplace)
* Errors returned during checkout validation

#### Service Conditions

**`BASKET_SERVICE_CONDITIONS`** (list of condition paths, default: \[]):

* Conditions checked when basket items are added/modified (runtime validation)
* Applied during POST/PUT operations, not during checkout
* Available conditions with detailed configuration examples:

**1. basket\_user\_max\_quantity**

* **Purpose**: Enforces per-user quantity limits over configurable time periods
* **Module**: `omnishop.baskets.conditions.basket_user_max_quantity`
* **Parameters**: Requires product attributes:
  * `max_user_quantity`: Maximum quantity user can order
    * Attribute name need to be set via `BASKET_PRODUCT_USER_MAX_QUANTITY_ATTRIBUTE`
* **Use Case**: Limit purchases per user to prevent abuse/scalping
* **Configuration Example**:

  ```python
  BASKET_SERVICE_CONDITIONS = [
      "omnishop.baskets.conditions.basket_user_max_quantity"
  ]
  ```
* **Product Attributes Example**:

  ```json
  {
    "max_user_quantity": 2
  }
  ```
* **Behavior**:
  * Queries user's order history for last N days
    * N is configurable via `BASKET_PRODUCT_USER_MAX_QUANTITY_GAP_HOUR` (default: 24 hours)
  * Sums quantities of same product
  * Rejects if adding current quantity exceeds limit
  * Example: User can only buy 2 units in 30 days

**2. basket\_item\_max\_count**

* **Purpose**: Enforces maximum total item count in basket
* **Module**: `omnishop.baskets.conditions.basket_item_max_count`
* **Use Case**: Simplify order processing, limit basket items
* **Configuration Example**:

  ```python
  BASKET_SERVICE_CONDITIONS = [
      "omnishop.baskets.conditions.basket_item_max_count"
  ]
  ```
* **Behavior**:
  * Counts basket items in quantity
  * Compares against `BASKET_MAX_ITEM_COUNT` setting
  * Prevents adding new item if count exceeds max item count setting
  * Error: "Maximum of {max item count} items can be added to the cart."

**3. bundle\_type\_compatibility\_condition**

* **Purpose**: Validates bundle type compatibility between products
* **Module**: `omnishop.baskets.conditions.bundle_type_compatibility_condition`
* **Parameters**: Requires `BUNDLE_TYPE_CONFIGURATION` static setting (configured in settings.py)
* **Use Case**: Prevent incompatible product bundles (e.g., subscription + one-time)
* **Configuration Example**:

  ```python
  BASKET_SERVICE_CONDITIONS = [
      "omnishop.baskets.conditions.bundle_type_compatibility_condition"
  ]

  BUNDLE_TYPE_CONFIGURATION = {
      "INCOMPATIBLE_BUNDLE_TYPES": (
          ("subscription", "one_time_purchase"),
          ("recurring_payment", "prepaid")
      ),
      "ATTRIBUTE_NAME": "bundle_type"
  }
  ```
* **Product Attributes Example**:

  ```json
  {
    "bundle_type": "subscription"
  }
  ```
* **Behavior**:
  * Reads `bundle_type` attribute from products
  * Checks against `INCOMPATIBLE_BUNDLE_TYPES` configuration
  * Prevents adding product if bundle type conflicts with existing items
  * Error: "This product cannot be purchased with the other products in the basket. If you add this product to the basket, other product(s) will be removed."
  * Example: Cannot mix "subscription" and "one\_time\_purchase" products

**4. extra\_product\_quantity\_condition**

* **Purpose**: Prevents quantity changes for basket items that have extra products/sub-items attached
* **Module**: `omnishop.baskets.conditions.extra_product_quantity_condition`
* **Parameters**: None (automatic detection of items with sub-items)
* **Use Case**: Protect parent-child relationships (warranties, gift wrapping, accessories, etc.)
* **Configuration Example**:

  ```python
  BASKET_SERVICE_CONDITIONS = [
      "omnishop.baskets.conditions.extra_product_quantity_condition"
  ]
  ```
* **Behavior**:
  * Detects if basket item has sub-items (extra products) attached to it
  * Prevents direct quantity modification of the parent item when sub-items exist
  * User must remove sub-items first, then modify parent quantity
  * Error: "The orders related to miscellaneous product do not accept changing quantity"
* **Example**:
  * User adds Laptop (qty: 1)
  * User adds Extended Warranty as extra product (attached to laptop as sub-item)
  * User tries to change Laptop quantity from 1 to 2 → **BLOCKED**
  * User must first remove the warranty, then change laptop quantity, then re-add warranty if desired

#### Namespace Settings (for multi-basket)

**`BASKET_NAMESPACE_VALIDATORS`** (list of validator configurations, default: see below):

* Validators for namespace-based basket operations
* Default validators:
  * `NullNamespaceValidator`: Prevents namespace from being None
  * `ActiveBasketCountValidator`: Limits number of active baskets (default: 5)
  * `NamespaceDataSourceValidator`: Validates namespace matches datasource
  * `DefaultNamespaceValidator`: Prevents namespace string "null"
* Each validator can have custom `kwargs` for configuration

**`RESET_BASKET_ON_SEGMENT_CHANGE`** (boolean, default: true):

* When true, basket is cleared when user segment changes
* Segment changes affect pricing/stock lists
* Prevents price inconsistencies across segments

#### Remote Pricing

**`BASKET_ITEM_REMOTE_PRICE_CLIENT_CONF`** (dict, default: {"headers": {"Authorization": "Bearer test\_token"}, "url": "<http://localhost:8000/"}>):

* Configuration for remote price calculation service
* Contains `url` and `headers` for remote API
* Used when pricing comes from external systems
* [Detailed Documentation about Remote Price](https://docs.akinon.com/technical-guides/commerce/remote-price)


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apidocs.akinon.com/commerce-openapis/basket/introduction/configuration-based-behavior.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
