Skip to main content

Test Scenarios (Gherkin)

Automation: These scenarios are executed via Python (Behave) using the zoho_simulation logic 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_namestart_dateend_datestatus
FY252024-10-012025-09-30Closed
FY262025-10-012026-09-30Open
FY272026-10-012027-09-30Planning

And the current date is "2025-10-15" And a Budget_Version exists (Source Version):

snapshot_monthfiscal_yearproposed_amountapproved_amount
2025-07FY26110000100000

And Contracts linked to the same Bucket for FY26:

contract_codestatusfy_allocation
CONT-001Approved42459
CONT-003Proposed5014

When the duplication process creates a new version for "2025-10" Then the new Budget_Version has:

FieldValueSource
proposed_amount110000Inherited (Manual)
approved_amount100000Inherited (Manual)
total_contracts_value47473Auto (42459 + 5014)
committed_amount42459Auto (Status Filter)
closing_forecast100000max(100k, 42k)
remaining_estimate57541100000 - 42459
review_statusDraftInitial 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:

FieldValue
approved_amount100000

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_namestart_dateend_datestatus
FY252024-10-012025-09-30Closed
FY262025-10-012026-09-30Open
FY272026-10-012027-09-30Planning

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 YearAmount Due
FY2689753.42
FY2730246.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_namestart_dateend_datestatus
FY252024-10-012025-09-30Closed
FY262025-10-012026-09-30Open
FY272026-10-012027-09-30Planning

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_namestart_dateend_datestatus
FY252024-10-012025-09-30Closed
FY262025-10-012026-09-30Open
FY272026-10-012027-09-30Planning

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 YearAmount Due
FY2724909

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_amount 100.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:
  1. CONT-P1 is reduced by 50.000 € -> Result: 0 €
  2. 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_applied field is set to true. And the Version's committed_amount increases by 60.000 €. And the Version's total_contracts_value reflects the new reality: 0 (P1) + 10k (P2) + 60k (REAL) = 70.000 €.

Scenario: Multi-FY contract allocation across versions

Given Fiscal_Years are defined:

fy_namestart_dateend_datestatus
FY252024-10-012025-09-30Closed
FY262025-10-012026-09-30Open
FY272026-10-012027-09-30Planning

And a new Contract:

contract_codestart_dateend_datetotal_contract_valuebudget_bucket
CONT-3012026-01-012027-12-31120000Digital Stream

And existing Budget_Versions for the same Budget_Bucket:

snapshot_monthbudget_bucketfiscal_yearproposed_amount
2025-10Digital StreamFY26800000
2026-10Digital StreamFY27600000

When the contract is saved Then contract's fy_allocation subform is populated:

fiscal_yearamount_duecalculation
FY2644876.71Jan 1 - Sep 30 2026 (273 days)
FY2760000.00Oct 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_namestart_dateend_datestatus
FY262025-10-012026-09-30Open
FY272026-10-012027-09-30Planning

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_payments for 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 |