From 7c17aa3ab8391af88a5121fa5d4ca6eb88ef1cfe Mon Sep 17 00:00:00 2001 From: Jesper Schulz-Wedde Date: Thu, 17 Sep 2026 18:10:21 +0200 Subject: [PATCH] Fix Finance review applicability and ownership boundaries Remove application-area gating and later VAT-field dependencies, align dynamic shared conventions, separate SCM ownership, and keep journal examples focused on the intended invariant. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/scripts/Test-SkillIndex.ps1 | 4 +- docs/using-bcquality.md | 11 ++-- evaluation/README.md | 4 +- evaluation/review-fixtures.json | 2 +- ...r-entries-through-application-codeunits.md | 4 +- ...nge-ledger-due-dates-through-entry-edit.md | 2 +- .../do-not-edit-shared-dimension-sets.md | 4 +- ...-modify-or-delete-posted-ledger-entries.md | 6 ++- ...mal-vat-journal-amount-includes-vat.bad.al | 2 - ...al-vat-journal-amount-includes-vat.good.al | 2 - .../normal-vat-journal-amount-includes-vat.md | 8 +-- ...edger-entries-through-posting-codeunits.md | 8 +-- ...erve-journal-batch-document-balance.bad.al | 8 +-- ...rve-journal-batch-document-balance.good.al | 4 +- ...preserve-journal-batch-document-balance.md | 2 +- ...erse-transactions-by-transaction-number.md | 2 +- ...ite-dimensions-as-dimension-set-entries.md | 2 +- microsoft/skills/review/al-finance-review.md | 54 ++++++++++++------- 18 files changed, 77 insertions(+), 52 deletions(-) diff --git a/.github/scripts/Test-SkillIndex.ps1 b/.github/scripts/Test-SkillIndex.ps1 index 424532c..e1fd87a 100644 --- a/.github/scripts/Test-SkillIndex.ps1 +++ b/.github/scripts/Test-SkillIndex.ps1 @@ -101,7 +101,7 @@ try { throw "Expected exactly one al-code-review record, found $($review.Count)." } if ((@($review[0].subSkills) -join "`n") -cne ($expectedLeaves -join "`n")) { - throw 'al-code-review subSkills did not preserve the declared 18-leaf order.' + throw "al-code-review subSkills did not preserve the declared $($expectedLeaves.Count)-leaf order." } foreach ($leafPath in $expectedLeaves) { $leaf = @($skills | Where-Object path -ceq $leafPath) @@ -239,4 +239,4 @@ finally { Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue } -Write-Output 'Skill-index check PASSED: deterministic, schema-valid, and all 18 review leaves preserved in order.' +Write-Output "Skill-index check PASSED: deterministic, schema-valid, and all $($expectedLeaves.Count) review leaves preserved in order." diff --git a/docs/using-bcquality.md b/docs/using-bcquality.md index 3186fe7..eae80fb 100644 --- a/docs/using-bcquality.md +++ b/docs/using-bcquality.md @@ -183,7 +183,7 @@ using your normal compilation, analyzer, test, and human-review workflow. ## Coverage and limits -The Microsoft broad review composes the 18 Microsoft domains listed below. +The Microsoft broad review composes the Microsoft domains listed below. The Community Agents review is a separate skill selected by the request, not a nested part of that coordinator. All current review leaves accept app folders, files, and diffs; request an Agent SDK review explicitly when that @@ -193,13 +193,16 @@ Available knowledge is **not** a promise that every rule will run. Selection depends on the task, target context, enabled layers, and source evidence. A whole-folder review is a current-state snapshot: detecting a published API removal or another comparison-only regression requires an actual baseline. -The corpus includes technical AL guidance and targeted Finance posting +The corpus combines technical AL guidance with targeted functional-domain invariants, not exhaustive functional validation or AppSource certification. The Finance leaf reviews journal posting, financial ledger changes, applications, and posting-linked dimension handling. It prunes unrelated code -at the leaf rather than changing broad-review orchestration. Its dimension -guidance can apply across application areas, but it does not own generic +at the leaf rather than changing broad-review orchestration. Finance articles +use `application-area: [all]` so missing application-area context does not +weaken applicable findings; resolved records and operations supply the +narrowing. Finance owns financial ledgers, not Item, Value, Capacity, Warehouse, +or inventory-application records owned by SCM. It also does not own generic custom-table or master Default Dimension wiring. Request a focused "Finance posting review" when only this domain is needed. diff --git a/evaluation/README.md b/evaluation/README.md index f8c1877..f460b08 100644 --- a/evaluation/README.md +++ b/evaluation/README.md @@ -8,7 +8,9 @@ Model-facing preparation hashes case IDs, neutralizes `Good`/`Bad` object-name t The Finance override deliberately covers every paired Finance article, not only the first filename. Its shared context supplies the target version and -application area, not expected answers. Scenario prerequisites live in +localization but deliberately omits application area, as production callers +often do. Finance applicability must come from its source-surface gate, not +an artificial evaluation-only area hint. Scenario prerequisites live in executable AL: the document-balance cases check the template setting, and the VAT cases encode the imported net/VAT/gross totals and applicable VAT mode. Do not move these prerequisites into comments that preparation removes. diff --git a/evaluation/review-fixtures.json b/evaluation/review-fixtures.json index 93c0054..f395139 100644 --- a/evaluation/review-fixtures.json +++ b/evaluation/review-fixtures.json @@ -25,7 +25,7 @@ "reverse-transactions-by-transaction-number", "write-dimensions-as-dimension-set-entries" ], - "context": "Target Business Central 28, worldwide standard application (w1), application-area finance. Review each file as an independent source input." + "context": "Target Business Central 28, worldwide standard application (w1). Review each file as an independent source input." }, "interfaces": { "article": "set-defaultimplementation-on-enum" diff --git a/microsoft/knowledge/finance/apply-ledger-entries-through-application-codeunits.md b/microsoft/knowledge/finance/apply-ledger-entries-through-application-codeunits.md index dfcc874..11f78cd 100644 --- a/microsoft/knowledge/finance/apply-ledger-entries-through-application-codeunits.md +++ b/microsoft/knowledge/finance/apply-ledger-entries-through-application-codeunits.md @@ -4,7 +4,7 @@ domain: finance keywords: [cust-ledger-entry, vendor-ledger-entry, detailed-ledger-entry, remaining-amount, application, unapplication, open, closed-by-entry-no] technologies: [al] countries: [w1] -application-area: [finance] +application-area: [all] --- # Apply and unapply entries through the application workflow, not status flags @@ -23,7 +23,7 @@ See sample: [`apply-ledger-entries-through-application-codeunits.good.al`](apply ## Anti Pattern -Implement payment matching, settlement, or reopening by directly persisting `Open`, `"Closed by Entry No."`, closure amounts/dates, or detailed-entry unapplication flags, or by deleting/rewriting detailed application amounts. Require confirmed writes to existing non-temporary records and settlement intent. Do not suggest assigning a `Remaining Amount` FlowField as a fix. +Implement customer/vendor payment matching, settlement, or reopening by directly persisting `Open`, `"Closed by Entry No."`, closure amounts/dates, or detailed-entry unapplication flags, or by deleting/rewriting detailed application amounts. Require confirmed writes to existing non-temporary customer/vendor or detailed customer/vendor entries and settlement intent. Item/inventory application records belong to SCM, not this rule. Do not suggest assigning a `Remaining Amount` FlowField as a fix. This article owns fabricated application state. Use the [posted-financial-content rule](do-not-modify-or-delete-posted-ledger-entries.md) for original accounting-value corrections, not a second finding prescribing the same application fix. diff --git a/microsoft/knowledge/finance/change-ledger-due-dates-through-entry-edit.md b/microsoft/knowledge/finance/change-ledger-due-dates-through-entry-edit.md index 01fc1ee..aca7b76 100644 --- a/microsoft/knowledge/finance/change-ledger-due-dates-through-entry-edit.md +++ b/microsoft/knowledge/finance/change-ledger-due-dates-through-entry-edit.md @@ -4,7 +4,7 @@ domain: finance keywords: [due-date, initial-entry-due-date, cust-entry-edit, vend-entry-edit, detailed-ledger-entry, aging] technologies: [al] countries: [w1] -application-area: [finance] +application-area: [all] --- # Change posted customer/vendor due dates through the entry-edit workflow diff --git a/microsoft/knowledge/finance/do-not-edit-shared-dimension-sets.md b/microsoft/knowledge/finance/do-not-edit-shared-dimension-sets.md index 38182c3..97b29f2 100644 --- a/microsoft/knowledge/finance/do-not-edit-shared-dimension-sets.md +++ b/microsoft/knowledge/finance/do-not-edit-shared-dimension-sets.md @@ -17,13 +17,13 @@ The same `Dimension Set ID` can be referenced by an unposted journal line and by To change an unposted transaction's dimensions, load its set into a **temporary** `Dimension Set Entry` buffer with `DimensionManagement.GetDimensionSet`, change the buffer, and obtain a reusable ID with `GetDimensionSetID`. Validate dimension values in the buffer so `Dimension Value ID` matches the chosen value. Store the resulting ID on the transaction and synchronize its projections through that record's supported dimension validation. -For already-posted G/L dimensions, use the supported dimension-correction workflow rather than changing shared rows. Read-only access, temporary buffers, and standard maintenance of projection metadata such as `Global Dimension No.` are not membership changes. This rule protects shared posting history; it does not prescribe custom-table/default-dimension wiring. +For already-posted G/L dimensions, use the supported dimension-correction workflow rather than changing shared rows. Read-only access, temporary buffers, and standard maintenance of projection metadata such as `Global Dimension No.` are not membership changes. This rule protects dimension sets reached from general-journal, financial-document, or Finance-ledger flows. It does not own Item, Value, Capacity, Warehouse, or inventory-application record writes, or prescribe custom-table/default-dimension wiring. See sample: [`do-not-edit-shared-dimension-sets.good.al`](do-not-edit-shared-dimension-sets.good.al). ## Anti Pattern -Follow a journal/document/ledger `Dimension Set ID` to a **persistent** `Dimension Set Entry` and modify, rename, or delete its dimension/value membership in order to change that one transaction. Inspect `IsTemporary` guards, aliases, and the fields written before reporting: the same operations on a temporary working copy are expected. +Follow a general-journal, financial-document, or Finance-ledger `Dimension Set ID` to a **persistent** `Dimension Set Entry` and modify, rename, or delete its dimension/value membership in order to change that one transaction. Inspect `IsTemporary` guards, aliases, and the fields written before reporting: the same operations on a temporary working copy are expected. See sample: [`do-not-edit-shared-dimension-sets.bad.al`](do-not-edit-shared-dimension-sets.bad.al). diff --git a/microsoft/knowledge/finance/do-not-modify-or-delete-posted-ledger-entries.md b/microsoft/knowledge/finance/do-not-modify-or-delete-posted-ledger-entries.md index eca3a5e..33a8029 100644 --- a/microsoft/knowledge/finance/do-not-modify-or-delete-posted-ledger-entries.md +++ b/microsoft/knowledge/finance/do-not-modify-or-delete-posted-ledger-entries.md @@ -4,7 +4,7 @@ domain: finance keywords: [g-l-entry, ledger-entry, reversal, audit-trail, correction, financial-content, entry-edit] technologies: [al] countries: [w1] -application-area: [finance] +application-area: [all] --- # Correct posted financial content through posting workflows, not row surgery @@ -19,11 +19,13 @@ Use a supported transaction/register reversal, credit memo, or correcting journa Supported operational edits are deliberate exceptions: for example, `"G/L Entry-Edit"` supports description changes, and `"Cust. Entry-Edit"` / `"Vend. Entry-Edit"` handle their table-specific editable fields. [Due-date synchronization](change-ledger-due-dates-through-entry-edit.md), [application/unapplication](apply-ledger-entries-through-application-codeunits.md), G/L dimension correction, and supported date compression have their own workflows. Do not flag their standard implementations, temporary simulation buffers, or extension-only metadata updates as financial row surgery. A subscriber is not exempt merely because it runs inside a supported workflow: inspect the fields it actually changes. +This rule covers G/L, customer/vendor/detailed, VAT, and financial-posting/register records. Item, Value, Capacity, Warehouse, inventory-application, and other inventory-posting records are SCM concerns. The financial-row leg of one inventory-posting bypass is outside this rule when the same inventory correction resolves it; an independently actionable financial defect remains in scope regardless of the containing module's name. + See sample: [`do-not-modify-or-delete-posted-ledger-entries.good.al`](do-not-modify-or-delete-posted-ledger-entries.good.al). ## Anti Pattern -Persist a change to original financial content, delete posted rows, or fabricate reversal flags/links to repair or undo a transaction outside the supported correction/maintenance workflow. Require an existing, non-temporary standard ledger record and evidence of the fields or rows affected; a `Modify` token alone is insufficient. Settlement-state writes belong to the application article rather than a duplicate finding here. +Persist a change to original financial content, delete posted rows, or fabricate reversal flags/links to repair or undo a transaction outside the supported correction/maintenance workflow. Require an existing, non-temporary Finance-owned record and evidence of the fields or rows affected; a `Modify` token or `*Ledger Entry` name alone is insufficient. Settlement-state writes belong to the application article rather than a duplicate finding here. See sample: [`do-not-modify-or-delete-posted-ledger-entries.bad.al`](do-not-modify-or-delete-posted-ledger-entries.bad.al). diff --git a/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.bad.al b/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.bad.al index e86a246..50ac8ff 100644 --- a/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.bad.al +++ b/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.bad.al @@ -35,13 +35,11 @@ codeunit 50108 "Import Purchase Journal Total" JournalLine.TestField("VAT Calculation Type", JournalLine."VAT Calculation Type"::"Normal VAT"); JournalLine.TestField("VAT %", 25); JournalLine.TestField("VAT Difference", 0); - JournalLine.TestField("Non-Deductible VAT %", 0); JournalLine.TestField("Bal. Gen. Posting Type", JournalLine."Bal. Gen. Posting Type"::" "); JournalLine.TestField("Bal. VAT %", 0); VATPostingSetup.Get(JournalLine."VAT Bus. Posting Group", JournalLine."VAT Prod. Posting Group"); VATPostingSetup.TestField("VAT Calculation Type", VATPostingSetup."VAT Calculation Type"::"Normal VAT"); VATPostingSetup.TestField("VAT %", 25); - VATPostingSetup.TestField("Non-Deductible VAT %", 0); VATPostingSetup.TestField("Unrealized VAT Type", VATPostingSetup."Unrealized VAT Type"::" "); GeneralLedgerSetup.Get(); GeneralLedgerSetup.TestField("Additional Reporting Currency", ''); diff --git a/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.good.al b/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.good.al index 4a54dba..961e234 100644 --- a/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.good.al +++ b/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.good.al @@ -35,13 +35,11 @@ codeunit 50108 "Import Purchase Journal Total" JournalLine.TestField("VAT Calculation Type", JournalLine."VAT Calculation Type"::"Normal VAT"); JournalLine.TestField("VAT %", 25); JournalLine.TestField("VAT Difference", 0); - JournalLine.TestField("Non-Deductible VAT %", 0); JournalLine.TestField("Bal. Gen. Posting Type", JournalLine."Bal. Gen. Posting Type"::" "); JournalLine.TestField("Bal. VAT %", 0); VATPostingSetup.Get(JournalLine."VAT Bus. Posting Group", JournalLine."VAT Prod. Posting Group"); VATPostingSetup.TestField("VAT Calculation Type", VATPostingSetup."VAT Calculation Type"::"Normal VAT"); VATPostingSetup.TestField("VAT %", 25); - VATPostingSetup.TestField("Non-Deductible VAT %", 0); VATPostingSetup.TestField("Unrealized VAT Type", VATPostingSetup."Unrealized VAT Type"::" "); GeneralLedgerSetup.Get(); GeneralLedgerSetup.TestField("Additional Reporting Currency", ''); diff --git a/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.md b/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.md index 80e3dec..6dda9ef 100644 --- a/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.md +++ b/microsoft/knowledge/finance/normal-vat-journal-amount-includes-vat.md @@ -4,20 +4,22 @@ domain: finance keywords: [normal-vat, automatic-vat-entry, gross-amount, net-amount, vat-posting-setup, gen-journal-line, purchase] technologies: [al] countries: [w1] -application-area: [finance] +application-area: [all] --- # Supply a VAT-inclusive journal Amount for automatic Normal VAT ## Description -For a general-journal line using **Automatic VAT Entry** and **Normal VAT**, `Amount` includes VAT. The posting engine extracts tax from that total; it does not add tax to a VAT-exclusive expense imported into `Amount`. For an LCY purchase of net 100 plus 25 VAT, entering 100 produces an 80 expense and 20 VAT, rather than the intended 100 expense and 25 VAT from a total of 125. +For a general-journal line using **Automatic VAT Entry** and **Normal VAT**, `Amount` includes VAT. The posting engine extracts tax from that total; it does not add tax to a VAT-exclusive expense imported into `Amount`. An LCY invoice with net 100 and VAT 25 therefore needs a journal total of 125, not 100. ## Best Practice Map the source's VAT-inclusive total to journal `Amount` in this posting mode. Establish the intended account and posting-group combination before validating the final amount. Account-derived VAT defaults depend on `Copy VAT Setup to Jnl. Lines`; do not assume account selection always supplies the intended configuration. -Require the actual input contract and calculation mode, not just a variable named `NetAmount`. The examples encode source net, VAT, and gross values plus a 25% Normal-VAT setup check. They target an LCY G/L purchase with 0.01 amount rounding and without balancing-side VAT, additional reporting currency, VAT differences, unrealized VAT, or non-deductible VAT. Other calculation types, Manual VAT Entry, reverse charge, Full VAT, sales/use tax, non-deductible or unrealized tax, and other currency/rounding contexts need their own analysis; this is not a universal gross-up formula or country-specific tax advice. +Require the actual input contract and calculation mode, not just a variable named `NetAmount`. The examples encode source net, VAT, and gross values plus a 25% Normal-VAT setup check. They target an LCY G/L purchase with 0.01 amount rounding and without balancing-side VAT, additional reporting currency, VAT differences, or unrealized VAT. Other calculation types, Manual VAT Entry, reverse charge, Full VAT, sales/use tax, unrealized tax, and other currency/rounding contexts need their own analysis; this is not a universal gross-up formula or country-specific tax advice. + +The concern is the supplied transaction total, not its deductible/non-deductible allocation. Non-deductible VAT features can change the allocation of that total, not turn the source's net amount into its gross amount. Do not infer a particular expense or deductible-VAT split from this rule. The samples therefore do not depend on later-version non-deductible-VAT fields. See sample: [`normal-vat-journal-amount-includes-vat.good.al`](normal-vat-journal-amount-includes-vat.good.al). diff --git a/microsoft/knowledge/finance/post-ledger-entries-through-posting-codeunits.md b/microsoft/knowledge/finance/post-ledger-entries-through-posting-codeunits.md index e24856b..aefb6bb 100644 --- a/microsoft/knowledge/finance/post-ledger-entries-through-posting-codeunits.md +++ b/microsoft/knowledge/finance/post-ledger-entries-through-posting-codeunits.md @@ -4,7 +4,7 @@ domain: finance keywords: [g-l-entry, ledger-entry, gen-jnl-post-line, gen-jnl-post-batch, journal-line, register, insert] technologies: [al] countries: [w1] -application-area: [finance] +application-area: [all] --- # Create financial ledger entries through the owning posting engine @@ -19,13 +19,15 @@ Use the owning document or journal posting workflow. For a normal persisted gene `"Gen. Jnl.-Post Line".RunWithCheck` is appropriate for a complete journal line inside a correctly owned posting lifecycle, but it does not invent a balancing account or document number, allocate numbering merely from `Posting No. Series`, or replace [batch document-balancing policy](preserve-journal-batch-document-balance.md). The line codeunit is stateful; its checked wrapper owns its start/continue/finish work. Normal batch posting owns its numbering and commits by default; do not imply these entry points are transaction-neutral. -Exclude temporary buffers and the standard engine's own insertion points. A checked parent may legitimately use `RunWithoutCheck`; do not replace it without inspecting that parent. This rule concerns standard financial ledgers, not a custom table merely named `Ledger Entry` or a supported, specifically reviewed migration/repair workflow. +Exclude temporary buffers and the standard engine's own insertion points. A checked parent may legitimately use `RunWithoutCheck`; do not replace it without inspecting that parent. This rule owns `G/L Entry`, `Cust. Ledger Entry`, `Vendor Ledger Entry`, their detailed customer/vendor entries, `VAT Entry`, and financial-posting/register records, not a custom table merely named `Ledger Entry` or a supported, specifically reviewed migration/repair workflow. + +`Item Ledger Entry`, `Value Entry`, Capacity/Warehouse entries, `Item Application Entry`, and other inventory-posting records are SCM concerns, not this rule's financial-ledger scope. That exclusion includes the financial-row leg of a single inventory-posting bypass when restoring the inventory workflow corrects the whole operation. Distinct, independently actionable financial defects remain in scope. See sample: [`post-ledger-entries-through-posting-codeunits.good.al`](post-ledger-entries-through-posting-codeunits.good.al). ## Anti Pattern -Create posted financial effects by directly inserting persistent `G/L Entry`, customer/vendor ledger, or VAT ledger rows outside their owning posting workflow. Resolve the actual record type and lifecycle. Balanced debit/credit values, copied dimensions, `Insert(true)`, and a lock around entry-number allocation do not turn raw inserts into a complete posting. +Create posted financial effects by directly inserting the Finance-owned records named above outside their owning posting workflow. Resolve the actual record type, operation, and lifecycle; do not match `*Ledger Entry` as a wildcard. Balanced debit/credit values, copied dimensions, `Insert(true)`, and a lock around entry-number allocation do not turn raw inserts into a complete posting. See sample: [`post-ledger-entries-through-posting-codeunits.bad.al`](post-ledger-entries-through-posting-codeunits.bad.al). diff --git a/microsoft/knowledge/finance/preserve-journal-batch-document-balance.bad.al b/microsoft/knowledge/finance/preserve-journal-batch-document-balance.bad.al index 40d4d43..1d5b5b3 100644 --- a/microsoft/knowledge/finance/preserve-journal-batch-document-balance.bad.al +++ b/microsoft/knowledge/finance/preserve-journal-batch-document-balance.bad.al @@ -6,6 +6,7 @@ codeunit 50107 "Post Journal Allocation" JournalTemplate: Record "Gen. Journal Template"; JournalBatch: Record "Gen. Journal Batch"; JournalLine: Record "Gen. Journal Line"; + LineToPost: Record "Gen. Journal Line"; PostLine: Codeunit "Gen. Jnl.-Post Line"; begin JournalTemplate.Get(TemplateName); @@ -24,11 +25,12 @@ codeunit 50107 "Post Journal Allocation" AddAllocationLine(JournalTemplate, BatchName, 20000, CreditAccount, PostingDate, 'ALLOC-B', -90); JournalLine.FindSet(); repeat - PostLine.RunWithCheck(JournalLine); + LineToPost := JournalLine; + PostLine.RunWithCheck(LineToPost); until JournalLine.Next() = 0; end; - local procedure AddAllocationLine(JournalTemplate: Record "Gen. Journal Template"; BatchName: Code[10]; LineNo: Integer; AccountNo: Code[20]; PostingDate: Date; DocumentNo: Code[20]; Amount: Decimal) + local procedure AddAllocationLine(JournalTemplate: Record "Gen. Journal Template"; BatchName: Code[10]; LineNo: Integer; AccountNo: Code[20]; PostingDate: Date; DocumentNo: Code[20]; LineAmount: Decimal) var JournalLine: Record "Gen. Journal Line"; begin @@ -42,7 +44,7 @@ codeunit 50107 "Post Journal Allocation" JournalLine.Validate("Account Type", JournalLine."Account Type"::"G/L Account"); JournalLine.Validate("Account No.", AccountNo); JournalLine.Validate("Gen. Posting Type", JournalLine."Gen. Posting Type"::" "); - JournalLine.Validate(Amount, Amount); + JournalLine.Validate(Amount, LineAmount); JournalLine.Insert(true); end; diff --git a/microsoft/knowledge/finance/preserve-journal-batch-document-balance.good.al b/microsoft/knowledge/finance/preserve-journal-batch-document-balance.good.al index 040269c..beff7f4 100644 --- a/microsoft/knowledge/finance/preserve-journal-batch-document-balance.good.al +++ b/microsoft/knowledge/finance/preserve-journal-batch-document-balance.good.al @@ -26,7 +26,7 @@ codeunit 50107 "Post Journal Allocation" PostBatch.Run(JournalLine); end; - local procedure AddAllocationLine(JournalTemplate: Record "Gen. Journal Template"; BatchName: Code[10]; LineNo: Integer; AccountNo: Code[20]; PostingDate: Date; DocumentNo: Code[20]; Amount: Decimal) + local procedure AddAllocationLine(JournalTemplate: Record "Gen. Journal Template"; BatchName: Code[10]; LineNo: Integer; AccountNo: Code[20]; PostingDate: Date; DocumentNo: Code[20]; LineAmount: Decimal) var JournalLine: Record "Gen. Journal Line"; begin @@ -40,7 +40,7 @@ codeunit 50107 "Post Journal Allocation" JournalLine.Validate("Account Type", JournalLine."Account Type"::"G/L Account"); JournalLine.Validate("Account No.", AccountNo); JournalLine.Validate("Gen. Posting Type", JournalLine."Gen. Posting Type"::" "); - JournalLine.Validate(Amount, Amount); + JournalLine.Validate(Amount, LineAmount); JournalLine.Insert(true); end; diff --git a/microsoft/knowledge/finance/preserve-journal-batch-document-balance.md b/microsoft/knowledge/finance/preserve-journal-batch-document-balance.md index 27751f9..b3079ac 100644 --- a/microsoft/knowledge/finance/preserve-journal-batch-document-balance.md +++ b/microsoft/knowledge/finance/preserve-journal-batch-document-balance.md @@ -4,7 +4,7 @@ domain: finance keywords: [force-doc-balance, gen-journal-template, gen-jnl-post-batch, runwithcheck, document-no, posting-date, balancing] technologies: [al] countries: [w1] -application-area: [finance] +application-area: [all] --- # Preserve the journal batch's document-balancing policy diff --git a/microsoft/knowledge/finance/reverse-transactions-by-transaction-number.md b/microsoft/knowledge/finance/reverse-transactions-by-transaction-number.md index d61f3a2..296d902 100644 --- a/microsoft/knowledge/finance/reverse-transactions-by-transaction-number.md +++ b/microsoft/knowledge/finance/reverse-transactions-by-transaction-number.md @@ -4,7 +4,7 @@ domain: finance keywords: [reversetransaction, reverseregister, transaction-no, entry-no, reversal-entry, g-l-register] technologies: [al] countries: [w1] -application-area: [finance] +application-area: [all] --- # Pass the transaction number, not a ledger-entry number, to ReverseTransaction diff --git a/microsoft/knowledge/finance/write-dimensions-as-dimension-set-entries.md b/microsoft/knowledge/finance/write-dimensions-as-dimension-set-entries.md index 7286b6b..0764f20 100644 --- a/microsoft/knowledge/finance/write-dimensions-as-dimension-set-entries.md +++ b/microsoft/knowledge/finance/write-dimensions-as-dimension-set-entries.md @@ -17,7 +17,7 @@ When a journal line or posting document inherits dimensions, its `Dimension Set For an intentional **complete** dimension transfer, copy the source set ID and synchronize the destination's projections through its supported validation or dimension-management routine. On `Gen. Journal Line`, `Validate("Dimension Set ID", SourceSetID)` updates the two shortcut fields. Do not assume another table has the same validation trigger. -When line-specific dimensions must survive a header change, use the appropriate set-combination or delta routine instead of blindly replacing the line's entire set. Reading or filtering a known global dimension is legitimate; it is not a claim to enumerate every dimension. This rule owns dimension transfer through existing journal/document posting records, not custom-table or master `Default Dimension` wiring, which belongs to data modeling. +When line-specific dimensions must survive a header change, use the appropriate set-combination or delta routine instead of blindly replacing the line's entire set. Reading or filtering a known global dimension is legitimate; it is not a claim to enumerate every dimension. This rule owns transfers through general-journal and financial-document posting records, not writes to Item, Value, Capacity, Warehouse, or inventory-application records owned by SCM. Generic custom-table or master `Default Dimension` wiring belongs to data modeling. See sample: [`write-dimensions-as-dimension-set-entries.good.al`](write-dimensions-as-dimension-set-entries.good.al). diff --git a/microsoft/skills/review/al-finance-review.md b/microsoft/skills/review/al-finance-review.md index 228086d..06090b1 100644 --- a/microsoft/skills/review/al-finance-review.md +++ b/microsoft/skills/review/al-finance-review.md @@ -15,12 +15,13 @@ application-area: [all] # AL Finance review Reviews the `finance` knowledge domain. This is a leaf action skill composed by -`al-code-review`; it invokes no other skills. Application-area discovery is -broad enough for posting-linked dimensions, but source relevance is narrow. +`al-code-review`; it invokes no other skills. Application-area metadata does +not gate Finance coverage; resolved source records and operations do. ## Source -Use READ's **Bounded retrieval for review skills** workflow with +Apply the source-surface gate in Relevance before retrieving knowledge. +If it passes, use READ's **Bounded retrieval for review skills** workflow with `-Domain finance`. Consume every catalog page across enabled layers, preserving each exact path and applicability metadata. Do not select a top-k catalog or deduplicate by basename. Open complete bodies only for exact Worklist paths, @@ -41,10 +42,20 @@ changed executable behavior involving at least one of these surfaces: - General-journal construction or posting, journal-batch processing, or an event subscriber whose resolved publisher is in the financial posting path. -- Writes or correction/application/reversal calls involving standard financial - ledger records, detailed customer/vendor entries, VAT entries, or G/L registers. +- Writes or correction/application/reversal calls involving `G/L Entry`, + `Cust. Ledger Entry`, `Vendor Ledger Entry`, `Detailed Cust. Ledg. Entry`, + `Detailed Vendor Ledg. Entry`, `VAT Entry`, or financial-posting/G/L-register + records. - Dimension transfer or dimension-set mutation connected by visible data flow - to an existing journal, posting document, or financial ledger record. + to an existing general journal, financial posting document, or Finance-owned + ledger record. + +Exclude `Item Ledger Entry`, `Value Entry`, Capacity/Warehouse entries, +`Item Application Entry`, and other inventory-posting records owned by SCM. +Do not adopt their findings when the SCM skill is absent or disabled. For one +inventory-originated posting bypass, equivalent findings have one SCM primary +owner; distinct independent financial defects remain Finance. Classify the +operation and actual record, not an inventory/finance word in a module name. Return `not-applicable` when none is present. Imports, object names, comments, read-only ledger displays, generic `Amount`/`Date`/`Open` fields, and calls to @@ -61,7 +72,7 @@ maps to the changed behavior; generic financial vocabulary is not enough. The following deterministic cues must select their named articles even if keyword ranking would otherwise omit them: -- Persistent standard financial ledger inserts reached from extension posting +- Persistent Finance-owned ledger inserts reached from extension posting code — `post-ledger-entries-through-posting-codeunits`. - Persisted general-journal lines posted through a line-codeunit loop or custom aggregate check, with visible template/document/date balancing context — @@ -69,28 +80,30 @@ keyword ranking would otherwise omit them: - Imported net/tax/gross values mapped into `Gen. Journal Line.Amount`, with evidence of the VAT posting mode and posting-setup combination — `normal-vat-journal-amount-includes-vat`. -- Persisted original accounting-value changes, deletion of posted rows, or +- Persisted original Finance accounting-value changes, deletion of Finance rows, or fabricated reversal flags/links — `do-not-modify-or-delete-posted-ledger-entries`. -- Settlement/reopening code writing `Open`, closure fields, detailed - application amounts, or unapplication flags — +- Customer/vendor settlement/reopening code writing `Open`, closure fields, + detailed customer/vendor application amounts, or unapplication flags — `apply-ledger-entries-through-application-codeunits`. - A due-date change persisted on an existing customer/vendor ledger entry — `change-ledger-due-dates-through-entry-edit`. - A `Reversal Entry.ReverseTransaction` or `ReverseRegister` argument with visible ledger-entry, transaction, or register provenance — `reverse-transactions-by-transaction-number`. -- A complete posting-dimension transfer represented by shortcut/global fields - or a `Dimension Set ID` assignment — +- A complete Finance posting-dimension transfer represented by shortcut/global + fields or a `Dimension Set ID` assignment — `write-dimensions-as-dimension-set-entries`. - A dimension/value membership change on `Dimension Set Entry`, reached from - a journal/document/ledger set ID — `do-not-edit-shared-dimension-sets`. + a general-journal/financial-document/Finance-ledger set ID — + `do-not-edit-shared-dimension-sets`. These are retrieval cues, not findings. Use the selected articles' normative -exceptions to classify standard workflows, temporary records, operational -edits, and extension fields. Finance does not own generic custom-table/master -dimension wiring, number-series API migration, or general AL validation, -locking, transaction, and event-style advice. Do not add those concerns as -Finance agent findings. +exceptions and ownership boundaries to classify standard workflows, temporary +records, operational edits, and extension fields. Do not select a Finance +ledger rule from `*Ledger Entry` or `Insert`/`Modify` alone. Finance does not +own SCM records, generic custom-table/master dimension wiring, number-series +API migration, or general AL validation, locking, transaction, and event-style +advice. Do not add those concerns as Finance agent findings. Resolve actual normative conflicts across layers per READ and record suppressed candidates per DO. Keep every remaining exact path in a stable worklist. @@ -109,7 +122,10 @@ about callers. Use the most specific article for the correction: application-state, due-date, and shared-dimension findings must not also become generic posted-row findings -for the same change. Emit `major` for a demonstrated financial-correctness +for the same change. Do not emit an equivalent Finance finding for the +financial-row leg of one SCM-owned inventory posting bypass; evaluate a +distinct financial defect only when its corrective action is independent. +Emit `major` for a demonstrated financial-correctness violation and reserve `blocker` for directly evidenced destructive corruption under DO's severity rules. Applicability alone produces no finding.