Most SMEs in the OHADA zone operate without any formal budget. A 2023 study of 201 Abidjan SMEs found that budget management is rare, ad hoc, and rarely digitized. The consequences:
Budget blindness: No one knows how much has been spent or committed against a plan until month-end reconciliation — or year-end, when it's too late.
Overspending: Multiple departments commit or spend without visibility into remaining budget. By the time the DG notices, the budget is blown.
No early warning: Budget overruns are discovered after the fact, not prevented.
Audit weakness: While budget management is NOT legally mandatory for private companies (confirmed by legal research — OHADA AUDCIF does not require it), OHADA encourages budget management as a governance best practice. Statutory auditors (CAC) often expect a budget vs. actual report.
Budget Lines Management (BUDMGT) is a governance best-practice module — not a compliance module — that gives companies real-time visibility and configurable control over their spending. It provides:
An annual budget structure broken into budget lines (categories of planned spending)
Real-time balance tracking: allocation vs. committed vs. spent vs. available
Configurable controls: three-level enforcement (warn / require-override / hard-block) per budget line
Budget transfer workflow with one-step approval
A real-time dashboard and Excel/CSV exports for budget monitoring
BUDMGT is NOT sellable standalone. It auto-activates when either Expense Management (EXPMGT) or Commitment Management (COMMIT) is purchased. It deactivates only when neither is active (see Platform Vision FR-PV-032).
Key finding from legal research: Budget management is NOT legally mandatory under OHADA (AUDCIF), SYSCOHADA, or Côte d'Ivoire national regulations for private-sector companies — regardless of company size or form (SARL, SA, SAS, Entreprise Individuelle).
BUDMGT is therefore a governance best-practice tool, not a legal compliance tool. All blocking behavior, approval chains, threshold alerts, and reporting features are product design decisions, not legal mandates.
Exception: Non-profit entities (associations, NGOs) governed by SYCEBNL (December 2022) ARE required to produce a "Tableau d'exécution budgétaire." Non-profit compliance mode is documented as V2 (see §A.8 Out of Scope).
BUDMGT role: Validates the annual budget. Approves budget transfers. Dashboard overview of budget health.
Papillon context: In S1-S2 companies (2-29 employees), the DG IS the comptable. They create AND validate the budget themselves. Needs a simple, visual dashboard — not spreadsheet-style tables.
Enterprise context: Reviews consolidated budget dashboards. Delegates transfer approvals to Finance Director. Needs high-level KPIs, not line-level detail.
Papillon context: Often an external accountant (cabinet comptable) managing 5-20 client companies via tenant switcher. Needs efficient multi-tenant workflows. Familiar with SYSCOHADA chart of accounts.
Enterprise context: In-house finance controller managing departmental budgets with multiple budget line owners.
P3b: Responsable Finance / Finance Director — [BOTH]¶
BUDMGT role: Approves budget transfers. Views all budgets. Can override thresholds. Secondary to DG for budget validation.
Papillon context: Exists only in larger SMEs (S4-S6, 50-350 employees). In smaller companies, this role is collapsed into DG.
Enterprise context: Key operational user. Manages budget discipline across departments.
BUDMGT role: Read-only view of budget lines scoped to their department. Sees allocation, committed, spent, and available for their department's lines only. No company-wide budget visibility.
Papillon context: May check budget status before approving a commitment or expense in their department.
Enterprise context: Actively monitors departmental budget consumption. May request transfers for their lines.
As a Comptable or DG,
I want to create an annual budget with budget lines organized by categories,
So that my company has a structured spending plan for the fiscal year.
Acceptance Criteria:
- Given I am a Comptable or DG, When I access BUDMGT for the first time in a new fiscal year, Then I see a guided wizard prompting me to create my first budget.
- Given I am creating a budget, When I add a budget line, Then I must specify: label, category, allocation amount (XOF, 0 decimals), and optionally a department scope.
- Given budget categories are pre-seeded, When I create a budget line, Then I can select from pre-seeded categories or create a custom one.
- Given I create a budget line, When the system prompts "Souhaitez-vous associer un compte SYSCOHADA ?", Then I can optionally map it to a Classe 6x account or skip.
As a DG,
I want to validate the annual budget once it's complete,
So that it becomes the official spending plan and budget lines are locked against informal changes.
Acceptance Criteria:
- Given a budget is in DRAFT status, When the DG clicks "Valider le budget", Then the budget status changes to ACTIVE and all budget line allocations become locked.
- Given a budget is ACTIVE, When a Comptable tries to edit a budget line allocation directly, Then the system blocks the edit and displays "Le budget est validé. Utilisez un virement budgétaire pour modifier les allocations."
- Given a budget is ACTIVE, When I view the budget, Then I see a "Validé le [date] par [DG name]" stamp.
As a Comptable, DG, or Finance Director,
I want to see the real-time balance of each budget line (allocation, committed, spent, available),
So that I know exactly where my company stands financially at any moment.
Acceptance Criteria:
- Given a budget is ACTIVE, When I view a budget line, Then I see: Allocation, Engagé (Committed), Réalisé (Spent), Disponible (Available) = Allocation - Committed - Spent.
- Given a commitment is approved against a budget line, When I refresh the dashboard, Then the Committed amount has increased by the commitment amount and Available has decreased.
- Given an approved commitment converts to an expense, When the system processes the conversion, Then the Committed amount decreases (release) and the Spent amount increases (consume) by the respective amounts.
As a Comptable,
I want to transfer budget from one line to another,
So that I can reallocate funds to where they're most needed without changing the total budget.
Acceptance Criteria:
- Given I am a Comptable, When I create a budget transfer, Then I must specify: source line, destination line, amount, and justification.
- Given the transfer amount exceeds the source line's available amount, When I submit, Then the system blocks the transfer with "Montant insuffisant sur la ligne source."
- Given the transfer is submitted, When the DG or Finance Director approves it, Then the source line's allocation decreases and the destination line's allocation increases by the transfer amount.
- Given the transfer is approved, When I view the audit trail, Then the transfer is recorded with requester, approver, amount, source, destination, justification, and timestamps.
As a Comptable or DG,
I want to configure warning and blocking thresholds on budget lines,
So that the system alerts me before a budget line is exhausted.
Acceptance Criteria:
- Given I am configuring budget settings, When I set tenant-level defaults, Then I can configure three thresholds: Warn (default 80%), Alert (default 95%), Action (default 100%).
- Given a budget line's consumption reaches the Warn threshold, When the threshold is crossed, Then the system sends an in-app notification to the Comptable and DG.
- Given a budget line has a per-line threshold override, When consumption is checked, Then the per-line threshold takes precedence over the tenant default.
- Given the Action threshold is reached and the blocking level is set to "hard-block", When a commitment/expense is submitted against this line, Then the system blocks the operation.
As a DG, Comptable, or Finance Director,
I want to see a visual dashboard of budget consumption,
So that I can quickly assess the overall budget health of my company.
Acceptance Criteria:
- Given I have access to the budget dashboard, When I open it, Then I see: total budget allocation, total committed, total spent, total available, and a consumption percentage.
- Given the dashboard is open, When I view it, Then I see budget consumption broken down by category and by department (for department-scoped lines).
- Given I want detailed data, When I click "Exporter", Then I can download an Excel/CSV file with all budget lines and their current balances.
As a department manager,
I want to see the budget lines allocated to my department,
So that I can monitor my department's spending within budget.
Acceptance Criteria:
- Given I am a Manager, When I access the budget view, Then I see ONLY budget lines scoped to my department.
- Given my department has no budget lines assigned, When I access the budget view, Then I see "Aucune ligne budgétaire affectée à votre service."
- Given I am a Manager, When I try to access company-wide budget data, Then the system restricts access and shows only my department's lines.
As a Comptable or DG using the app in an area with poor connectivity,
I want to view cached budget line balances offline,
So that I have a reference for budget status even without internet.
Acceptance Criteria:
- Given I have previously loaded the budget dashboard while online, When I go offline, Then I can still see the last-cached budget balances.
- Given I am viewing offline data, When I see the dashboard, Then a visible banner states "Données hors ligne — dernière mise à jour : [timestamp]."
- Given I am offline, When I try to submit a budget transfer or any mutation, Then the system shows "Opération impossible hors ligne. Connectez-vous pour effectuer des modifications budgétaires."
As a Comptable or DG whose company starts using BUDMGT mid-fiscal year,
I want to create a partial-year budget for the remaining months,
So that I can start tracking budget consumption immediately without waiting for the next fiscal year.
Acceptance Criteria:
- Given the current fiscal year is already in progress, When I create my first budget, Then the system allows me to set the budget start date to today (or any date within the current fiscal year).
- Given I create a mid-year budget, When I set allocations, Then the allocation represents the remaining budget for the rest of the fiscal year (not a pro-rated annual amount).
As a Comptable,
I want to prepare next year's budget as a DRAFT while the current year's budget is still ACTIVE,
So that I can plan ahead without disrupting current-year operations.
Acceptance Criteria:
- Given the current fiscal year's budget is ACTIVE, When I create a budget for the next fiscal year, Then it is created in DRAFT status.
- Given two fiscal-year budgets coexist (current ACTIVE + next DRAFT), When I navigate the budget module, Then I can switch between fiscal years via a year selector.
- Given the new fiscal year starts, When the system detects the date change, Then it prompts: "Le nouvel exercice a commencé. Voulez-vous activer le budget [year] et clôturer [previous year] ?"
Cooperatives (sociétés coopératives): Do companies governed by the OHADA Uniform Act on Cooperatives have different budget requirements? Not researched. Likely irrelevant for Papillon's SME target.
🟢 LOW
Unresolved — monitor
OQ-BUD-02
Public subsidies / government contracts: Do CI companies receiving public funds face additional budget documentation requirements? Could affect some Papillon clients.
🟢 MEDIUM
Unresolved — needs targeted research if demand arises
OQ-BUD-03
AUSCGIE Art. 376 / 853-12 national modifications: The statutory audit thresholds (Bilan > 125M, CA > 250M, Effectif > 50 for SARL/SAS) are presented as uniform per AUSCGIE, but some OHADA states may have national modifications. Flag for verification if a CAC client reports different thresholds.
A budget belongs to exactly one fiscal year. The fiscal year is determined by the tenant's configured fiscal year (Control Plane FR-PV-100/101/102). BUDMGT does NOT have a separate budget period configuration.
FR-BUD-002
A budget has a lifecycle status: DRAFT → ACTIVE → CLOSED. Only one budget per fiscal year per tenant.
FR-BUD-003
IF a new fiscal year budget is being prepared while the current year's budget is ACTIVE THEN both can coexist: current year = ACTIVE, next year = DRAFT. Maximum of two budgets can exist simultaneously (one ACTIVE, one DRAFT).
FR-BUD-004
IF the DG validates a DRAFT budget THEN the status changes to ACTIVE. The validation is irreversible. Validation date, validator user_id, and validator name are recorded.
FR-BUD-005
IF a budget is ACTIVE THEN all budget line allocations are locked. Allocation changes are possible ONLY through the budget transfer workflow (FR-BUD-040 to FR-BUD-048). Budget revision (direct allocation increase/decrease) is V2.
FR-BUD-006
IF the fiscal year ends THEN the ACTIVE budget must be manually closed by the DG or Comptable. The system prompts closure but does NOT auto-close. On closure: status → CLOSED, all open alerts are resolved, and the year-end balance is frozen.
FR-BUD-007
IF a budget is CLOSED THEN it is read-only. No mutations (reserve, consume, release, transfer) are possible. Historical data remains accessible for reporting.
FR-BUD-008
IF a tenant starts using BUDMGT mid-fiscal year THEN they can create a budget with a start date later than the fiscal year start. The budget's effective period runs from the specified start date to the fiscal year end. Allocations represent the remaining-year budget, not a pro-rated annual amount.
A category CANNOT be deactivated if active budget lines reference it. The system displays: "Cette catégorie est utilisée par [N] lignes budgétaires actives. Réaffectez-les avant de désactiver."
A budget line belongs to exactly one budget (fiscal year) and one category. It has: id, tenant_id, budget_id (FK), category_id (FK), label, allocation (BigDecimal, XOF 0 decimals), committed (BigDecimal), spent (BigDecimal), org_unit_id (FK, nullable — for department scoping), syscohada_account (nullable — full account code), enforcement_level (nullable — overrides tenant default), warn_threshold_pct (nullable — override), alert_threshold_pct (nullable — override), action_threshold_pct (nullable — override), status (ACTIVE / INACTIVE), created_at, updated_at.
FR-BUD-021
available is a computed value: available = allocation - committed - spent. It is NOT stored. It is calculated at query time.
FR-BUD-022
allocation, committed, and spent are stored as BigDecimal. All arithmetic MUST use BigDecimal operations. Never double/float. (Platform rule #4.)
FR-BUD-023
XOF has zero decimal places. All amounts are whole numbers. IF a user enters a decimal value THEN the system rejects it: "Les montants en XOF doivent être des nombres entiers."
FR-BUD-024
IF org_unit_id is NULL THEN the budget line is company-global — any commitment/expense across the company can draw from it.
FR-BUD-025
IF org_unit_id is set THEN the budget line is department-scoped — only commitments/expenses from employees in that org unit (or its children) can draw from it.
FR-BUD-026
During budget line creation, the system displays a prompt: "Souhaitez-vous associer un compte SYSCOHADA ?" with a searchable dropdown of Classe 6x (and 2x for CAPEX) accounts. The field is optional. If skipped, no SYSCOHADA mapping is recorded.
FR-BUD-027
Budget lines are never hard-deleted. They can be deactivated (status → INACTIVE). An INACTIVE budget line is hidden from new operations but preserved in the database for historical reference. Existing commitments/expenses retain their FK reference.
FR-BUD-028
A budget line CANNOT be deactivated if committed > 0 (active commitments exist). The system displays: "Cette ligne a des engagements en cours ([amount] XOF). Annulez-les avant de désactiver."
Reserve (called by COMMIT module on commitment approval): IF available >= requested_amount THEN committed += requested_amount. ELSE the behavior depends on the budget line's enforcement level (FR-BUD-035).
FR-BUD-031
Consume (called by EXPMGT module on expense approval): IF available >= requested_amount THEN spent += requested_amount. ELSE the behavior depends on the enforcement level (FR-BUD-035).
FR-BUD-032
Release (called by COMMIT module on commitment cancellation): committed -= released_amount. IF committed would go negative THEN reject the operation and log an error. This should never happen in normal operation — indicates a data integrity issue.
FR-BUD-033
Commitment-to-Expense conversion: When an approved commitment materializes as an expense: (1) Release the commitment amount (committed -= commitment_amount), (2) Consume the expense amount (spent += expense_amount). These two operations are executed atomically. The net budget impact equals the difference between the expense amount and the commitment amount. If they are equal, the net impact on available is zero.
FR-BUD-034
All budget mutations (reserve, consume, release) MUST be atomic. No partial updates. If the operation fails mid-way, the entire transaction rolls back. The ARCHITECT determines the concurrency/locking strategy (pessimistic vs. optimistic).
FR-BUD-035
Enforcement levels (configurable per budget line, defaults from tenant settings):
Enforcement Level Decision Table:
Budget Line Available
Enforcement Level
Threshold Crossed
→ System Behavior
available > 0 AND consumption < warn_threshold
Any
None
✅ Allow. No alert.
consumption ≥ warn_threshold AND < alert_threshold
✅ Allow. Send urgent notification. Visual warning on the budget line. Log the over-budget operation.
consumption ≥ action_threshold
REQUIRE_OVERRIDE
Action
⏸️ Block. Operation enters PENDING_OVERRIDE status. Requires DG or Finance Director to approve the over-budget operation. On approval: operation proceeds. On rejection: operation cancelled.
consumption ≥ action_threshold
HARD_BLOCK
Action
❌ Block. Operation rejected. Error: "Budget insuffisant sur la ligne [label]. Disponible : [available] XOF. Demandé : [amount] XOF."
IF allocation = 0 THEN any reserve/consume operation triggers the action threshold behavior immediately (you can't spend from an empty line).
FR-BUD-038
Notifications for threshold crossing are sent once per threshold per budget line per fiscal year. The system tracks which thresholds have already been triggered to avoid notification spam.
FR-BUD-039
IF a release or transfer increases available back below a previously crossed threshold THEN the threshold is reset and can trigger again if re-crossed.
A budget transfer moves allocation from one budget line (source) to another (destination) within the same fiscal year. It does NOT change committed or spent amounts.
FR-BUD-041
A transfer has: id, tenant_id, budget_id, source_line_id, destination_line_id, amount (BigDecimal), justification (text, mandatory), requested_by, requested_at, approved_by (nullable), approved_at (nullable), status (PENDING / APPROVED / REJECTED / CANCELLED).
FR-BUD-042
IF transfer.amount > source_line.available THEN the transfer request is rejected at submission: "Montant insuffisant. Disponible sur la ligne source : [available] XOF."
FR-BUD-043
The only limit on transfer amount is the source line's available balance. No percentage cap. No maximum amount. The approval workflow is the control mechanism.
FR-BUD-044
Transfer approval is one-step: the request is routed to the DG (P1) or Finance Director (P3b). Either can approve.
FR-BUD-045
IF the transfer is approved THEN: source_line.allocation -= transfer.amount AND destination_line.allocation += transfer.amount. These two updates are atomic.
FR-BUD-046
IF the transfer is rejected THEN: no allocation changes. The rejection reason is recorded.
FR-BUD-047
The requester can cancel a PENDING transfer before it is approved/rejected.
FR-BUD-048
A budget transfer is only possible on an ACTIVE budget. IF the budget is DRAFT or CLOSED THEN transfers are not available.
Tenant-level default thresholds are stored in the tenant's BUDMGT settings: warn_threshold_pct (default 80), alert_threshold_pct (default 95), action_threshold_pct (default 100), default_enforcement_level (default WARN).
FR-BUD-051
Each budget line can override the tenant defaults by setting its own warn_threshold_pct, alert_threshold_pct, action_threshold_pct, and enforcement_level. IF a per-line value is NULL THEN the tenant default applies.
FR-BUD-052
Threshold validation: warn_threshold_pct < alert_threshold_pct < action_threshold_pct. All values must be between 1 and 200 (allowing over-100% for soft-warn scenarios).
FR-BUD-053
The default_enforcement_level has three values: WARN, REQUIRE_OVERRIDE, HARD_BLOCK. Default shipped value: WARN (best-practice positioning — not punitive by default).
At fiscal year end, the DG or Comptable manually triggers budget closure. The system prompts: "Clôturer le budget [year] ? Cette action est irréversible."
FR-BUD-061
On closure: budget status → CLOSED. Final balances are frozen. No further reserve/consume/release/transfer operations are accepted.
FR-BUD-062
IF there are open (non-zero) committed amounts at closure THEN the system displays a warning: "[N] lignes ont des engagements en cours totalisant [amount] XOF. Ces engagements seront perdus à la clôture." The DG/Comptable must acknowledge this warning to proceed.
FR-BUD-063
On closure, unspent budget amounts are NOT carried forward. The next fiscal year starts with a clean budget (if one exists in DRAFT, it can be activated). Budget carry-over is V2.
FR-BUD-064
On closure, open commitments are NOT migrated to the next fiscal year. They remain associated with the closed year's budget for historical reference. The COMMIT module should flag these to the user for manual resolution.
Responsable Finance (P3b): Approve transfers, approve over-budget overrides, view all lines, export data. Cannot create/edit budget lines or validate budget.
FR-BUD-073
Manager (N+1): Read-only view of budget lines scoped to their department ONLY. No company-wide budget visibility. No mutation capability.
FR-BUD-074
Employé (P4): No access to BUDMGT. Budget information is not exposed to employees.
FR-BUD-075
All permission checks use the platform RBAC system (Control Plane). BUDMGT defines required permissions (e.g., BUDGET_CREATE, BUDGET_VALIDATE, BUDGET_TRANSFER_APPROVE, BUDGET_VIEW_ALL, BUDGET_VIEW_DEPARTMENT) and maps them to platform roles.
May differ from fiscal_year_start for mid-year budgets
label
String(100)
Yes
E.g., "Budget 2026"
status
Enum
Yes
DRAFT / ACTIVE / CLOSED
validated_by
UUID
Nullable
FK → User. Set on validation.
validated_at
Timestamp
Nullable
Set on validation.
closed_by
UUID
Nullable
FK → User. Set on closure.
closed_at
Timestamp
Nullable
Set on closure.
created_by
UUID
Yes
FK → User
created_at
Timestamp
Yes
updated_at
Timestamp
Yes
Constraints:
- UNIQUE(tenant_id, fiscal_year_start) — one budget per fiscal year per tenant
- Only one budget with status=ACTIVE per tenant at any time
- Only one budget with status=DRAFT per tenant at any time
Initial (and current, after transfers) allocated amount. XOF, 0 decimals.
committed
BigDecimal
Yes
Default 0. Increased by reserve, decreased by release.
spent
BigDecimal
Yes
Default 0. Increased by consume.
org_unit_id
UUID
Nullable
FK → OrganisationalUnit. NULL = company-global.
syscohada_account
String(20)
Nullable
Full SYSCOHADA account code (e.g., "6041")
enforcement_level
Enum
Nullable
WARN / REQUIRE_OVERRIDE / HARD_BLOCK. NULL = use tenant default.
warn_threshold_pct
Integer
Nullable
NULL = use tenant default
alert_threshold_pct
Integer
Nullable
NULL = use tenant default
action_threshold_pct
Integer
Nullable
NULL = use tenant default
status
Enum
Yes
ACTIVE / INACTIVE
created_at
Timestamp
Yes
updated_at
Timestamp
Yes
version
Integer
Yes
Optimistic locking version (if ARCHITECT chooses optimistic).
Constraints:
- allocation >= 0, committed >= 0, spent >= 0
- committed + spent <= allocation is NOT a DB constraint (can be exceeded with WARN or REQUIRE_OVERRIDE enforcement)
- UNIQUE(tenant_id, budget_id, label) — no duplicate line names within a budget
IF linkedCommitmentId is not null THEN execute Commitment→Expense conversion (FR-BUD-033): release commitment + consume expense atomically. ELSE execute Consume: budget_line.spent += amount. Apply enforcement rules.
OrganisationUnitCreated
Org & Master Data (CP)
unitId, tenantId, type, name, parentId
No immediate action. New org units become available for budget line scoping.
OrganisationUnitDeactivated
Org & Master Data (CP)
unitId, tenantId, deactivatedDate
IF any active budget lines are scoped to this org unit THEN flag them for review (in-app notification to Comptable). Do NOT auto-deactivate — the lines may still have active commitments.
No immediate BUDMGT action. Future commitments/expenses by this employee will draw from budget lines scoped to the new unit. Existing committed amounts on old-unit lines remain unchanged.
AUDCIF (Acte Uniforme relatif au Droit Comptable et à l'Information Financière)
Budget management is NOT required by AUDCIF for private companies. AUDCIF governs financial accounting, not management accounting/budgeting. Art. 1, 5, 11 define the scope — budget is outside it.
Confirmed by legal research. No compliance risk.
AUDCIF Art. 7
Fiscal year = calendar year (Jan 1 – Dec 31). BUDMGT follows the tenant's fiscal year config from Control Plane (FR-PV-100/101/102).
BUDMGT inherits this behavior — no separate handling.
AUDCIF Art. 22
Immutability of validated accounting records. BUDMGT applies this as a best practice for validated budget allocations (FR-BUD-005).
Best practice adoption, not legal mandate for budgets.
AUDCIF Art. 24
10-year retention for accounting documents. BUDMGT applies 10-year retention by analogy (not legally required for budget data).
Conservative choice. Budget data is lightweight — cost is negligible.
AUSCGIE Art. 376, 853-12
Statutory audit (CAC) thresholds: Bilan > 125M FCFA, CA > 250M FCFA, Effectif > 50 for SARL/SAS. SA always requires CAC. A CAC may expect budget reports as part of governance review.
Contextual. BUDMGT's Excel export satisfies any CAC request for budget data.
SYCEBNL (December 2022)
Non-profit entities MUST produce a "Tableau d'exécution budgétaire." BUDMGT does NOT implement this in MVP.
No budget obligation exists for private companies under any CI fiscal law. Confirmed by legal research.
CI DGI tax regimes
Entreprenant (≤50M), Micro (50–200M), Réel simplifié (200–500M), Réel normal (>500M). These affect accounting requirements, NOT budget requirements. No BUDMGT impact.
CI Loi n°2013-450 (Data Protection)
Budget data is company-level, not personal data. No specific data protection impact. General platform compliance (FR-PV-090-093) applies.
BUDMGT has NO legal compliance obligations in CI for private companies. All module behavior is governed by product design decisions, not regulatory mandates. This is the lowest-risk module from a legal perspective.