Skip to content

Phase 01: Master Data

Duration: 1 week Goal: Implement core master data DocTypes for Legacy ERP operations


class Item(BaseDocType):
"""Product/SKU managed by Legacy ERP."""
# Identity
item_code: str = Field(max_length=50, unique=True)
item_name: str = Field(max_length=200)
description: str | None = None
# Classification
item_group: str # FK to ItemGroup
brand: str | None = None
manufacturer: str | None = None
# Stock Settings
stock_uom: str = "Nos" # Unit of Measure
is_stock_item: bool = True
has_batch_no: bool = False
has_serial_no: bool = False
# Pricing
standard_rate: Decimal = Decimal("0")
mrp: Decimal = Decimal("0")
legacy_erp_price: Decimal = Decimal("0") # Discounted price
# Status
is_active: bool = True
class Meta:
table_name = "item"
indexes = ["item_code", "item_group"]
class ItemGroup(BaseDocType):
"""Hierarchical product categorization."""
name: str = Field(max_length=100)
parent_group: str | None = None # Self-referential
is_group: bool = False
class Meta:
table_name = "item_group"
  • Create Item DocType
  • Create ItemGroup DocType
  • CRUD API tests
  • Bulk import endpoint for 10K SKUs
  • Item search with filters

class Depot(BaseDocType):
"""Legacy ERP Area Depot (34 across India)."""
depot_code: str = Field(max_length=20, unique=True)
depot_name: str = Field(max_length=200)
# Location
region: str # FK to Region
address: str | None = None
city: str | None = None
state: str | None = None
pincode: str | None = None
# Contact
depot_manager: str | None = None
phone: str | None = None
email: str | None = None
# Status
is_active: bool = True
class Meta:
table_name = "depot"
class Region(BaseDocType):
"""Regional Office (5 regions)."""
region_code: str = Field(max_length=10, unique=True)
region_name: str = Field(max_length=100)
regional_manager: str | None = None
class Meta:
table_name = "region"
class Warehouse(BaseDocType):
"""Storage location within a Depot."""
warehouse_code: str = Field(max_length=50, unique=True)
warehouse_name: str = Field(max_length=200)
depot: str # FK to Depot
# Type
warehouse_type: str = "Stores" # Stores, Damaged, Transit
# Capacity
total_capacity: int | None = None
current_utilization: int | None = None
is_active: bool = True
class Meta:
table_name = "warehouse"
  • Create Region DocType
  • Create Depot DocType
  • Create Warehouse DocType
  • Seed 5 regions, 34 depots
  • Depot → Warehouse hierarchy API

class URC(BaseDocType):
"""Unit Run Canteen - Retail outlet."""
urc_code: str = Field(max_length=50, unique=True)
urc_name: str = Field(max_length=200)
# Affiliation
depot: str # Primary Depot
secondary_depot: str | None = None # Dual dependency
unit_name: str | None = None # Military unit
# Location
address: str | None = None
city: str | None = None
state: str | None = None
# Contact
officer_in_charge: str | None = None
phone: str | None = None
# Status
status: str = "Active" # Active, Suspended, Terminated
registration_date: date | None = None
class Meta:
table_name = "urc"
indexes = ["depot", "status"]
  • Create URC DocType
  • URC registration workflow
  • URC status management (suspend/terminate)
  • Bulk URC import for 3,630 records

class Supplier(BaseDocType):
"""Vendor/Supplier providing goods to Legacy ERP."""
supplier_code: str = Field(max_length=50, unique=True)
supplier_name: str = Field(max_length=200)
# Business Info
supplier_type: str = "Company" # Company, Individual
gstin: str | None = None
pan: str | None = None
# Contact
contact_person: str | None = None
phone: str | None = None
email: str | None = None
address: str | None = None
# Banking
bank_name: str | None = None
bank_account: str | None = None
ifsc_code: str | None = None
# Status
status: str = "Active" # Active, Blacklisted, Inactive
class Meta:
table_name = "supplier"
class ItemSupplier(BaseDocType):
"""Many-to-many: Which suppliers provide which items."""
item: str # FK to Item
supplier: str # FK to Supplier
supplier_part_no: str | None = None
price: Decimal = Decimal("0")
lead_time_days: int = 7
is_default: bool = False
class Meta:
table_name = "item_supplier"
unique_together = [("item", "supplier")]
  • Create Supplier DocType
  • Create ItemSupplier link DocType
  • Supplier onboarding API
  • Bulk supplier import for 700 records

class Member(BaseDocType):
"""Legacy ERP Beneficiary (Ex-serviceman, Defence civilian, etc.)."""
member_id: str = Field(max_length=50, unique=True) # Legacy ERP Card number
# Identity
full_name: str = Field(max_length=200)
category: str # Serving, Retired, Widow, Defence Civilian
rank: str | None = None
service: str | None = None # Army, Navy, Air Force
# Contact
phone: str | None = None
email: str | None = None
address: str | None = None
# Affiliation
primary_urc: str | None = None # FK to URC
# Wallet (Book-Keeper reference)
wallet_account_id: str | None = None # Book-Keeper account code
# Status
is_active: bool = True
card_expiry: date | None = None
class Meta:
table_name = "member"
indexes = ["category", "primary_urc"]
  • Create Member DocType
  • Member registration API
  • Book-Keeper wallet account creation on registration
  • Member search by card number

  • All 8 DocTypes created and migrated
  • CRUD APIs working for all DocTypes
  • Seed data loaded (regions, depots, sample items)
  • Foreign key relationships working
  • Search/filter endpoints functional
  • Unit tests passing

Endpoint Method Description
/api/v1/item GET, POST List/Create items
/api/v1/item/{id} GET, PUT, DELETE Item CRUD
/api/v1/depot GET, POST List/Create depots
/api/v1/urc GET, POST List/Create URCs
/api/v1/supplier GET, POST List/Create suppliers
/api/v1/member GET, POST List/Create members