Supply List Guide

The supply list system imports 659 items across 17 categories from the static JS supply catalog into the operational budget pipeline.

Overview

The static supply list (/supply-list/) provides a standalone JavaScript tool for browsing and costing supplies. The Django supplies app mirrors that data into the database so it can participate in the ShowcaseBudgetLine system alongside BOM (Bill of Materials) entries.

Pipeline: JS data filesseed_supply_itemsSupplyCategory/SupplyItemPropertySupplyPlanSupplyCalculationServiceShowcaseBudgetLine

Supply budget lines appear with a [Supply] prefix to distinguish them from [BOM] lines.

Key Concepts

17 Categories

# Category Items Budget Category
0 Medical & First Aid ~51 EQUIPMENT
1 Food Storage & Preservation ~52 FOOD
2 Agriculture & Permaculture ~47 FOOD
3 IT & Communications ~37 EQUIPMENT
4 Housing & Construction ~47 INFRASTRUCTURE
5 Cooking & Kitchen ~30 EQUIPMENT
6 Tools & Workshop ~48 EQUIPMENT
7 Nutrition & Supplements ~23 FOOD
8 Machinery & Vehicles ~22 EQUIPMENT
9 Utilities & Energy ~34 INFRASTRUCTURE
10 Security & Safety ~51 EQUIPMENT
11 Education & Training ~33 EQUIPMENT
12 Textiles & Clothing ~47 EQUIPMENT
13 Sanitation & Hygiene ~42 INFRASTRUCTURE
14 Livestock & Animal Husbandry ~55 FOOD
15 Nuclear Preparedness ~27 EQUIPMENT
16 Tasmania Disaster Prep ~13 EQUIPMENT

5 Importance Levels

Items are assigned one of five importance levels, ordered from most to least critical:

Level Description
necessary Required for basic survival and safety
important Significantly improves capability or resilience
useful Worthwhile for a well-prepared community
optional Nice to have, not critical
possible Speculative or situational items

PropertySupplyPlan uses an importance threshold — selecting "useful" includes all items at necessary, important, and useful levels.

5 Scaling Types

Quantity scaling matches the JS calcQuantity function. The base value acts as a minimum floor, not an additive constant.

Type Formula (pop = population) Example at pop=100
fixed base base=2 → 2
per_person max(base, ceil(pop * multiplier)) base=1, mult=0.5 → 50
per_household max(base, ceil(ceil(pop/4) * multiplier)) base=1, mult=1 → 25
per_n_people max(base, ceil(pop / n)) base=1, n=25 → 4
per_hectare max(base, ceil(ceil(pop/10) * multiplier)) base=1, mult=2 → 20

The per_hectare type estimates land from population at 10 people per hectare as a default.

4 Cost Tiers

Each item can have up to four cost estimates:

Tier Field Description
expected cost_expected Most likely per-unit cost (AUD)
upper95 cost_upper95 95th percentile upper bound
lower_new cost_lower_new Lowest new-purchase price
lower_secondhand cost_lower_secondhand Lowest secondhand price

PropertySupplyPlan selects one tier for the entire plan. Falls back to expected if the chosen tier is null for a given item.

13 Scenario Tags

Items are tagged with scenario contexts. A PropertySupplyPlan can filter to items matching specific tags (empty = include all):

Tag Description
general_resilience Core resilience items
grid_failure Power grid disruption
supply_chain Supply chain breakdown
drought Extended drought
flooding Flood events
bushfire Bushfire scenarios
storms Severe storm events
pandemic Disease outbreak
nuclear_winter Nuclear winter scenario
nuclear Nuclear incident proximity
fallout Radioactive fallout
emp Electromagnetic pulse
uv_increase Increased UV radiation

Scaling Logic

The base-as-floor semantics are important: base is the minimum quantity, not added to the scaled result.

# per_person example with base=3, multiplier=0.2
pop=5  → max(3, ceil(5 * 0.2))  = max(3, 1) = 3  (floor wins)
pop=20 → max(3, ceil(20 * 0.2)) = max(3, 4) = 4  (scaling wins)
pop=100 → max(3, ceil(100 * 0.2)) = max(3, 20) = 20

This means small communities get at least base of each item, while larger communities scale up. The crossover point depends on the item's multiplier.

Using the System

Admin Interface

  1. Browse items: Admin > Supply Items — filter by category, importance, scaling type
  2. Create a plan: Admin > Property Supply Plans — select showcase + operational plan, set cost tier and importance threshold
  3. Recalculate: Select plans and use "Recalculate supply plan costs" action
  4. Overrides: Within a plan, add inline PropertySupplyItemOverride records to exclude items, adjust costs, set installation years

Shell Commands

# Preview costs for a plan
python manage.py shell -c "
from backend.supplies.models import PropertySupplyPlan
from backend.supplies.services import SupplyCalculationService
plan = PropertySupplyPlan.objects.first()
result = SupplyCalculationService().calculate_plan_cost(plan)
print(f'Items: {result[\"item_count\"]}, Total: \${result[\"total_cost\"]:,.2f}')
for cat, cost in sorted(result['by_category'].items()):
    print(f'  {cat}: \${cost:,.2f}')
"

# Generate budget lines
python manage.py shell -c "
from backend.supplies.models import PropertySupplyPlan
from backend.supplies.services import SupplyBudgetService
plan = PropertySupplyPlan.objects.first()
lines = SupplyBudgetService().generate_budget_lines(plan, replace_existing=True)
print(f'Generated {len(lines)} budget lines')
"

Management Commands

# Import items from JS data files
python manage.py seed_supply_items              # Create/update items
python manage.py seed_supply_items --clear      # Delete all and reimport
python manage.py seed_supply_items --dry-run    # Parse-only validation

# Create supply plans for showcases
python manage.py setup_supply_plans             # Create plans for primary ops
python manage.py setup_supply_plans --recalculate  # Also recalculate existing

Budget Integration

Category Mapping

Supply categories map to ShowcaseBudgetLine categories:

Supply Categories Budget Category
Medical, IT & Comms, Cooking, Tools, Machinery, Security, Education, Textiles, Nuclear, Tasmania Disasters EQUIPMENT
Food Storage, Agriculture, Nutrition, Livestock FOOD
Housing, Utilities, Sanitation INFRASTRUCTURE

How Budget Lines Appear

When SupplyBudgetService.generate_budget_lines() runs, it:

  1. Calculates costs for all matching items (filtered by importance + tags)
  2. Groups by budget category and installation year
  3. Creates ShowcaseBudgetLine records with:
  4. line_item: "Supply - Equipment Supplies" (etc.)
  5. description: "[Supply] Auto-generated from {plan name}"
  6. Year columns (year_0 through year_5) populated from grouped costs

These appear alongside [BOM] lines and manual budget entries in the showcase budget view.

Override System

PropertySupplyItemOverride records provide per-item control:

Field Purpose
is_included Set False to exclude an item entirely
custom_cost Override the per-unit cost
custom_quantity_multiplier Scale quantity (e.g., 1.5 = 50% more)
installation_year Defer to years 1-5 instead of year 0

Only create overrides for items that need adjustment — unoverridden items use the plan's cost tier and year 0 by default.

Data Source

The 659 items are sourced from the static JS supply list at static/supply-list/data/. Each of the 17 .js files defines an array of item objects. The seed_supply_items command parses these JS files (handling JS-to-JSON conversion including unquoted keys, single-line comments, and trailing commas) and creates corresponding database records.

To add new items: edit the JS data files, then rerun python manage.py seed_supply_items.