← Docs / Guides
Revenue recognition (IFRS 15 / ASC 606)
Deferred revenue, ratable, milestone and percent-complete schedules, refund liabilities, subscriptions.
Per-line revenue deferral and scheduled recognition: contract liabilities, over-time methods, transaction-price allocation, refund provisions, subscriptions and contract modifications. The default path is unchanged — a plain invoice line still recognizes revenue in full at issue (point in time), which is 606/15-consistent for a single performance obligation satisfied on delivery. Everything below is opt-in per invoice line.
The software is 606/15-capable; the reporting entity is the one that is (or is not) compliant. Choosing the right method per obligation, estimating standalone selling prices and refund rates, and judging whether remaining goods or services are distinct on modification remain accounting judgements the filer makes.
Accounts
Three chart accounts back the flows, wired as posting-rule keys (overridable per company via ledger/posting-rules/update): revenue.deferredIncome → 4910 "Ateinančių laikotarpių pajamos" (contract liability), revenue.refundLiability → 4450 "Grąžinimo įsipareigojimai pirkėjams", revenue.contractAsset → 2910 "Sukauptos pajamos". Existing companies get the accounts by re-applying the chart template (ledger/accounts/apply-template).
Performance obligations on invoice lines
sales/invoices/create|update lines accept recognition: { method, startDate, endDate, milestones } with method one of:
| Method | Behaviour at issue | Recognition |
|---|---|---|
point_in_time (default) |
CR revenue in full | at issue, unchanged |
ratable (startDate..endDate) |
CR deferred income | day-weighted monthly schedule over the service period |
milestone (milestones[], percents summing to 100) |
CR deferred income | one tranche per milestone, recognized on the event |
percent_complete |
CR deferred income | via cumulative progress reports |
AR and VAT are untouched: issue posts DR 2410 for the gross, CR 4492 for VAT, and splits the net between revenue (point-in-time lines) and 4910 (deferred lines). Schedules are stored in base currency (EUR) at the issue-date FX rate — sales/recognition-schedules/list (sales:read) shows every tranche with status pending | recognized | cancelled.
Transaction-price allocation. With more than one line, standaloneSellingPrice on every line allocates the invoice net across obligations pro-rata (IFRS 15 §76–80); the allocated amount — not the stated line price — drives the revenue/deferred split and the schedules. VAT stays with the invoice lines as stated.
Recognition engine
Recognition posts DR 4910 / CR revenue (service/product account and cost center from the original line) as a single journal per run, recorded in sales/recognition/runs/list.
POST /v1/sales/recognition/compute(sales:read){ asOfDate? }— dry-run preview of due ratable tranches.POST /v1/sales/recognition/run(sales:write){ asOfDate?, postingDate?, scheduleIds? }— post due ratable tranches, or exactly the tranches named byscheduleIds(any method).POST /v1/sales/recognition/progress(sales:write){ invoiceLineId, percentComplete, date? }— percent-complete lines: report cumulative progress; the newly earned delta posts immediately, regressions are rejected.POST /v1/sales/recognition/summary(sales:read) — recognized-to-date, remaining, pending count and next due date per line, plus company totals.
Three events drive recognition without polling: period lock (ledger/periods/lock) first recognizes everything due through the period end, posted on the period-end date; delivery-act issue (sales/acts/issue) recognizes the linked invoice's pending milestone tranches on the act date; and a schedule-due timer arms to the next ratable due date and posts per company when it arrives (a locked period retries later). Milestones are event-based on purpose — a milestone's expectedDate is planning information and never triggers recognition by itself.
Variable consideration — refund liability
refundEstimatePercent on a line credits that share of the (allocated) net to 4450 instead of revenue or deferred income at issue — expected refunds are excluded from the transaction price (IFRS 15 §55). Per-invoice state lives in sales/refund-liability/list (estimated, consumed, observed settlement refunds, remaining).
Actuals: a credit note against the invoice debits 4450 up to the remaining liability before touching revenue. sales/refund-liability/true-up (sales:write) { invoiceId, estimatedTotal, date? } revises the estimate and posts the delta against revenue in either direction (floored at the consumed amount). PSP settlement refunds matched to the invoice are recorded on the liability and emit a refund_liability.actual webhook — they do not post against 4450 directly, because relieving revenue and output VAT requires the credit note as the VAT document.
Subscriptions — agreements to invoices
Give an agreement a billingPeriod (monthly | quarterly | annual) and agreements/generate-invoice (agreements:write) creates the next unbilled period's draft invoice: lines from the agreement items (or value as one line per period), each with ratable recognition over the service period. agreements/billing/run { asOfDate? } sweeps all active agreements, generates every due period, and expires agreements fully billed past their end date. Final short periods are pro-rated by days; autoRenew extends the term by its own length and keeps billing. Generated invoices carry agreementId (filterable in sales/invoices/list).
Contract modifications
POST /v1/sales/recognition/modify (sales:write) { invoiceLineId, approach, date?, newEndDate?, newMilestones? }:
prospective— cancel the pending schedule and respread the unrecognized remainder over the new terms from the modification date (remaining goods/services are distinct: IFRS 15 §20(a), §21(a)). Ratable lines takenewEndDate; milestone lines takenewMilestones(percents of the remaining amount).cumulative_catch_up(ratable only) — recompute revenue as if the new terms applied from the start and post the difference immediately, in either direction (single partially-satisfied obligation: §21(b)); the remainder respreads.
Price decreases flow through credit notes: a credit note against an invoice with pending schedules debits deferred income first and trims the pending plan from its far end, then the refund liability, and only then revenue. Price increases are additional invoices with their own recognition — prospective by construction.
Limits
- Schedules and recognition postings are base-currency (EUR) amounts fixed at the issue-date FX rate; deferred balances are not re-measured for FX after issue.
- The contract-asset account (2910) is provided in the chart and as a posting key, but no automated unbilled-revenue flow posts to it yet — recognizing ahead of invoicing is a manual journal today.
- Allocation requires a standalone selling price on all lines of the invoice or none; the residual approach (§79(c)) is not implemented.
- Refund liabilities are tracked net of VAT at invoice level; the corresponding asset for the right to recover returned goods (§B25) is not modelled.
- Cumulative catch-up applies to ratable lines; milestone re-planning is prospective only; percent-complete lines are adjusted through progress reports, not
modify. - Significant financing components (§60–65), non-cash consideration, and consideration payable to a customer are out of scope.
- Automatic schedule-due runs post on the day they fire; catch-up postings into locked periods are rejected — unlock or use an open posting date.