Multi-Step Cascading Allocations¶
Problem¶
Current allocation engine runs a single pass per rule. Real allocations require ordered steps where output of step N becomes input to step N+1. Example: 1. Step 1: Allocate IT costs to all departments by headcount 2. Step 2: Allocate Facilities costs (which now include some IT) by square meters 3. Step 3: Allocate shared services to business units by revenue
Requirements¶
R1: Step ordering in allocation_rules seed¶
Add column step_order (integer) to allocation_rules.csv:
allocation_rule_id,rule_name,step_order,source_account,source_cost_center,driver_type,target_account,description
ALLOC_001,IT Cost Allocation,1,7100,IT,headcount,7100,Step 1: IT by headcount
ALLOC_002,Facility Allocation,2,7200,FACILITY,sqm,7200,Step 2: Facilities by sqm
ALLOC_003,Mgmt Fee Allocation,3,7300,MGMT,revenue,7300,Step 3: Mgmt by revenue
R2: Cascading allocation macro¶
New macro allocation_engine_multistep that:
1. Reads all rules ordered by step_order
2. For step 1: source pool comes from gold_trial_balance (as today)
3. For step N>1: source pool comes from gold_trial_balance PLUS allocated amounts from steps 1..N-1
4. Each step produces allocation rows with step_order column
R3: New model gold_allocation_results_v2¶
- Replaces
gold_allocation_results - Contains all steps' results
- Columns: step_order, allocation_rule_id, data_area_id, fiscal_year, fiscal_period, source_account, target_cost_center, driver_type, pool_amount, driver_weight, allocated_amount
R4: Driver seed flexibility¶
- Each rule references its own driver seed via
driver_seed_namecolumn allocation_drivers_headcount(existing), addallocation_drivers_sqm,allocation_drivers_revenue
Acceptance Tests¶
| Test | Assertion |
|---|---|
assert_allocation_step_order |
All rows have valid step_order matching their rule |
assert_step2_pool_includes_step1 |
Step 2 pool_amount > original TB amount for that account (proves cascade) |
assert_each_step_sums_to_pool |
Per step: sum(allocated_amount) = pool_amount within 0.01 |
assert_no_self_allocation |
No row has target_cost_center = source_cost_center |
Out of Scope¶
- Circular (iterative) allocations
- Reciprocal allocation method