انتقل إلى المحتوى الرئيسي

Locations Domain

Overview

The Locations domain manages the hierarchical structure of warehouse facilities, storage areas, and inventory locations within the organization. It provides a flexible, multi-level location hierarchy that supports various warehouse management scenarios from simple single-warehouse operations to complex multi-facility, multi-zone warehouse networks.

Core Concepts

Hierarchical Location Structure

The Locations domain implements a parent-child hierarchy that mirrors real-world warehouse organization:

Main Warehouse
├── Receiving Zone
│ ├── Dock 1
│ └── Dock 2
├── Storage Zone A
│ ├── Aisle A1
│ │ ├── Shelf A1-1
│ │ └── Shelf A1-2
│ └── Aisle A2
└── Shipping Zone
├── Staging Area 1
└── Staging Area 2

Location Classification

Locations are classified using two independent dimensions:

  1. Location Type: Physical characteristics and structure

    • Warehouse
    • Zone
    • Aisle
    • Shelf/Bin
    • Storage Unit
    • Dock
    • Yard
  2. Location Purpose: Functional role in operations

    • General Storage
    • Receiving
    • Shipping
    • Quarantine
    • Returns
    • Production
    • Scrap/Damaged

This dual-classification system allows flexible organization while maintaining clear operational purpose.

Operational Status

Each location has an operational status that controls its availability:

  • Operational: Location is active and can be used for inventory transactions
  • Non-Operational: Location is inactive (maintenance, closed, etc.)

Non-operational locations:

  • Cannot receive new inventory
  • Cannot be used as transaction destinations
  • Retain existing inventory (read-only)
  • Can be reactivated when needed

Domain Structure

Aggregates

locations/
├── aggregates/
│ └── location.aggregate.md # Core Location aggregate documentation

Entities

locations/
└── entities/
└── location.md # Location entity (aggregate root)

Lookup Entities

locations/
└── lookup-entities/
├── location-type.md # Location type classifications
└── location-purpose.md # Location purpose definitions

Value Objects

locations/
└── value-objects/
└── address.md # Physical address value object

Domain Services

locations/
└── services/
└── location-hierarchy-service.md # Hierarchy validation and management

Key Aggregates

Location

Aggregate Root: Location

Purpose: Represents a physical or logical storage location within the warehouse hierarchy.

Key Characteristics:

  • Supports unlimited hierarchy depth
  • Dual classification (Type + Purpose)
  • Optional physical address
  • Operational status control
  • Parent-child relationship management

Relationships:

  • Has one LocationType (required)
  • Has one LocationPurpose (required)
  • Has one parent Location (optional)
  • Has many child Location instances (0 to many)
  • Has one Address value object (optional)

Core Operations:

  • Create location with type and purpose
  • Update location information
  • Set operational status
  • Manage parent-child relationships
  • Calculate full hierarchical path

Business Rules

Location Creation Rules

  1. Code Required: Location code must be unique and not empty
  2. Name Required: Location name cannot be empty
  3. Type Required: Every location must have a LocationType
  4. Purpose Required: Every location must have a LocationPurpose
  5. Code Normalization: Location codes are automatically uppercased
  6. Parent Optional: Locations can be created without parent (root locations)

Hierarchy Rules

  1. No Circular References: Location cannot be its own ancestor
  2. Operational Parent Requirement: Child locations can only be added to operational parent locations
  3. Single Parent: Each location has at most one parent
  4. Unlimited Depth: No artificial limit on hierarchy depth
  5. Hierarchy Validation: LocationHierarchyService validates complex hierarchy operations

Update Rules

  1. Immutable Code: Location code cannot be changed after creation
  2. Name Updates: Location name can be updated freely
  3. Purpose Changes: Location purpose can be changed at any time
  4. Type Immutability: Location type cannot be changed (create new location instead)
  5. Address Updates: Physical address can be added, updated, or removed

Operational Status Rules

  1. Status Transitions: Locations can be set operational or non-operational
  2. Child Impact: Making parent non-operational doesn't affect children (they can remain operational)
  3. Transaction Validation: Inventory transactions validate location is operational
  4. Inventory Retention: Non-operational locations retain existing inventory (read-only)

Integration Points

With Transaction Module

  • Location Validation: Transactions validate source/destination locations are operational
  • Movement Operations: Stock movements require valid source and destination locations
  • Adjustment Operations: Stock adjustments require valid location
  • Assembly Operations: Assembly transactions require valid production location
  • Location Tracking: Transactions create location-based inventory records

With Inventory Module

  • Location-Based Tracking: Inventory records maintain per-location quantities
  • Stock Queries: Inventory lookups filter by location and hierarchy
  • Available Stock: Location hierarchy supports roll-up inventory queries
  • Location Transfers: Inventory updates track location movements

With Item Module

  • TrackByLocation Setting: Item StockableBehavior determines location requirement
  • Location Validation: Items with TrackByLocation=true require location specification
  • Simplified Tracking: Items with TrackByLocation=false use default location

Common Patterns

Creating Root Location (Warehouse)

// Create main warehouse (no parent)
var warehouse = Location.Create(
code: "WH-MAIN",
name: "Main Distribution Center",
locationType: warehouseType,
locationPurpose: generalStoragePurpose,
description: "Primary distribution facility - North Region",
parentLocation: null, // Root location
physicalAddress: new Address(
street: "123 Industrial Parkway",
city: "Springfield",
state: "IL",
postalCode: "62701",
country: "USA"));

await locationRepository.AddAsync(warehouse);
await unitOfWork.CommitAsync();

Creating Child Location with Hierarchy

// 1. Load parent location
var warehouse = await locationRepository.GetByCodeAsync("WH-MAIN");

// 2. Create child zone with hierarchy validation
var receivingZone = Location.Create(
code: "RCV-ZONE-A",
name: "Receiving Zone A",
locationType: zoneType,
locationPurpose: receivingPurpose,
description: "Primary receiving area for inbound shipments",
parentLocation: warehouse,
hierarchyService: locationHierarchyService); // Validates hierarchy

// 3. Parent automatically includes child in collection
await unitOfWork.CommitAsync();

// At this point:
// - Parent: WH-MAIN
// - Child: RCV-ZONE-A
// - Hierarchy: WH-MAIN / RCV-ZONE-A

Building Multi-Level Hierarchy

// Level 1: Warehouse (root)
var warehouse = Location.Create("WH-01", "Main Warehouse", warehouseType, generalPurpose);

// Level 2: Zone
var storageZone = Location.Create("ZONE-A", "Storage Zone A", zoneType, generalPurpose,
parentLocation: warehouse);

// Level 3: Aisle
var aisle = Location.Create("AISLE-A1", "Aisle A1", aisleType, generalPurpose,
parentLocation: storageZone);

// Level 4: Shelf
var shelf = Location.Create("SHELF-A1-1", "Shelf A1-1", shelfType, generalPurpose,
parentLocation: aisle);

// Result hierarchy: WH-01 / ZONE-A / AISLE-A1 / SHELF-A1-1

Location Status Management

// Make location non-operational (e.g., for maintenance)
var location = await locationRepository.GetByCodeAsync("AISLE-A1");

location.SetNonOperational();
await unitOfWork.CommitAsync();

// Location is now unavailable for new transactions
// Existing inventory remains (read-only access)

// Later, reactivate location
location.SetOperational();
await unitOfWork.CommitAsync();

Getting Full Hierarchical Path

var shelf = await locationRepository.GetByCodeAsync("SHELF-A1-1");

// Get display path
string fullPath = shelf.GetFullPath();
// Result: "Main Warehouse / Storage Zone A / Aisle A1 / Shelf A1-1"

// Useful for:
// - UI breadcrumbs
// - Transaction displays
// - Reports
// - Pick lists

Repository Pattern

ILocationRepository

Query Methods:

  • GetByIdAsync(Guid id): Get location with all related data
  • GetAllAsync(): Get all operational locations
  • GetByCodeAsync(string code): Find location by unique code
  • GetRootLocationsAsync(): Get top-level locations (no parent)
  • GetChildrenAsync(Guid parentId): Get immediate children of a location
  • GetDescendantsAsync(Guid parentId): Get all descendants (recursive)

Specialized Query Methods:

  • GetByTypeAsync(int locationTypeId): Find locations by type
  • GetByPurposeAsync(int locationPurposeId): Find locations by purpose
  • GetOperationalLocationsAsync(): Get only operational locations
  • GetNonOperationalLocationsAsync(): Get only non-operational locations

Hierarchy Methods:

  • GetAncestorsAsync(Guid locationId): Get all parent locations up to root
  • GetPathAsync(Guid locationId): Get full path from root to location
  • GetSubtreeAsync(Guid rootId): Get location and all descendants

Validation Methods:

  • ExistsByCodeAsync(string code): Check if location code exists
  • IsCodeUniqueAsync(string code, Guid? excludeId): Validate for updates
  • HasChildrenAsync(Guid locationId): Check if location has children

Command Methods:

  • AddAsync(Location location): Create new location
  • Update(Location location): Update existing location
  • Archive(Location location): Soft delete location
  • UnArchive(Location location): Restore archived location

Domain Services

LocationHierarchyService

Purpose: Validates complex hierarchy operations and prevents invalid location structures.

Key Methods:

Hierarchy Validation:

void ValidateParentAssignment(Location parent, Location child)
  • Prevents circular references
  • Validates parent is operational
  • Ensures no ancestor loops

Hierarchy Queries:

Task<IEnumerable<Location>> GetAllAncestorsAsync(Location location)
Task<IEnumerable<Location>> GetAllDescendantsAsync(Location location)
Task<int> GetHierarchyDepthAsync(Location location)
Task<bool> IsAncestorOfAsync(Location potential Ancestor, Location descendant)

Business Logic:

  • Circular reference prevention
  • Depth calculations
  • Ancestor validation
  • Subtree operations

Testing Strategy

Unit Tests

  • Factory Method Tests: Location creation with various combinations
  • Hierarchy Tests: Parent-child relationship management
  • Validation Tests: Business rule enforcement
  • Status Tests: Operational status transitions
  • Path Tests: Full path calculation

Integration Tests

  • Repository Tests: Database operations and query correctness
  • Hierarchy Persistence: Multi-level hierarchies correctly saved/loaded
  • Lookup Integration: LocationType and LocationPurpose relationships
  • Address Persistence: Value object correctly stored
  • Circular Reference Tests: Database constraints prevent invalid hierarchies

Domain Service Tests

  • Hierarchy Validation: Service correctly validates hierarchy operations
  • Ancestor Queries: Correctly retrieves all ancestors
  • Descendant Queries: Correctly retrieves all descendants
  • Circular Detection: Prevents circular parent references

Future Enhancements

Planned Features

  1. Location Capacity: Track capacity limits (volume, weight, pallet count)
  2. Location Dimensions: Physical dimensions (length, width, height)
  3. Location Attributes: Flexible attribute system (temperature controlled, hazmat, etc.)
  4. Pick Path Optimization: Define optimal picking sequences within locations
  5. Zone Management: Enhanced zone-level operations and reporting
  6. Location Reservations: Reserve locations for specific orders or operations

Extensibility Points

  1. Additional Location Types: System can accommodate new location types via lookup tables

  2. Custom Purposes: New location purposes can be added without code changes

  3. Integration Events: Publish events for cross-module integration

    • LocationCreated
    • LocationStatusChanged
    • LocationHierarchyModified
  4. Warehouse Management Integration: Foundation for advanced WMS features

    • Directed putaway
    • Wave picking
    • Cross-docking
    • Slotting optimization

Domain Documentation

API Documentation

Concept Documentation

Architecture Documentation


Last Updated: 2025-10-24 | Status: Active Development | Version: 1.0