Locations
A Location is a physical site the tenant operates from: a warehouse, a retail store, a dark store, a click-and-collect counter, a partner facility, a return center. In Carriyo's model, every place that participates in any operational flow is registered as a single Location record.
The interesting story isn't what a Location is, it's how many different things a single Location does. A warehouse can simultaneously be where pickers work, where stock is counted, where a customer drives for click-and-collect, the origin address on outbound shipments, and the destination on inter-warehouse transfers. Carriyo doesn't model these as separate entities. It models them as roles that a single Location plays, turned on or off independently per Location.
The five roles
Three of the roles are turned on by explicit boolean flags on
the Location record (fulfillment_location,
inventory_location, collection_location). The other two are
turned on implicitly: the Location plays the role whenever a
Shipment references it as a pickup or dropoff.
1. Fulfillment location
The warehouse / store / dark store where pickers and packers
work. When the fulfillment_location flag is on:
- The Location becomes eligible for assignment by allocation rules; a Fulfillment Order can target this Location.
- A default set of Fulfillment App settings is auto-provisioned (pick mode, picker assignment strategy, mispick handling, etc.).
- The Fulfillment App recognizes the Location as a workspace for its operators.
2. Inventory location
The Location where stock is tracked. When the
inventory_location flag is on, the inventory pipeline accepts
stock events targeting this Location and the platform keys stock
records by (tenant, product, location). Without the flag,
inventory events targeting the Location are rejected.
Note that a Location can be a fulfillment site without being an inventory site (e.g. a 3PL location where Carriyo doesn't track stock) or vice versa. The two roles are independent.
3. Collection location
The Location where click-and-collect customers pick up their
orders. When the collection_location flag is on:
- The Location becomes a valid
customer_collection_addresson an order, gating that orders can only nominate this Location for collection if the flag is set. - Checkout delivery options include this Location as a click-and-collect choice for shoppers in range.
4. Shipping pickup location
The origin address on a Shipment. When a Shipment's
pickup.partner_location_id references a Location, the platform
hydrates the pickup with the Location's address, contact, geo
coordinates, custom fields, registration numbers, and location type
at booking time. This is the dominant use of Locations: every
forward shipment has a pickup, and the pickup is almost always a
Location.
Carriers refuse to book against a Location that's been deactivated,
so the platform also checks that the Location is ACTIVE before
hydration.
5. Delivery dropoff location
The destination address on a Shipment, when the destination
is itself a Location rather than a customer address. This is how
inter-warehouse transfers, store replenishments, and central-DC
→ forward-warehouse moves are modeled. A Shipment's
dropoff.partner_location_id references a Location, and the
same enhancement process that runs on pickup runs on the
destination.
What a Location carries
Beyond the role flags, the Location record holds:
- Identity.
location_code(operational shorthand likeDXB-WH-01) andlocation_name. - Address. Full structured address (street, building, floor,
flat, area, city, state, postcode, country) plus a
coordsfield for the geo point. Apo_boxfield is supported for countries that use them. - Contact. Primary and alternate phone, contact name, contact email, company name. Used for ops handoff and as the "from" address on carrier paperwork.
- Classification.
type(BUSINESSorRESIDENTIAL) andlocation_type(WAREHOUSEorSTORE). Carriers use these signals when computing pickup logistics. - Operating schedule. Working days, daily working windows,
blackout dates, and a
schedule_bymode (apply globally or per weekday). Feeds delivery-promise computation and pickup-window scheduling. - Fulfillment zones. Country / state combinations this Location is allowed to fulfill. Used by allocation when matching shipments to Locations.
- Address codes. Country-specific structured identifiers (e.g. Saudi Arabia's national address short code).
- Registration numbers. VAT, customs, tax, business-licence numbers that need to print on shipping labels and customs paperwork.
- Custom fields. Tenant-defined extensibility map. The same custom-attribute system that applies to other first-class entities.
Scoping and status
Locations are tenant-scoped at the storage layer (no Location
crosses tenant boundaries) and merchant-assignable at the access
layer. The merchants list controls which merchants on a
multi-merchant tenant can use this Location:
- Empty list. Location is available to every merchant in the tenant.
- Populated list. Location is restricted to the named merchants.
Status is one of ACTIVE (default), INACTIVE (temporarily
disabled; the shipment enhancer refuses non-active Locations),
or DELETED (soft-deleted). Deletion is blocked if the Location
is still referenced by tenant routing rules or carrier
configuration. The platform refuses to orphan dependent records.
Lifecycle
Locations are created and updated via the Locations API or the
Dashboard's Locations setup screen. Bulk import is supported for
tenants migrating from another platform: POST /api/locations/bulk/import
accepts a list capped by the tenant's bulk-import limit.
Once a Location is referenced by orders, shipments, or
inventory, it shouldn't be deleted. Flip it to INACTIVE
instead. This preserves historical references while keeping the
Location out of new operational flows.
How locations fit with other modules
- Orders → allocation engine.
Allocation reads from a Location's fulfillment role and the
fulfillment_zoneslist to decide which Location handles a line. - Inventory. Stock is keyed per Location; the inventory role gates which Locations are valid.
- Shipping. Pickup and dropoff resolve through Locations.
- Click and collect. Collection points are Locations with the collection role on.
- Fulfillment App. Runs in single-Location context; the operator is scoped to one Location at a time.
- Account model. Locations are tenant-scoped and merchant-assignable.