> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usenash.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Order Validations

When creating a Nash order, Nash applies these validations to ensure it's valid.

### Address & Location Validation

* **Address Input Exclusivity**:
  * An error is raised if you provide both `pickup_address` and `pickup_place_id` (or the dropoff equivalents). You must use one or the other.
  * An error is raised if you provide address components (e.g., `pickup_address_street`) along with `pickup_address` or `pickup_place_id`.
* **Address Input Requirement**: If no store location ID is provided, it requires one of the following for both pickup and dropoff:
  1. A single-line `address` string.
  2. A `place_id`.
  3. A set of `address_components` (street, city, zip, etc.).
  * If none of these are present, a "required field" error is added for the address.
* **Store Location Logic**:
  * If a `pickup_store_location_id` or `pickup_external_store_location_id` is provided, it attempts to find the corresponding `StoreLocation` in the database.
  * **Existence Check**: It fails if the store location ID does not exist for that organization or if the store has been marked as `is_deleted`.
  * **Automatic Store Creation**: If an `external_store_location_id` is given but not found, it checks an organization preference (`automatically_create_store_locations`). If enabled, it attempts to create a new `StoreLocation` using the order's pickup details. If this fails, an error is logged.
  * **Default Field Population**: If a valid `pickup_store_location` is found, it automatically populates the order's pickup fields (name, phone, email, instructions) with the data from the store, unless those fields were already provided in the request.
* **Geocoding and Parsing**:
  * If a raw `pickup_address` or `dropoff_address` string is provided, it attempts to parse it and geocode it to get coordinates (latitude/longitude). It will raise an error if parsing fails (e.g., "Address not found").
  * It performs the same parsing and geocoding for `pickup_place_id` and `dropoff_place_id`.
* **Identical Location Check**:
  * It checks if the `pickup_place_id` and `dropoff_place_id` are the same. If so, it raises an error.
  * After parsing, it compares the final `pickup_address_components` and `dropoff_address_components`. If they are identical, it raises an error.
* **Cross-Country Check**: Fails if the parsed `pickup_address_country` and `dropoff_address_country` are not the same.
* **Distance Check**:
  * Calculates the straight-line distance between the pickup and dropoff coordinates.
  * It checks against an organization-specific `maximum_delivery_distance_miles` preference and fails if the distance exceeds it.

### Required & Conditional Fields

* **Core Required Fields**: Checks that a value is present for: `value_cents`, `pickup_phone_number`, `dropoff_phone_number`, `delivery_mode`.
* **Contact Name Requirement**:
  * Requires either `pickup_first_name` or `pickup_business_name` to be present.
  * Requires either `dropoff_first_name` or `dropoff_business_name` to be present.

### Data Type & Format Validation

* **Integer Fields**: Verifies that `value_cents`, `tip_amount_cents`, and `items_count` are valid integers.
* **Float/Decimal Fields**: Verifies that dimensional fields (`weight`, `height`, `width`, `depth`, `volume`) are valid decimal numbers and are greater than 0.
* **Order Value**: Checks that `value_cents` is greater than 0.
* **Item Count**: Checks that `items_count`, if provided, is at least 1.
* **Name Fields**: Checks that all name fields (`pickup_first_name`, etc.) are strings and do not exceed a maximum length (80 characters).
* **Phone Numbers**:
  * Uses a validation utility (`get_validated_phone_number`) to check if `pickup_phone_number` and `dropoff_phone_number` are valid phone numbers for the corresponding country.
  * If the number is invalid but the organization has a default backup phone number configured, it will use the backup number instead of failing.
* **Items JSON**: If the `items` field is provided, it iterates through the list and tries to instantiate an `Item` object from each entry to ensure the data structure is valid.
* **Order Metadata**:
  * It validates that the dictionary has no more than 15 key-value pairs and that all values are simple scalar types (string, int, float, bool).

### Enum & ID Validation

* **Delivery Mode**:
  * Ensures `delivery_mode` is one of the allowed values (`now` or `scheduled`).
  * If mode is `now`, it nullifies all datetime fields.
  * If mode is `scheduled`, it requires at least one of the datetime fields (`pickup_start_time`, etc.) to be set.
* **Currency**:
  * If a `currency` is provided, it ensures it's in the list of `SUPPORTED_CURRENCIES`.
  * If no currency is provided, it attempts to infer it from the `pickup_address_country`.
* **Requirements**: Ensures all provided `requirements` are in the list of `SUPPORTED_PACKAGE_REQUIREMENTS` (unless it's a `custom:` requirement).
* **Vehicle Size**: Ensures `minimum_vehicle_size` is in the list of `SUPPORTED_VEHICLES`.
* **Dispatch Strategy**: If `dispatch_strategy_id` is provided, it confirms that it exists, belongs to the organization, and is not deleted.
* **Delivery Window**: If `delivery_window_id` is provided, it checks if it's a valid, active window.
* **External ID Uniqueness**: If an `external_id` is given, it queries the database to ensure no other order within the same organization already uses that ID.

### Datetime Validation

* **Parsing**: Attempts to parse all provided datetime strings (`pickup_start_time`, `pickup_end_time`, `dropoff_start_time`, `dropoff_end_time`) into proper datetime objects. It can handle UTC or timezone-localized inputs based on an order flag. Fails if a string is not a valid date format.
* **Chronological Order**:
  * `pickup_start_time` must be earlier than `pickup_end_time`.
  * `dropoff_start_time` must be earlier than `dropoff_end_time`.
  * `pickup_start_time` must be earlier than `dropoff_end_time`.
  * `pickup_end_time` must be earlier than `dropoff_end_time`.
