Test Scenarios (Gherkin)
Automation: These scenarios are executed via Python (Behave) using the
zoho_simulationlogic engine (../.agent/skills/zoho_simulation/scripts/logic_engine.py). See techContext.md for framework details and local skills.
Feature: Budget & Rolling Forecast (UC1)
Scenario: Create quarterly budget snapshot (Inheritance)
Given Fiscal_Years are defined:
| fy_name | start_date | end_date | status |
|---|---|---|---|
| FY25 | 2024-10-01 | 2025-09-30 | Closed |
| FY26 | 2025-10-01 | 2026-09-30 | Open |
| FY27 | 2026-10-01 | 2027-09-30 | Planning |
And the current date is "2025-10-15" And a Budget_Version exists (Source Version):
| snapshot_month | fiscal_year | proposed_amount | approved_amount |
|---|---|---|---|
| 2025-07 | FY26 | 110000 | 100000 |
And Contracts linked to the same Bucket for FY26:
| contract_code | status | fy_allocation |
|---|---|---|
| CONT-001 | Approved | 42459 |
| CONT-003 | Proposed | 5014 |
When the duplication process creates a new version for "2025-10" Then the new Budget_Version has:
| Field | Value | Source |
|---|---|---|
| proposed_amount | 110000 | Inherited (Manual) |
| approved_amount | 100000 | Inherited (Manual) |
| total_contracts_value | 47473 | Auto (42459 + 5014) |
| committed_amount | 42459 | Auto (Status Filter) |
| closing_forecast | 100000 | max(100k, 42k) |
| remaining_estimate | 57541 | 100000 - 42459 |
| review_status | Draft | Initial Status |
Scenario: Strict Date Snapping (Auto-alignment)
Given the user attempts to create a Budget Version with snapshot_month "2025-11-15" When the validation logic runs Then the snapshot_month is automatically changed to "2026-01-01" (Next valid quarter start) And the user is alerted about the change And valid quarters are defined as starting on months 1, 4, 7, 10
Given a Budget_Version:
| Field | Value |
|---|---|
| approved_amount | 100000 |
And committed_amount is 120000 (from Approved contracts) When calculations are triggered Then closing_forecast is 120000 (max of 100k and 120k) And an "Overrun Alert" is generated because committed_amount > approved_amount
Scenario: Manual budget manager input for planning fields
Given a Budget_Version exists (V_FY26 for 2025-10) And automated actuals are:
- committed_amount: 300000 When the budget manager manually inputs:
- proposed_amount: 500000
- approved_amount: 450000 Then the Budget_Version updates:
- proposed_amount: 500000 (Team Strategy)
- approved_amount: 450000 (Business Baseline)
- total_contracts_value: calculated from contracts
- closing_forecast: 450000 (max of 450k Approvato vs 300k Impegnato)
- remaining_estimate: 150000 (450k Approvato - 300k Impegnato)
Scenario: Parallel planning across Fiscal Years
When the budget manager initiates planning for the next year (FY27) Then a new planning version (V_FY27) is created for snapshot_month "2026-10" And V_FY26 and V_FY27 coexist for the same Budget Bucket And V_FY26 continues to calculate metrics based on FY26 contract allocations And V_FY27 calculates metrics based on FY27 contract allocations And status updates to one FY do not affect the calculations of the other
Scenario: Remaining estimate can be negative
Given a Budget_Version with proposed_amount 500000 And committed_amount 600000 (from approved contracts) When calculations are triggered Then remaining_estimate is calculated as -100000 And the negative value is accepted and stored
Feature: Contract Management & FY Allocation (UC2)
Scenario: Allocate contract value across fiscal years on creation
Given Fiscal_Years are defined:
| fy_name | start_date | end_date | status |
|---|---|---|---|
| FY25 | 2024-10-01 | 2025-09-30 | Closed |
| FY26 | 2025-10-01 | 2026-09-30 | Open |
| FY27 | 2026-10-01 | 2027-09-30 | Planning |
And a new Contract is created with budget_bucket "Digital Stream", start_date "01-Jan-2026", end_date "31-Dec-2026", total_contract_value 120000 When the contract is saved Then fy_allocation subform has entries:
| Fiscal Year | Amount Due |
|---|---|
| FY26 | 89753.42 |
| FY27 | 30246.58 |
Scenario: Re-allocate on contract edit
Given an existing contract with fy_allocation populated When the contract dates or value are edited Then the fy_allocation is cleared and recalculated with new values
Scenario: Contract spans multiple years proportionally
Given Fiscal_Years are defined:
| fy_name | start_date | end_date | status |
|---|---|---|---|
| FY25 | 2024-10-01 | 2025-09-30 | Closed |
| FY26 | 2025-10-01 | 2026-09-30 | Open |
| FY27 | 2026-10-01 | 2027-09-30 | Planning |
And a contract from "15-Jun-2026" to "15-Jun-2027" with value 100000 When saved Then calculate days: total 366, in FY26: from Jun 15 to Sep 30 (108 days), amount 29508.20 And FY27: from Oct 1 2026 to Jun 15 2027 (258 days), amount 70491.80
Scenario: Contract extends beyond defined fiscal years
Given Fiscal_Years are defined:
| fy_name | start_date | end_date | status |
|---|---|---|---|
| FY25 | 2024-10-01 | 2025-09-30 | Closed |
| FY26 | 2025-10-01 | 2026-09-30 | Open |
| FY27 | 2026-10-01 | 2027-09-30 | Planning |
And a new Contract is created with budget_bucket "Digital Stream", start_date "01-Jan-2027", end_date "31-Dec-2029", total_contract_value 100000 When the contract is saved Then fy_allocation subform has entries:
| Fiscal Year | Amount Due |
|---|---|
| FY27 | 24909 |
And a warning is displayed: "Contract period extends beyond defined fiscal years; only overlapping portion allocated."
Scenario: Contract status change impacts financial metrics
Given a Contract (CONT-201) with status "Proposed" and value 100000 linked to FY26 And a Budget_Version (V_FY26):
- proposed_amount: 500000
- approved_amount: 450000
- committed_amount: 200000 (other contracts) When CONT-201 status changes to "Approved" Then the Budget_Version is recalculated:
- total_contracts_value: (unchanged sum)
- committed_amount: 300000 (now includes CONT-201)
- closing_forecast: 450000 (max of 450k Approvato vs 300k Impegnato)
- remaining_estimate: 150000 (450k Approvato - 300k Impegnato)
Scenario: Manual FIFO consumption of Proposed placeholders (Deep Dive)
Given a Budget_Bucket with two "Proposed" contracts:
- CONT-P1: 50.000 € (Added 09:00 AM)
- CONT-P2: 20.000 € (Added 10:00 AM)
And a Budget_Version exists for this Bucket with
proposed_amount100.000 € When a new Contract "CONT-REAL" is saved as "Approved" with value 60.000 € And the user clicks "Proposed Contracts Value Erosion" button on CONT-REAL Then the FIFO logic triggers:
- CONT-P1 is reduced by 50.000 € -> Result: 0 €
- CONT-P2 is reduced by remaining 10.000 € -> Result: 10.000 €
And both P1 and P2 subforms (fy_allocation) are cleared and recalculated for 0€ and 10k€ respectively.
And CONT-REAL's
erosion_appliedfield is set to true. And the Version'scommitted_amountincreases by 60.000 €. And the Version'stotal_contracts_valuereflects the new reality: 0 (P1) + 10k (P2) + 60k (REAL) = 70.000 €.
Scenario: Multi-FY contract allocation across versions
Given Fiscal_Years are defined:
| fy_name | start_date | end_date | status |
|---|---|---|---|
| FY25 | 2024-10-01 | 2025-09-30 | Closed |
| FY26 | 2025-10-01 | 2026-09-30 | Open |
| FY27 | 2026-10-01 | 2027-09-30 | Planning |
And a new Contract:
| contract_code | start_date | end_date | total_contract_value | budget_bucket |
|---|---|---|---|---|
| CONT-301 | 2026-01-01 | 2027-12-31 | 120000 | Digital Stream |
And existing Budget_Versions for the same Budget_Bucket:
| snapshot_month | budget_bucket | fiscal_year | proposed_amount |
|---|---|---|---|
| 2025-10 | Digital Stream | FY26 | 800000 |
| 2026-10 | Digital Stream | FY27 | 600000 |
When the contract is saved Then contract's fy_allocation subform is populated:
| fiscal_year | amount_due | calculation |
|---|---|---|
| FY26 | 44876.71 | Jan 1 - Sep 30 2026 (273 days) |
| FY27 | 60000.00 | Oct 1 2026 - Sep 30 2027 (365 days) |
And FY26 Budget_Version (2025-10) recalculates:
- total_contracts_value: updated to include 44876.71
And FY27 Budget_Version (2026-10) recalculates:
- total_contracts_value: updated to include 60000.00
And a warning is displayed: "Contract period extends beyond defined fiscal years; only overlapping portion allocated."
Feature: Invoice Register & Reconciliation (UC4)
Scenario: Successful invoice matching
Given a Contract exists with contract_code "ABC123" And an Invoice is imported with imported_id "ABC123", amount 5000 When the invoice is processed Then the invoice status is set to "To Pay" And contract.total_invoiced is updated by +5000 And invoice.contract_id is linked to the contract
Scenario: Invoice matching failure
Given no contract has contract_code "XYZ999" And an Invoice is imported with imported_id "XYZ999" When processed Then invoice status is "Association Error" And no contract is updated
Scenario: Update spent amount with FY-competence (Single Date)
Given a Contract for FY26
And an Invoice with invoice_date falling in FY26
When the reconciliation process runs
Then the invoice is automatically allocated to FY26 (subform invoice_fy_allocation)
And budget_version (FY26).spent_amount increases by the invoice amount
And remaining_payments for FY26 is recalculated
Scenario: Multi-FY Invoice Splitting (Automated via Service Period)
Given Fiscal_Years are defined:
| fy_name | start_date | end_date | status |
|---|---|---|---|
| FY26 | 2025-10-01 | 2026-09-30 | Open |
| FY27 | 2026-10-01 | 2027-09-30 | Planning |
And a Contract spanning FY26 and FY27
And an Invoice for 10.000 €
And service_start_date is "2026-08-01" (FY26)
And service_end_date is "2026-11-30" (FY27)
When the invoice is saved
Then the system automatically splits the invoice in invoice_fy_allocation (pro-rata):
- Total Service Days: 122 (Aug 1 - Nov 30)
- FY26: 5.000,00 € (61 days: Aug-Sep)
- FY27: 5.000,00 € (61 days: Oct-Nov)
And budget_version (FY26).spent_amount is updated automatically
And budget_version (FY27).spent_amount is updated automatically
And
remaining_paymentsfor both FYs are updated correctly
Feature: Strategic Dimensions & Reporting (UC3-New)
Scenario: Multi-dimensional budget analysis
Given Budget Buckets categorized by:
- Domain: IT, HR
- Stream: Infrastructure, Training
- Expense Type: Capex, Opex When a report is generated Then metrics (Proposed, Approved, Committed, Spent) are aggregated correctly at each level And Variance is visible for each Stream (Approved vs Committed) And delta expectations (Proposto vs Approvato) is visible to flag strategic risks
Feature: Financial Oversight & Alerts (UC5)
Scenario: Monitor budget health metrics
Given a Budget_Version (V_FY26) with:
- proposed_amount: 500000 (Team Strategy)
- approved_amount: 450000 (Business Baseline)
- committed_amount: 400000 (Reality) When budget health monitoring runs Then system calculates:
- Percent Consumed: 88.8% (400k / 450k Approved)
- Delta Strategy: +50k (Proposed vs Approved) And budget health is determined as "Healthy" (under baseline)
Scenario: Alert for negative remaining estimate (Overrun)
Given a Budget_Version with approved_amount 500000 and committed_amount 600000 When budget health monitoring runs Then system detects negative remaining_estimate vs Approved And generates "Budget Overrun" critical alert And sends notification to budget manager
Scenario: Variance analysis and reporting
Given multiple budget versions across FYs When variance analysis runs Then system calculates:
- Approved vs Committed vs Proposed variance for each version
- Remaining estimate trends
- Multi-FY comparison metrics And generates comprehensive variance report
Feature: Historical Analysis & Audit (UC6)
Scenario: Compare budget versions across fiscal years
Given FY26 budget version and FY27 budget version When version comparison is requested Then system retrieves both versions And calculates differences in proposed_amount (Strategy), approved_amount (Baseline), and committed_amount (Reality) And generates comparison report showing planning vs execution evolution
Scenario: Track budget evolution over time
Given multiple versions of a budget exist for budget_bucket "Digital Stream" (2025-01, 2025-04, 2025-07) When evolution analysis is requested Then system retrieves all versions in chronological order And calculates metric changes between versions And generates evolution timeline report
Scenario: Audit trail and change history
Given budget versions have been modified over time When audit trail is requested Then system retrieves complete change history And shows who made changes, when, and what was changed And provides detailed audit log for compliance
Feature: Budget Version Recalculation
Scenario: Manual Batch Recalculation (Dynamic & Reproducible)
Given a Budget_Version (V_FY26) for October 2025 with:
- approved_amount: 450000
- committed_amount: 84191 (from previous contracts)
- spent_amount: 8000 (from previous invoices)
- last_recalculated: "2025-10-01"
When the Budget Manager creates a new Contract "CONT-NEW-2":
- budget_bucket: Same as V_FY26
- status: "Approved"
- fy_allocation: { fiscal_year: FY26, amount_due: 10000 }
And the Budget Manager creates a new Invoice "INV-NEW-2":
- budget_bucket: Same as V_FY26 (via Contract)
- status: "Paid"
- invoice_fy_allocation: { fiscal_year: FY26, amount_allocated: 5000 }
And the user goes to the Budget_Versions report And selects V_FY26 And clicks the "Recalculate Selected Versions" button
Then the script executes and the Budget_Version updates:
- committed_amount: 94191 (84191 + 10000)
- spent_amount: 13000 (8000 + 5000)
- residual: 437000 (450000 - 13000)
- last_recalculated: Current Time
And if the process is repeated with a second set of Contract/Invoice, the values increment accordingly, demonstrating reproducibility.
Feature: Typed Budget Versions (CAPEX vs OPEX)
Scenario: Segregated aggregation by Expense Type
Given a Budget_Bucket "Website Revamp" And Fiscal Year "FY25" is Open And two Budget_Versions exist for this Bucket/FY: | expense_type | approved_amount | | Capex | 50000 | | Opex | 20000 |
And Contracts exist: | contract_code | expense_type | status | amount_due_fy25 | | CONT-C1 | Capex | Approved | 30000 | | CONT-O1 | Opex | Approved | 5000 | | CONT-O2 | Opex | Proposed | 2000 |
When the versions are recalculated Then the CAPEX Version has:
- total_contracts_value: 30000 (CONT-C1)
- committed_amount: 30000
- remaining_estimate: 20000 (50k - 30k)
And the OPEX Version has:
- total_contracts_value: 7000 (CONT-O1 + CONT-O2)
- committed_amount: 5000 (CONT-O1 only)
- remaining_estimate: 15000 (20k - 5k)
Scenario: Cross-Type Validation (Strict Inheritance)
Given a Budget_Version "Website - FY25 - Capex" exists And NO "Opex" version exists for "Website - FY25" When a user attempts to create a Contract for "Website" with expense_type "Opex" aligned to "FY25" Then the system should allow the creation (as per patterns) But the Contract will NOT be aggregated into the Capex version And a warning or report should flag "Orphaned Contract: No matching Opex Version found"
Scenario: Mixed Invoice Reconciliation
Given a CAPEX Contract "Server Hardware" (Value 10k)
And an OPEX Contract "Cloud Subscription" (Value 5k)
And a CAPEX Version (Approved 10k) and OPEX Version (Approved 5k)
When an Invoice of 2k is matched to "Server Hardware"
Then only the CAPEX Version's spent_amount increases by 2k
And the OPEX Version's spent_amount remains unchanged
Feature: Strategic Pivot Reporting
Scenario: Aggregate spending by Stream and Budget Bucket
Given the following "Streams": | name | code | stream_type | | Digital Transf | 1.1 | Strategic | | Core Ops | 2.0 | Operational |
And the following "Budget_Buckets": | bucket_name | stream | domain | | Cloud Infra | Digital Transf | IT | | Legacy Maint | Core Ops | IT |
And the following "Fiscal_Years": | fy_name | start_date | end_date | | FY25 | 2024-10-01 | 2025-09-30 | | FY26 | 2025-10-01 | 2026-09-30 |
And the following "Budget_Versions": | budget_bucket | fiscal_year | expense_type | approved_amount | | Cloud Infra | FY25 | Opex | 10000 | | Cloud Infra | FY26 | Opex | 50000 | | Legacy Maint | FY25 | Opex | 20000 |
When I generate the "Strategic Pivot" report
Then the report row for "Digital Transf" should show: | fiscal_year | approved_amount | | FY25 | 10000 | | FY26 | 50000 |
And the report row for "Core Ops" should show: | fiscal_year | approved_amount | | FY25 | 20000 | | FY26 | 0 |