mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-06 09:26:52 +01:00
Add unit tests and knowledge files for BC domain context
- Introduced unit tests for the bc-domain-context implementation, covering various scenarios including filtering by application area, technology mismatches, layer precedence, and conditional applicability. - Added knowledge files related to finance, including topics such as Chart of Accounts, Codeunit 12, Dimension Management, and VAT on prepayment chains, among others. - Each knowledge file includes structured metadata and best practices to enhance the domain knowledge available for Business Central tasks.
This commit is contained in:
parent
0142e1e0de
commit
7fbb121c24
18 changed files with 1170 additions and 1 deletions
28
microsoft/knowledge/finance/chart-of-accounts.md
Normal file
28
microsoft/knowledge/finance/chart-of-accounts.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [chart-of-accounts, gl-account, account-category, account-subcategory, financial-reports]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Chart of Accounts
|
||||
|
||||
## Description
|
||||
|
||||
The Chart of Accounts (table 15 — `G/L Account`) is the backbone of Business Central's financial reporting. Every posting in the system, no matter where it originates, eventually produces G/L Entries against accounts defined here. The chart's structure determines what financial statements look like: accounts carry an Account Category (Assets, Liabilities, Equity, Income, Cost of Goods Sold, Expense) and an Account Subcategory that groups them for statement rows. Financial reports (balance sheet, income statement, trial balance) aggregate entries by these classifications rather than by the raw account numbers.
|
||||
|
||||
Because every sub-ledger (customer, vendor, item, fixed asset, bank) ultimately posts to G/L, the chart is the single integration point for all monetary movement. A miscategorised account shifts amounts between sections of the financial statements without producing a posting error — the numbers look fine at the account level and wrong at the statement level.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Set Account Category and Account Subcategory on every G/L Account — do not leave them blank on new accounts. Run the financial report rebuild after restructuring the chart so the subcategory totals re-calculate against all historical entries.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Using free-text Account Name as the only grouping signal. Reports that aggregate by name are brittle to typos and translation; category/subcategory are the authoritative grouping.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Chart of Accounts & G/L Posting") on 2026-04-21. To be refined in Phase 2 from `D:\Repos\NAV\App\Layers\W1\BaseApp\Finance\`.
|
||||
28
microsoft/knowledge/finance/codeunit-12-gen-jnl-post-line.md
Normal file
28
microsoft/knowledge/finance/codeunit-12-gen-jnl-post-line.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [codeunit-12, gen-jnl-post-line, journal-posting, high-risk, ledger-integrity]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Codeunit 12 (Gen. Jnl.-Post Line)
|
||||
|
||||
## Description
|
||||
|
||||
Codeunit 12 is the single posting engine for every journal line in Business Central. General journals, payment journals, cash receipt journals, recurring journals, IC journals, and the journal-like intermediaries used by document posting (Sales-Post, Purch.-Post, Invoice Post. Buffer) all funnel through this codeunit to produce G/L Entries, Customer Ledger Entries, Vendor Ledger Entries, Bank Account Ledger Entries, VAT Entries, and Detailed Ledger Entries. The entry numbering, dimension resolution, multi-currency math, and VAT computation for every posted line happen here.
|
||||
|
||||
Because every monetary posting passes through codeunit 12, any modification to its behaviour — even a seemingly local change to one sub-procedure — has repository-wide blast radius. A change intended to affect only Purchase posting will also hit Sales, General Journal, Intercompany, bank payments, and every extension that raises integration events on codeunit 12's publishers. Debugging an unexpected posting change across multiple modules frequently traces back here.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Extend codeunit 12 only through the published integration events (`OnAfterPostGLAcc`, `OnAfterPostCustVendAccount`, etc.). Subscribing is additive and local to the subscriber; forking codeunit 12's body inside an extension loses access to Microsoft's future fixes.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Modifying codeunit 12's core computation in a customisation to fix a reported issue. Every subsequent BC platform upgrade must merge around the modification, and the modification's side effects on other modules are rarely exhaustively tested. Use events.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "High-Risk Areas") on 2026-04-21.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [codeunit-408, dimension-management, dimension-merge, high-risk, dimension-set]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Codeunit 408 (Dimension Management)
|
||||
|
||||
## Description
|
||||
|
||||
Codeunit 408 is the central broker for every dimension operation in Business Central. It resolves Default Dimensions into concrete Dimension Set Entries, deduplicates sets by Dimension Set ID, merges header/line/master-data defaults during posting, enforces Dimension Combination rules, and owns the API that every other module uses to read or write dimensions. Sales, Purchase, Manufacturing, Warehouse, Fixed Assets, and Job posting all call into this codeunit; the codeunit is also how BC-internal UI controls retrieve the dimension values shown on a document.
|
||||
|
||||
A modification here propagates to every posted dimension, across every module. The blast radius is not bounded by "we only customised Sales" — a change to the merge logic that Sales happens to exercise may shift dimensions on a Job Journal that shares no code with Sales. Subscribers to codeunit 408's integration events are safe; direct modifications are a high-risk change that frequently produces silent drift (dimension values on ledger entries that are defensible line by line but produce wrong totals in the financial statements).
|
||||
|
||||
## Best Practice
|
||||
|
||||
Extend only via the published integration events or by subscribing to business-layer events that codeunit 408 emits during its lifecycle. Review every dimension-related extension as part of every BC upgrade to confirm its event subscribers still fire.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Writing to Dimension Set Entries (table 480) from custom code to "fix" a miscategorised entry. The set is shared across many entries; editing the set retroactively reclassifies every entry that referenced it, usually in ways the author did not intend.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "High-Risk Areas") on 2026-04-21.
|
||||
28
microsoft/knowledge/finance/dimension-combinations.md
Normal file
28
microsoft/knowledge/finance/dimension-combinations.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [dimension-combination, blocked-combination, dimension-matrix, dimension-value-combination]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Dimension combinations
|
||||
|
||||
## Description
|
||||
|
||||
Dimension Combinations (tables 350 — `Dimension Combination`, and 351 — `Dimension Value Combination`) are the guardrail that restricts which dimension values may coexist on the same posting. Table 350 records pair-level rules for two dimensions (typically Global Dimension 1 and Global Dimension 2): the pair may be Blocked, Limited (only specific value pairs allowed), or blank (free). Table 351 records the allowed value pairs under a Limited combination. The check runs during posting via codeunit 408; when a rejected pair arrives on a Dimension Set, posting fails with a specific error naming the blocked combination.
|
||||
|
||||
Combinations are the right mechanism for organisational rules like "the Marketing department cannot post to the Factory location" — they enforce once, at post time, across every document type. They are the wrong mechanism for user-input validation (they do not fire until post), and they are often surprising to users who see them for the first time years into a deployment because they were set up once and forgotten.
|
||||
|
||||
## Best Practice
|
||||
|
||||
When introducing a new blocked combination, run a what-if query against open documents and journal batches first. Existing lines whose dimensions already violate the new rule will fail posting as soon as the rule activates; fix those lines before turning it on.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Using Dimension Combinations to simulate permission checks. They gate posting, not data entry, and they fire in every module — a combination added to enforce a Sales workflow may suddenly block a General Journal entry no one expected.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Dimensions — The #1 Source of Finance Issues") on 2026-04-21.
|
||||
28
microsoft/knowledge/finance/dimension-default-priority.md
Normal file
28
microsoft/knowledge/finance/dimension-default-priority.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [dimension-default, dimension-priority, posting-conflict, dimension-merge, troubleshooting]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Dimension default priority
|
||||
|
||||
## Description
|
||||
|
||||
At post time, Business Central merges dimension values from several sources into the final Dimension Set for each ledger entry. The merge honours a priority order: document header defaults (copied from customer/vendor at document creation) are the base, document line defaults overlay header (customer/vendor/item/G/L account defaults applied line by line), and line-level user edits overlay the defaults. For Gen. Journal posting, G/L Account default dimensions are applied inside codeunit 12 after the line is otherwise finalised. Dimension Combinations (tables 350/351) are a final gate that may reject the merged set outright.
|
||||
|
||||
The single most common posting error in finance is a conflict during this merge: a line-default mandatory dimension conflicts with a header-default Same Code rule, or a Dimension Combination rejects a pair that neither source knew about. Users see the error only at post time, often long after the values were set. Troubleshooting requires tracing back through each source layer.
|
||||
|
||||
## Best Practice
|
||||
|
||||
When a post fails on dimensions, inspect in this order: (1) the error message's named conflict, (2) Default Dimensions on every master referenced by the document (customer, vendor, items, G/L accounts), (3) the Dimension Combination matrix, (4) document-header dimensions for staleness (a header-level change does NOT cascade to existing lines; if the header was re-coded after lines were entered, line defaults no longer match).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Manually forcing a Dimension Set ID on a ledger entry to bypass the merge. The entry then carries a set that does not match its source defaults, and next-period reports silently disagree with the journal audit trail.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (sections: "Dimensions — The #1 Source of Finance Issues", "Dimension Conflict Troubleshooting") on 2026-04-21.
|
||||
30
microsoft/knowledge/finance/dimensions.md
Normal file
30
microsoft/knowledge/finance/dimensions.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [dimensions, default-dimension, dimension-set, codeunit-408, global-dimension]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Dimensions
|
||||
|
||||
## Description
|
||||
|
||||
Dimensions are analytical tags — Department, Project, Region, etc. — attached to every posting so financial reports can filter and group by business attributes without adding columns to every ledger table. Two representations coexist: Default Dimensions (table 352) declare per-record defaults on masters (customer, vendor, item, G/L account, employee), and Dimension Set Entries (table 480) record the actual combinations carried on each ledger entry. A Dimension Set ID on a ledger entry references the exact set of dimension values; multiple entries sharing a set reuse the same ID rather than duplicating rows.
|
||||
|
||||
Codeunit 408 (`Dimension Management`) is the central broker: it resolves defaults into concrete sets at posting time, deduplicates sets, and enforces dimension combination rules. It also owns the merge logic that walks document header, document line, and master-data defaults to produce the final set.
|
||||
|
||||
Default Dimensions carry one of four rules per dimension: Code Mandatory (posting blocks without a value), Same Code (the value must match the master's default exactly), No Code (posting blocks if any value is provided), or blank (free choice, no constraint). The rule is enforced at post time, not at entry; user-interface entry may allow setting values that later fail posting.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Set Global Dimension 1/2 on every master that drives dimension analysis; this prepopulates document lines without users remembering to add them.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Introducing a new required dimension mid-year without backfilling existing open documents. Posting will fail for every document whose header was created before the rule existed.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Dimensions — The #1 Source of Finance Issues") on 2026-04-21. To be refined in Phase 2 from `D:\Repos\NAV\App\Layers\W1\BaseApp\Foundation\Dimensions\`.
|
||||
30
microsoft/knowledge/finance/entry-application.md
Normal file
30
microsoft/knowledge/finance/entry-application.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [entry-application, remaining-amount, payment-discount, payment-tolerance, codeunit-226, codeunit-227]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Entry application
|
||||
|
||||
## Description
|
||||
|
||||
Entry application is the mechanism by which payments close invoices, credit memos offset invoices, and refunds close credits. A customer ledger entry carries a Remaining Amount that tracks the unapplied balance; an application event (Apply Customer Entries / Apply Vendor Entries) reduces Remaining Amount on both sides of the application until one side hits zero. Codeunit 226 (`CustEntry-Apply Posted Entries`) handles customer applications; codeunit 227 (`VendEntry-Apply Posted Entries`) handles vendors. Both route through codeunit 12 for the G/L posting and write Detailed Cust./Vendor Ledger Entries that preserve the application history.
|
||||
|
||||
Two tolerances add flexibility. Payment Discount gives a counterparty a reduced amount if they pay within a grace window; when the payment matches the discounted amount, the invoice closes and a discount-expense G/L Entry records the difference. Payment Tolerance lets a slightly short payment still close an invoice; the shortfall posts to a Payment Tolerance account. Both are configured on the Sales & Receivables Setup and Vendor Posting Groups; both can be disabled per customer/vendor.
|
||||
|
||||
Applications across currencies trigger an exchange-rate adjustment inside the application itself: the FCY amounts apply directly, but the LCY equivalent of each leg may differ because the rates at posting dates differ. The difference posts to an exchange gain/loss account as part of the application, independent of the period-end Adjust Exchange Rates batch.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Let the Apply action compute the amounts. Manually setting Amount to Apply on one side and letting the other auto-calculate produces rounding that can leave tiny (0.01) Remaining Amounts that block closing the period.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Scripting direct updates to Remaining Amount to close out a balance. The Detailed Cust./Vendor Ledger Entry chain no longer matches and the entry, while appearing closed, cannot be un-applied or reversed cleanly.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Entry Application") on 2026-04-21.
|
||||
28
microsoft/knowledge/finance/exchange-rate-adjustment.md
Normal file
28
microsoft/knowledge/finance/exchange-rate-adjustment.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [exchange-rate, adjust-exchange-rate, report-595, detailed-ledger-entry, unrealized-gain-loss]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Exchange rate adjustment
|
||||
|
||||
## Description
|
||||
|
||||
Open foreign-currency ledger entries accumulate unrealized gain or loss as the exchange rate drifts from the posting-date rate. Report 595 (`Adjust Exchange Rates`) is the period-end batch job that revalues every open customer, vendor, bank, and G/L entry against the rate at the adjustment date. For each entry, it computes the rate delta, posts a Detailed Cust./Vendor Ledger Entry (or G/L Entry for bank and G/L accounts) that brings the LCY value back in line, and posts the offset to the configured Unrealized Gains/Unrealized Losses account. The next run reverses the prior adjustment before posting a new one, so the unrealized accounts only ever carry the current-period difference.
|
||||
|
||||
Running this batch is the hinge between period-end reporting and correct FCY balances. Skipping a period leaves the LCY equivalent of open balances stale; the next run has to absorb two periods of drift into one, producing a large unrealized swing that auditors flag. Running it twice in the same period on the same data is safe — the reversal mechanism makes the operation idempotent as long as the rate table has not changed.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Schedule the batch as part of the month-end close, after posting the last FCY transactions and before freezing the period. Store the Exchange Rate table values the batch used so that re-running against "today's rates" later can be reconciled against the month-end snapshot.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Running the batch without first verifying that the Currency Exchange Rate table has entries for the adjustment date. BC silently uses the most recent earlier entry, which on a missing-rate day can be weeks stale and produces an unrealized swing with no economic meaning.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Multi-Currency — Rounding and Exchange Rates") on 2026-04-21.
|
||||
28
microsoft/knowledge/finance/general-journal-posting.md
Normal file
28
microsoft/knowledge/finance/general-journal-posting.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [general-journal, journal-line, journal-posting, journal-types, gen-jnl-post-line]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# General journal posting
|
||||
|
||||
## Description
|
||||
|
||||
Journal posting is the freeform pathway into G/L. A user fills lines in a journal batch (table 81 — `Gen. Journal Line`) and runs post; codeunit 12 (`Gen. Jnl.-Post Line`) processes each line into the appropriate ledger entries. The same table serves several journal types, distinguished by their template/batch combination: General (generic postings), Payment (outgoing payments with applying logic), Cash Receipt (incoming payments with applying logic), Recurring (allocations and accruals with date formulas), and IC General (intercompany variants that replicate to partner companies).
|
||||
|
||||
Before the post, codeunit 13 (`Gen. Jnl.-Check Line`) validates each line — balancing, dimensions, account existence, posting restrictions. A failure there halts the entire batch; partial posts are not possible within a balanced transaction set. A single journal batch may contain many balanced transactions; each transaction is identified by a matching Document No. and must balance to zero across debits and credits.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Separate unrelated postings into distinct balanced transactions (distinct Document No. values) within the batch. This makes a failure easier to locate and lets un-failed transactions still post if the check is run line-by-line.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Stacking many unrelated postings under one Document No. A single validation error then blocks everything and the user must hunt for the offending line inside the balanced group.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Chart of Accounts & G/L Posting") on 2026-04-21. To be refined in Phase 2 from `D:\Repos\NAV\App\Layers\W1\BaseApp\Finance\`.
|
||||
28
microsoft/knowledge/finance/general-ledger-entries.md
Normal file
28
microsoft/knowledge/finance/general-ledger-entries.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [gl-entry, ledger, posting, subledger, immutable]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# General Ledger entries
|
||||
|
||||
## Description
|
||||
|
||||
G/L Entries (table 17) are the ultimate destination of every monetary posting in Business Central. Every sub-ledger entry — Customer Ledger Entry (21), Vendor Ledger Entry (25), Item Ledger Entry (32), Fixed Asset Ledger Entry (5601), Bank Account Ledger Entry (271) — produces corresponding G/L Entries that update account balances. The sub-ledgers exist to carry dimension-specific analytical data (due date, item number, reservation); G/L Entries are the canonical financial record.
|
||||
|
||||
G/L Entries are immutable. Reversing a mistake requires a corrective posting (often via `Reverse` on the original entry), not modification. The Entry No. column is monotonically increasing, so applications ordering entries by Entry No. see insertion order; they should not assume any relationship between Entry No. and Posting Date.
|
||||
|
||||
## Best Practice
|
||||
|
||||
When reading G/L Entries in a report, filter on Posting Date and Global Dimension 1/2 Code rather than on numeric Entry No. ranges — ranges are not stable across companies and break when entries are reversed and re-posted.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Modifying G/L Entry columns directly in custom code to "fix" a posting error. The sub-ledger entries and supporting tables (Detailed Cust./Vendor Ledger Entry, VAT Entry) remain unchanged and diverge from G/L, producing an off-balance state that only surfaces at period-close reconciliation.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Chart of Accounts & G/L Posting") on 2026-04-21. To be refined in Phase 2 from `D:\Repos\NAV\App\Layers\W1\BaseApp\Finance\`.
|
||||
28
microsoft/knowledge/finance/multi-currency-rounding.md
Normal file
28
microsoft/knowledge/finance/multi-currency-rounding.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [multi-currency, rounding, currency-precision, invoice-rounding, fcy-lcy]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Multi-currency rounding
|
||||
|
||||
## Description
|
||||
|
||||
Every Currency record (table 4) declares four rounding precisions that govern how BC handles foreign-currency (FCY) amounts: Amount Rounding Precision (typically 0.01), Unit-Amount Rounding Precision (typically 0.00001, used for unit prices), Invoice Rounding Precision (typically 0.01, the tolerance that lets an invoice round to a "clean" final amount), and Appln. Rounding Precision (tolerance for closing applications across currencies). The four precisions interact with the local currency's precision to determine what amounts a document ends up posting.
|
||||
|
||||
At post time the codeunit computes three amounts per line: the FCY amount (rounded to Amount Rounding Precision), the LCY amount (FCY × exchange rate, rounded to the local currency's precision), and any residual that falls to the Invoice Rounding account configured on the Customer/Vendor Posting Group. Rounding conflicts appear when: (a) LCY precision is coarser than FCY — JPY bookkeeping with EUR documents rounds to whole yen but allows 0.01 EUR; (b) per-line rounding on a many-line document diverges from single-line rounding of the document total; (c) the exchange rate changes between an order's receipt and its invoice, and the rounding residual shifts.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Use the Invoice Rounding account purposefully — set it to a dedicated G/L account so the residuals aggregate where finance can review them. A catch-all "other income" lumps them with real transactions and hides rounding drift.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Disabling Invoice Rounding by setting the precision to 0. The residuals then split across every VAT and payment account, making period-end reconciliation a hunt for pennies that do not belong to any transaction.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "Multi-Currency — Rounding and Exchange Rates") on 2026-04-21.
|
||||
28
microsoft/knowledge/finance/unrealized-vat.md
Normal file
28
microsoft/knowledge/finance/unrealized-vat.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [unrealized-vat, vat-realization, payment-application, vat-entry, deferred-recognition]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# Unrealized VAT
|
||||
|
||||
## Description
|
||||
|
||||
Unrealized VAT defers the VAT liability to the moment payment settles rather than the moment the invoice posts. When enabled on a VAT Posting Setup cell, posting the invoice creates a VAT Entry with a zero amount in the Amount column and the full amount in Unrealized Amount. When a payment applies to the invoice via codeunit 226 (`CustEntry-Apply Posted Entries`) or 227 (`VendEntry-Apply Posted Entries`), additional VAT Entries are created that move the amount from Unrealized to Realized in proportion to the payment applied. Partial payments realize partial VAT.
|
||||
|
||||
This matters for three reasons. First, the VAT return runs on realized entries only, so the period the liability is declared depends on payment date, not invoice date. Second, the chain of VAT Entries grows: one per application event. Third, reversing an application (un-applying entries) creates mirror VAT Entries that reverse the realization — never edit existing entries. The mechanism is well-defined; bugs usually stem from assumptions that VAT always realizes at posting.
|
||||
|
||||
## Best Practice
|
||||
|
||||
When migrating a company onto Unrealized VAT, take the effective-date approach: new invoices carry the new setup, historical open invoices post-realize at payment under the old setup. Mixing both setups on the same open invoice produces a VAT Entry chain that does not balance.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Expecting the VAT account to equal the invoice's VAT amount immediately after the invoice posts. Under Unrealized VAT, the account is zero until the first payment applies. Reports that compare invoice VAT to G/L VAT balance must filter by realization state or they report every unpaid invoice as an error.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "VAT Calculation") on 2026-04-21.
|
||||
28
microsoft/knowledge/finance/vat-on-prepayment-chains.md
Normal file
28
microsoft/knowledge/finance/vat-on-prepayment-chains.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [vat-prepayment, prepayment-chain, credit-memo, rounding, proportional-adjustment]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# VAT on prepayment chains
|
||||
|
||||
## Description
|
||||
|
||||
When a Sales or Purchase document carries a prepayment percentage, Business Central splits VAT across the prepayment and the final invoice. The prepayment invoice posts VAT on the prepayment percentage of the order; the final invoice posts VAT on the remaining portion and contains a deduction line that reverses the prepayment's VAT share. If a credit memo reverses either leg, its VAT must proportion across whatever has already posted. This chain — prepayment invoice → final invoice → optional credit memo — must reconcile to the same VAT amount a one-shot invoice would have produced.
|
||||
|
||||
The chain is rounding-sensitive: each leg rounds independently per the VAT posting setup, and the sum of rounded legs can differ from rounding the total once. In multi-currency chains, each leg may use a different exchange rate (posting date differs), further complicating reconciliation. Symptom: the VAT account carries a 0.01 or 0.02 residual after all legs post; no single posting caused it, but the chain does not balance to the expected single-invoice equivalent.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Let Business Central compute and post the VAT on every leg rather than overriding it. The proportional-adjustment logic inside codeunit 80/90 expects to own these amounts; manual overrides produce residuals that only surface at VAT return time.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Correcting a prepayment-chain mismatch by modifying the VAT Entry on the final invoice. The entry is linked to the G/L Entry and the sales invoice line; editing it desynchronises the three and the VAT return aggregates the wrong number. Post a corrective document instead.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "VAT Calculation" and "VAT Edge Cases That Cause Triage Issues") on 2026-04-21.
|
||||
28
microsoft/knowledge/finance/vat-posting-setup.md
Normal file
28
microsoft/knowledge/finance/vat-posting-setup.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
bc-version: [1..99]
|
||||
domain: finance
|
||||
keywords: [vat, vat-posting-setup, vat-business-group, vat-product-group, reverse-charge, full-vat]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [finance]
|
||||
---
|
||||
|
||||
# VAT posting setup
|
||||
|
||||
## Description
|
||||
|
||||
VAT Posting Setup (table 325) is the matrix that tells Business Central how to compute VAT for every combination of VAT Business Posting Group (who the counterparty is — domestic, EU, export) and VAT Product Posting Group (what is being transacted — standard goods, reduced-rate goods, exempt services). Each cell of the matrix declares the VAT % and the VAT Calculation Type that applies when that combination appears on a posting.
|
||||
|
||||
Three calculation types cover the common cases. Normal VAT applies the rate as a percentage of the line amount — the standard sales/purchase tax path. Reverse Charge VAT records the VAT on both sides of the transaction without a cash movement; the buyer, not the seller, is responsible for remitting it to the authority. Full VAT treats the entire line amount as VAT with no underlying taxable base — used for VAT-only correction documents. Every posted line in the document flows through the matching cell; misconfigured cells produce posting errors, incorrect returns, or off-balance VAT accounts.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Populate the full matrix, including "not applicable" cells (with zero rate and a note). Missing cells produce an error message that names the combination the user tried to use, which is clearer than an unexpected zero-rate post that would mask the misconfiguration.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Creating a single catch-all VAT Business Group for "everyone" and a single VAT Product Group for "everything." Reporting the VAT return later becomes impossible because every transaction collapses into one cell; the Authority requires transaction-level breakdown.
|
||||
|
||||
## Provenance
|
||||
|
||||
Migrated from microsoft/BCAppsTriage's `plugins/triage/skills/triage/references/area-knowledge/finance.md` (section: "VAT Calculation") on 2026-04-21. To be refined in Phase 2 from `D:\Repos\NAV\App\Layers\W1\BaseApp\Finance\VAT\`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue