Skip to content

Bug/648925 VAT charged in Sales Invoice with Cash Basis (Unrealized VAT) is not paid on Sales Credit Note applied to that Posted Sales Invoice if we use a similar Cash Basis VAT Prod Posting Group in the Mexican version - regression. - #13015

Open
Maria Jose Jofre (v-mjofre) wants to merge 6 commits into
mainfrom
bugs/648925-master-VAT-posted-SalesInv-CredNote-CashBasis

Conversation

@v-mjofre

@v-mjofre Maria Jose Jofre (v-mjofre) commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Error Reported
When a posted sales credit memo was applied to a sales invoice under the Cash Basis VAT model, the invoice’s unrealized VAT was not realized if the credit memo used a different VAT product posting group—even when both VAT posting setups were functionally equivalent.

The existing logic matched VAT entries only by their exact VAT business and product posting groups, preventing the system from identifying the corresponding invoice VAT entry.

Solution
Updated the Cash Basis VAT realization logic to identify equivalent VAT posting setups between sales invoices and sales credit memos.

Two VAT posting setups are considered equivalent when they have matching VAT business posting groups, VAT calculation types, VAT percentages, Cash Basis unrealized VAT types, sales VAT accounts, and sales unrealized VAT accounts.

The solution:

  • Maps credit memo VAT groups to their corresponding invoice VAT groups.
  • Supports full and partial credit memos.
  • Supports documents containing multiple VAT groups.
  • Preserves the credit memo’s VAT posting groups in the generated VAT entries.
  • Avoids matching non-equivalent or ambiguous VAT posting setups.
  • Prevents unnecessary G/L entries from being created to transfer amounts between unrealized and realized VAT accounts.
  • Preserves the existing public PostUnrealVATEntry interface.

Files Modified

  • GenJnlPostLine.Codeunit.al
    Updated the unrealized VAT posting logic to map equivalent invoice and credit memo VAT groups and use the correct groups when creating VAT entries.

  • CustLedgerEntry.Table.al
    Added logic to collect VAT posting setups from invoices and credit memos, identify equivalent Cash Basis VAT configurations, and calculate the applicable amounts by VAT group.

  • ERMCashBasis.codeunit.al
    Added automated tests covering full and partial credit memos, multiple VAT groups, mixed exact/equivalent groups, and non-equivalent VAT configurations.

Result
Applying a sales credit memo with an equivalent but differently coded VAT posting group now correctly realizes the related invoice’s unrealized VAT.

The VAT amount is realized proportionally for partial credit memos and independently for each VAT group in documents with multiple rates. Non-equivalent configurations remain unchanged, and no unnecessary VAT realization G/L entries are generated.

Fixes
[[AB#654308]

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 1

Recommendation: Request Changes

What this PR does

This change extends Cash Basis VAT application so a sales credit memo can realize invoice VAT when the documents use different but equivalent VAT posting groups. It maps groups in both directions, keeps the credit memo groups on the generated VAT entries, and adds coverage for full, partial, multi-group, ambiguous, and non-equivalent cases.

Problem-solution fit

Fit: Strong

The change targets the reported regression directly, and the new tests cover the main sales-document variants. One existing general-journal path is unintentionally changed by the new document-type lookup.

Suggestions

S1 (🔴 High): Preserve general journal credit memo realization
Posting a customer credit memo directly from a general journal creates no Sales Cr.Memo Line. These new invoice groups make grouping run anyway, and GetInvoiceVATPostingGroupForCreditMemoVATGroup() then returns false, so the applied invoice's cash-basis VAT is not realized. Keep the whole-settlement fallback when no posted credit-memo lines exist, and add a regression test.

S2 (🟠 Moderate): Clear the new analyzer warning
The required app builds fail because the new local overload introduces AA0244 for GLEntryNo. Rename that parameter and its uses so the warning comparison passes.

Risk assessment and necessity

Risk: This changes Cash Basis VAT realization in core customer application posting. A wrong branch can leave unrealized VAT open or realize the wrong VAT group; the sales-document tests are broad, but the general-journal fallback is not covered and the required builds currently fail on a new analyzer warning. The existing public PostUnrealVATEntry interface is preserved.

Necessity: Supporting equivalent VAT posting groups is needed to restore correct realization for the reported regression. The scope is focused, but it must preserve credit memos posted outside Sales documents before it is safe to merge.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13015 round=1 by=alexei-dobriansky at=2026-10-20T01:06:13Z lastSha=8640a678e3585512ae60226d41151e7a48aad451 reviewKey=fd938948b51707e4a519f8e34a5e7bcfb0550555698fc3500c5fb11533f405f4 suggestions=S1@9f039eda,S2@2caab76a

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 2

Recommendation: Request Changes

What this PR does

The latest commit preserves the whole-settlement path for general journal credit memos that have no posted sales lines. It also adds full, partial, and unapply regression scenarios, moves repeated VAT allocation calculations outside the entry loop, and clears the prior parameter-name warning. The posting fallback now addresses the earlier general-journal regression, but the new test calls do not match either helper signature and stop the affected apps from compiling.

Status of previous suggestions
ID Title Status Author response
S1 Preserve general journal credit memo realization Addressed The fallback is restored when no posted sales credit memo lines exist, with intended regression coverage added in 30f7055.
S2 Clear the new analyzer warning Addressed The local overload parameter was renamed to GLRegisterEntryNo.
New observations (commits since round 1)

S3 (🔴 High): Fix the mismatched test helper calls
The four new tests call VerifyGeneralJournalCrMemoRealizesInvoiceVAT with two arguments, but only a one-argument procedure has that name; the unused RunGeneralJournalCrMemoVATScenario has the matching signature. The affected NA apps cannot compile. Call the intended helper or consolidate the duplicate helpers.

Risk assessment and necessity

Risk: This is core Cash Basis VAT application logic, where a wrong branch can leave VAT unrealized or post incorrect ledger amounts. The general-journal fallback is now present and the parameter warning is fixed, but the new regression tests currently prevent the MX, US, and CA app builds from completing, so the posting behavior cannot be validated in this revision.

Necessity: Equivalent VAT posting groups must realize the same invoice VAT, and general journal credit memos must keep the existing whole-settlement behavior. The remaining correction is small but required before this financial posting change is safe to merge.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13015 round=2 by=alexei-dobriansky at=2026-10-21T01:11:55Z lastSha=30f7055cdbbda48968b3473042965196e723b32a reviewKey=77022e39f50b527c001f6ea526bd2ce12a31ce00edaa20eb8ed47f2e624b130b suggestions=S1@9f039eda:addressed,S2@2caab76a:addressed,S3@ec7df5ad:new parentRound=1

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 3

Recommendation: Accept

What this PR does

The latest commit fixes the mismatched test helper calls and adds full and partial multi-VAT-group coverage for general journal credit memos. The corrected calls now match the intended helper, and the added scenarios exercise the whole-settlement fallback across each invoice VAT group without changing the posting logic again.

Status of previous suggestions
ID Title Status Author response
S1 Preserve general journal credit memo realization Addressed The no-sales-line fallback remains in place, and full, partial, unapply, and multi-group general journal scenarios now cover it.
S2 Clear the new analyzer warning Addressed The local overload continues to use GLRegisterEntryNo.
S3 Fix the mismatched test helper calls Addressed The four two-argument calls now use RunGeneralJournalCrMemoVATScenario, and the one-argument helper is used by the new multi-group tests.
New observations (commits since round 2)

None.

Risk assessment and necessity

Risk: This remains sensitive Cash Basis VAT application code, where a wrong allocation can leave VAT unrealized or post the wrong ledger amounts. The latest changes are limited to the missing namespace and regression tests, and the earlier posting fallback is now covered for full, partial, unapply, and multiple-group cases. The current MX check still reports analyzer warnings on earlier PR lines, so CI must be green before merge.

Necessity: Equivalent VAT posting groups must realize the same invoice VAT, while general journal credit memos must keep the existing whole-settlement behavior. The code and test scope now match those requirements.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13015 round=3 by=alexei-dobriansky at=2026-10-21T19:29:31Z lastSha=4feb607975bcaef16418b0a70f5ef6ce460fe396 reviewKey=07ae5990029bb6c02dbc65062c56763a7d5f0a931bcf25ee1f4a019971a8903b suggestions=S1@9f039eda:addressed,S2@2caab76a:addressed,S3@ec7df5ad:addressed parentRound=2

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 4

Recommendation: Accept

What this PR does

The latest commit corrects the general journal unapply test so it includes the reversal G/L entries, whose document type is blank, together with the original credit memo entries. It also verifies that each VAT account has exactly the original and reversal entry before checking that their amounts net to zero. The posting logic is unchanged, and the updated assertions match the unapply behavior.

Status of previous suggestions
ID Title Status Author response
S1 Preserve general journal credit memo realization Addressed The no-sales-line fallback remains covered by full, partial, unapply, and multi-group scenarios.
S2 Clear the new analyzer warning Addressed The posting overload continues to use GLRegisterEntryNo.
S3 Fix the mismatched test helper calls Addressed The corrected helper calls remain in place and compile against the intended signatures.
New observations (commits since round 3)

None.

Risk assessment and necessity

Risk: Cash Basis VAT application is financially sensitive because a wrong allocation can leave VAT unrealized or post the wrong ledger amounts. The latest change only strengthens the unapply verification and does not alter production behavior. Required CI is still red: the default localized builds report two new AA0139 warnings from earlier test setup changes, and several clean jobs also report runner container failures, so CI must be green before merge.

Necessity: Equivalent VAT posting groups must realize the same invoice VAT, while general journal credit memos must preserve the existing whole-settlement path. The latest test correction is needed to verify that unapplication restores VAT and reverses both G/L transfers correctly.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13015 round=4 by=alexei-dobriansky at=2026-10-22T01:15:07Z lastSha=2f3a9bcd12679e5ca198fc4d2fb4e9a981f7e74e reviewKey=5a93de29c576227ece73e5fadd2235520f03476ed05a46b4f0696d4ecd4672db suggestions=S1@9f039eda:addressed,S2@2caab76a:addressed,S3@ec7df5ad:addressed parentRound=3

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 5

Recommendation: Accept

What this PR does

The latest commit updates two exchange-rate VAT tests to limit the user ID to the length stored by the My Notifications table. The field and the test-library parameter are both Code[50], so the new CopyStr calls remove the overflow warning without changing the test behavior or production posting logic.

Status of previous suggestions
ID Title Status Author response
S1 Preserve general journal credit memo realization Addressed The no-sales-line fallback remains covered by full, partial, unapply, and multi-group scenarios.
S2 Clear the new analyzer warning Addressed The posting overload still uses GLRegisterEntryNo, and the latest commit clears the remaining user-ID overflow warnings.
S3 Fix the mismatched test helper calls Addressed The corrected helper calls remain in place and match the intended signatures.
New observations (commits since round 4)

None.

Risk assessment and necessity

Risk: Cash Basis VAT application remains financially sensitive because a wrong allocation can leave VAT unrealized or post incorrect ledger amounts. The latest change is limited to test setup, and its length limit matches both the stored user-ID field and the called procedure. The build matrix is still running, with no failing check at review time.

Necessity: Equivalent VAT posting groups must realize the same invoice VAT while preserving the general-journal fallback. The latest correction is needed to remove the test analyzer warnings without changing the covered behavior.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13015 round=5 by=alexei-dobriansky at=2026-10-22T19:28:05Z lastSha=02c54d7c58d6d72c99cc626fac4138104e08cf29 reviewKey=10299d540e588e27bd99f5a74fba4fd5a4b5f02169ca661ad8fea13a770c7cb2 suggestions=S1@9f039eda:addressed,S2@2caab76a:addressed,S3@ec7df5ad:addressed parentRound=4

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Stale Status Check Deleted

The Pull Request Build workflow run for this PR was older than 72 hours and has been deleted.

📋 Why was it deleted?

Status checks that are too old may no longer reflect the current state of the target branch. To ensure this PR is validated against the latest code and passes up-to-date checks, a fresh build is required.


🔄 How to trigger a new status check:

  1. 📤 Push a new commit to the PR branch, or
  2. 🔁 Close and reopen the PR

This will automatically trigger a new Pull Request Build workflow run.

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Good Sense Reviewer - Round 6

Recommendation: Accept

What this PR does

The latest commit excludes blank or comment lines when collecting posted credit memo VAT groups and amounts. This keeps those lines from creating an empty VAT group during Cash Basis VAT allocation. It also removes overlapping tests while retaining coverage for full application through the unapply scenario, partial and multi-group general journal application, and equivalent, non-equivalent, and ambiguous VAT posting setups.

Status of previous suggestions
ID Title Status Author response
S1 Preserve general journal credit memo realization Addressed The no-sales-line fallback remains in place and is still covered by full unapply and partial multi-group scenarios.
S2 Clear the new analyzer warning Addressed The posting overload still uses GLRegisterEntryNo, and the user-ID length corrections remain in place.
S3 Fix the mismatched test helper calls Addressed The retained tests continue to call the intended helpers with matching signatures.
New observations (commits since round 5)

None.

Risk assessment and necessity

Risk: Cash Basis VAT application is financially sensitive because incorrect grouping can leave VAT unrealized or post incorrect ledger amounts. The new line-type filter is applied consistently to credit memo group discovery and allocation, and the remaining tests cover the important full, partial, multi-group, equivalent, non-equivalent, and unapply paths. The current build matrix is still running, so CI must complete successfully before merge.

Necessity: Equivalent VAT posting groups must realize the same invoice VAT while general journal credit memos preserve the whole-settlement fallback. Ignoring blank posted lines is needed so descriptive lines do not participate in VAT grouping.


[AI-PR-REVIEW] version=1 promptVersion=4 system=github pr=13015 round=6 by=alexei-dobriansky at=2026-10-27T14:25:15Z lastSha=1137c21f6310c5e2fbe8ac0cafe3c2fe95456429 reviewKey=27b37bbb4d146ed09670325b04b06b59a9fe9a3e79d7f9fc6450b7f814bea104 suggestions=S1@9f039eda:addressed,S2@2caab76a:addressed,S3@ec7df5ad:addressed parentRound=5

SalesCrMemoLine.SetLoadFields(Type, "Amount Including VAT", "VAT Bus. Posting Group", "VAT Prod. Posting Group");
if SalesCrMemoLine.FindSet() then
repeat
if CreditMemoVATPostingSetup.Get(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟠\ High\ Severity\ —\ Performance}$

The unbounded Sales Cr.Memo Line loop performs CreditMemoVATPostingSetup.Get for every line. This creates an N+1 lookup pattern; cache each distinct VAT posting-group pair or restructure the lookup so the posting setups are loaded once per distinct key before processing the lines.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.51.6

SalesInvoiceLine.SetLoadFields(Type, "VAT Bus. Posting Group", "VAT Prod. Posting Group");
if SalesInvoiceLine.FindSet() then
repeat
if InvoiceVATPostingSetup.Get(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟠\ High\ Severity\ —\ Performance}$

The unbounded Sales Invoice Line loop performs InvoiceVATPostingSetup.Get for every line. This creates an N+1 lookup pattern; cache each distinct VAT posting-group pair or restructure the lookup so the posting setups are loaded once per distinct key before processing the lines.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.51.6

This branch was previously deployed

1 inactive deployment
triage — 1137c21f Deployed Oct 31, 2026 by AndersLarsenMicrosoft via Classify team ownership #9652
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Team: Finance GitHub request for Finance area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants