Extract IT withholding tax code - #9185
Conversation
Copilot PR ReviewIteration 7 · Outcome: completed Knowledge source: https://github.com/microsoft/BCQuality@822cae1b2771ac25f665f73369f69093bd4fd630 Findings by domainFindings split into Knowledge-backed (cite a BCQuality article) and Agent (the agent's own judgement, no matching BCQuality rule).
Totals: 13 knowledge-backed · 1 agent findings. Orchestrator pre-filter (13 file(s) excluded)
Findings produced by the Copilot CLI agent against BCQuality at |
| #endif | ||
| end; | ||
|
|
||
| #if not CLREAN29 |
There was a problem hiding this comment.
The obsoleted procedure 'CheckWithholdTax' in Gen.
Jnl.-Post Line is guarded by '#if not CLREAN29' — the compiler symbol is misspelled ('CLREAN29' instead of 'CLEAN29'). Every other obsolete-removal block introduced in this same PR (in this file and in PurchPost.Codeunit.al) correctly uses '#if not CLEAN29'. Because 'CLREAN29' is never a real build symbol, 'not CLREAN29' is always true, so this block will never be compiled out — not even in a CLEAN29 build — defeating the staged-removal mechanic the referenced guidance describes ('the standard mechanic for retiring the actual implementation body is to remove the #if not CLEAN block in the same release that flips the state to Removed'). The obsolete wrapper will silently survive indefinitely alongside its now-duplicated logic in 'WHT Gen. Jnl.-Post Line IT'.
| #if not CLREAN29 | |
| #if not CLEAN29 |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| Caption = 'Contribution'; | ||
| Image = "Report"; | ||
| RunObject = Report Contribution; | ||
| ToolTip = 'Get a report of social security and workers´Š¢ compensation contribution taxes on non-inventory services that you have purchased from an independent contractor or consultant.'; |
There was a problem hiding this comment.
Two role-center tooltips in this page extension contain mojibake (workers´Š¢ compensation) instead of readable text, so users will see corrupted UI copy.
Replace the corrupted characters in both tooltips with a normal apostrophe or typographic apostrophe (workers' compensation / workers' compensation).
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| codeunit 12111 "WHT Gen. Journal Line IT" | ||
| { | ||
|
|
||
| [EventSubscriber(ObjectType::Table, Database::"Gen. Journal Line", 'OnAccountNoOnValidateOnBeforeCreateDim', '', true, false)] |
There was a problem hiding this comment.
The new Gen.
Journal Line subscribers for Account No. and Document Date immediately delegate to DeleteTmpWithhSocSec/UpdateTmpWithholdingContribution, which read the persistent Tmp Withholding Contribution table on every validation. This matches the anti-pattern of doing database work in frequently-fired subscribers without a cheap in-memory guard; add a fast exit so only lines that can actually have withholding state touch the table.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| } | ||
|
|
||
| var | ||
| Text12100: Label 'You cannot create the withhold entry from entry %1 because it''s an %2 Document.'; |
There was a problem hiding this comment.
Label Text12100 has two placeholders (%1, %2) but no Comment explaining them.
Translators cannot infer from the text alone that %1 is the entry number and %2 is the document type, so the label should document both placeholders explicitly.
| Text12100: Label 'You cannot create the withhold entry from entry %1 because it''s an %2 Document.'; | |
| Text12100: Label 'You cannot create the withhold entry from entry %1 because it''s an %2 Document.', Comment = '%1 = Entry No., %2 = Document Type'; |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
This PR deletes WHT-backed fields directly from existing base tables and reintroduces them in tableextensions (for example Vendor, Vendor Templ., and Gen.Journal Line) with no Pending deprecation window. That is an immediate contract break for dependent extensions that still compile against the base-table symbols; per the referenced guidance, these fields need a staged Pending → Removed lifecycle instead of disappearing in one release. Notably, other parts of this same PR (e.g. procedures in GenJnlPostLine.Codeunit.al and PurchPost.Codeunit.al) correctly wrap the moved logic in Knowledge:
Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why |
The move also removes public base-object entry points outright (
|
| end; | ||
|
|
||
| [EventSubscriber(ObjectType::Codeunit, Codeunit::"Gen. Jnl.-Post Line", 'OnPrepareTempVendLedgEntryOnBeforeCheckAgainstApplnCurrency', '', true, false)] | ||
| local procedure OnPrepareTempVendLedgEntryOnBeforeCheckAgainstApplnCurrency(GenJournalLine: Record "Gen. Journal Line"; OldVendorLedgerEntry: Record "Vendor Ledger Entry") |
There was a problem hiding this comment.
This subscriber does not copy the publisher signature exactly.
OnPrepareTempVendLedgEntryOnBeforeCheckAgainstApplnCurrency is published with (GenJournalLine, NewCVLedgerEntryBuffer, OldVendorLedgerEntry), but the subscriber skips the middle parameter and makes its second parameter OldVendorLedgerEntry. For event subscribers, the parameter list must match the publisher order; skipping a non-trailing parameter prevents the subscriber from binding/compiling.
| local procedure OnPrepareTempVendLedgEntryOnBeforeCheckAgainstApplnCurrency(GenJournalLine: Record "Gen. Journal Line"; OldVendorLedgerEntry: Record "Vendor Ledger Entry") | |
| local procedure OnPrepareTempVendLedgEntryOnBeforeCheckAgainstApplnCurrency(GenJournalLine: Record "Gen. Journal Line"; NewCVLedgerEntryBuffer: Record "CV Ledger Entry Buffer"; OldVendorLedgerEntry: Record "Vendor Ledger Entry") |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| codeunit 12138 "WHT Gen. Jnl.-Post Line IT" | ||
| { | ||
| var | ||
| Text1130023: Label 'Because this invoice includes Withholding Tax, it should not be applied directly. Please use the function Payment Journals -> Payments -> Withh.Tax-Soc.Sec.'; |
There was a problem hiding this comment.
Text1130023 is passed to Error() in this codeunit, but its name has no approved suffix.
Per AA0074, error labels should use an Err suffix so the call-site contract is visible from the identifier.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| } | ||
|
|
||
| var | ||
| Text12100: Label 'You cannot create the withhold entry from entry %1 because it''s an %2 Document.'; |
There was a problem hiding this comment.
Text12100 is passed to Error() from this page extension, but its name has no approved suffix.
Per AA0074, error labels should use an Err suffix instead of a generic Text#### identifier.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| [EventSubscriber(ObjectType::Codeunit, Codeunit::"Purch.-Post", 'OnBeforeCheckPostRestrictions', '', true, false)] | ||
| local procedure OnBeforeCheckPostRestrictions(var PurchaseHeader: Record "Purchase Header"; var IsHandled: Boolean) | ||
| begin | ||
| CheckWithholdingTaxTotalAmount(PurchaseHeader); |
There was a problem hiding this comment.
This codeunit calls its own procedures as bare identifiers (CheckWithholdingTaxTotalAmount, PostWithhSocSec, GetCompWithhTaxTotalAmount) instead of this.<procedure>(...).
The this prefix is the BC style convention for explicit self-reference inside codeunits.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
Agentic PR Review - Round 1Recommendation: Request ChangesWhat this PR doesThis PR moves the Italian withholding tax customization out of base objects and into WHT-prefixed table, page, and codeunit extensions. It also adds BaseApp events so the new subscribers can run in the old posting and validation paths. The extraction is a coherent feature increment and follows the same broad direction as the NL TrMode and ES Cartera extractions. The new event publishers are present in the in-repo IT BaseApp changes, and the main posting subscribers map back to the removed code paths. The PR is not ready because required checks fail, the work item link is missing, and the field/API move is not proven upgrade-safe. SuggestionsS1 - Make the IT app builds pass S2 - Link the ADO work item S3 - Make the field move upgrade-safe S4 - Add a withholding tax regression test Risk assessment and necessityRisk: This touches vendor master data, general journal lines, purchase posting, payment journals, role centers, permissions, and withholding tax posting. A wrong event point or missing upgrade step can change tax amounts, lose WHT field data, or break dependent extensions. The failing IT builds are direct evidence that the extraction is incomplete. Necessity: Extracting the IT withholding tax customization is a valid direction and matches the NL/ES extraction pattern. The scope is still too risky to merge until the work item is linked, required checks pass, public symbols/data are protected, and a focused WHT posting regression test exists.
|
| var | ||
| ComputedWithholdingTax: Record "Computed Withholding Tax"; | ||
| [SecurityFiltering(SecurityFilter::Filtered)] | ||
| WithholdingTax: Record "Withholding Tax"; |
There was a problem hiding this comment.
In the extracted codeunit 'WHT Navigate Handler IT', the variable ComputedWithholdingTax: Record "Computed Withholding Tax" no longer carries [SecurityFiltering(SecurityFilter::Filtered)], while the sibling WithholdingTax variable in the same var block still does.
The original code this was extracted from (src/Layers/IT/BaseApp/Local/Foundation/Navigate/LocalNavigateHandler.Codeunit.al, pre-PR) applied [SecurityFiltering(SecurityFilter::Filtered)] to both variables. Dropping the attribute on ComputedWithholdingTax means the Navigate page's count/lookup against that table will no longer apply the record-level security filter, which can let a user without permission on filtered records see or count rows outside their allowed scope. Impact would normally warrant 'major', but per agent-finding severity rules it is capped at 'minor' here since no dedicated knowledge article backs the SecurityFiltering attribute pattern yet; this should be promoted to a knowledge-backed rule.
Recommendation:
- restore the attribute —
[SecurityFiltering(SecurityFilter::Filtered)]immediately before theComputedWithholdingTax: Record "Computed Withholding Tax";declaration.
| var | |
| ComputedWithholdingTax: Record "Computed Withholding Tax"; | |
| [SecurityFiltering(SecurityFilter::Filtered)] | |
| WithholdingTax: Record "Withholding Tax"; | |
| var | |
| [SecurityFiltering(SecurityFilter::Filtered)] | |
| ComputedWithholdingTax: Record "Computed Withholding Tax"; | |
| [SecurityFiltering(SecurityFilter::Filtered)] | |
| WithholdingTax: Record "Withholding Tax"; |
Agent judgement — not directly backed by a BCQuality knowledge article.
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| end; | ||
|
|
||
| [EventSubscriber(ObjectType::Table, Database::"Purchase Header", 'OnBeforeShowPostedDocsToPrintCreatedMsg', '', true, false)] | ||
| local procedure OnBeforeShowPostedDocsToPrintCreatedMsg(var PurchaseHeader: Record "Purchase Header") |
There was a problem hiding this comment.
The event subscriber OnBeforeShowPostedDocsToPrintCreatedMsg in the new codeunit 'WHT Purchase Header IT' declares only one parameter, var PurchaseHeader: Record "Purchase Header", but the publisher in Purchase Header (src/Layers/IT/BaseApp/Purchases/Document/PurchaseHeader.Table.al, line 9381) declares (var ShowPostedDocsToPrint: Boolean; HideValidationDialog: Boolean; var PurchaseHeader: Record "Purchase Header").
AL binds event subscribers positionally against the publisher's leading parameters; a subscriber may omit trailing parameters but its declared parameters must match the publisher's from the first one onward. Here the subscriber's sole parameter is type Record where the publisher's first parameter is Boolean, so the signatures do not align and the subscriber will not bind/compile correctly. Fix by reproducing the publisher's full parameter list (or at least its leading Boolean, Boolean parameters) before the Record parameter, e.g. (var ShowPostedDocsToPrint: Boolean; HideValidationDialog: Boolean; var PurchaseHeader: Record "Purchase Header").
Suggested fix (apply manually — could not be anchored as a one-click suggestion):
[EventSubscriber(ObjectType::Table, Database::"Purchase Header", 'OnBeforeShowPostedDocsToPrintCreatedMsg', '', true, false)]
local procedure OnBeforeShowPostedDocsToPrintCreatedMsg(var ShowPostedDocsToPrint: Boolean; HideValidationDialog: Boolean; var PurchaseHeader: Record "Purchase Header")Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| using Microsoft.Foundation.Address; | ||
| using Microsoft.Utilities; | ||
|
|
||
| tableextension 12201 "WHT VEndor IT" extends Vendor |
There was a problem hiding this comment.
The new table extension is named "WHT VEndor IT" (internal object name) — the 'E' in 'VEndor' is capitalized, a clear spelling typo of 'Vendor'.
It doesn't break compilation, but it is inconsistent with every sibling object in this PR (WHT Vendor Card IT, WHT Vendor Templ IT, WHT Vendor IT codeunit) and will look wrong in object lists, telemetry, and future greps for 'Vendor'. Recommend renaming to "WHT Vendor IT" for consistency before merge.
| tableextension 12201 "WHT VEndor IT" extends Vendor | |
| tableextension 12201 "WHT Vendor IT" extends Vendor |
Agent judgement — not directly backed by a BCQuality knowledge article.
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
Agentic PR Review - Round 2Recommendation: Request ChangesWhat this PR doesThis PR extracts the Italian withholding tax code from base objects into WHT-prefixed object extensions. Since round 1, the new commit moves more bank payment, navigate, purchase, and withholding references into the WHT area. The round-2 changes are not enough. The IT Default and Clean builds still fail, the PR body still has no Status of previous suggestions
New observations (commits since round 1)S5 - Preserve manual WHT code overrides Risk assessment and necessityRisk: This is still high risk. The PR touches vendor master data, general journal lines, purchase posting, manual vendor payments, role centers, permissions, and withholding tax posting. The current failing IT builds prove the extraction is incomplete, and the unresolved field move can still break upgrade or dependent extensions. Necessity: Extracting the IT withholding tax customization is still a valid direction. It should not merge until the required checks pass, the work item is linked, the field move is made upgrade-safe or proven safe, focused WHT regression coverage exists, and the manual payment WHT values are preserved.
|
| { | ||
| fields | ||
| { | ||
| field(12101; "Fiscal Code"; Code[20]) |
There was a problem hiding this comment.
This PR deletes persisted WHT fields 12101, 12130, 12131, and 12133-12138 from table 81 and recreates them in tableextension 12200.
Reusing the field numbers does not migrate stored values into extension storage, so existing Gen. Journal Line data will be lost on upgrade unless the old fields are staged through obsoletion and a Subtype = Upgrade migration copies the data before final removal.
Knowledge:
- microsoft/knowledge/upgrade/obsolete-pending-to-removed-staging.md
- microsoft/knowledge/upgrade/obsoletion-requires-reason-and-tag.md
- microsoft/knowledge/upgrade/upgrade-codeunit-subtype.md
- microsoft/knowledge/upgrade/datatransfer-for-bulk-init.md
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| { | ||
| fields | ||
| { | ||
| field(12101; "Fiscal Code"; Code[20]) |
There was a problem hiding this comment.
This PR removes Vendor fields 12101-12122, 12126-12131, and 12184-12185 from table 23 and redefines them in tableextension 12201.
That is a schema move to new storage with no Pending obsoletion metadata on the old fields and no upgrade codeunit to backfill the new extension fields, so existing vendor WHT data will come up blank after upgrade.
Knowledge:
- microsoft/knowledge/upgrade/obsolete-pending-to-removed-staging.md
- microsoft/knowledge/upgrade/obsoletion-requires-reason-and-tag.md
- microsoft/knowledge/upgrade/upgrade-codeunit-subtype.md
- microsoft/knowledge/upgrade/datatransfer-for-bulk-init.md
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| { | ||
| fields | ||
| { | ||
| field(12101; "Fiscal Code"; Code[20]) |
There was a problem hiding this comment.
This PR removes Vendor Templ.
fields 12101-12120, 12122, and 12126-12131 from the base table and recreates them in tableextension 12202. Existing template records do not get copied into extension storage automatically, and the diff adds neither obsoletion metadata nor any Subtype = Upgrade/DataTransfer migration, so WHT defaults stored in vendor templates will be stranded on upgrade.
Knowledge:
- microsoft/knowledge/upgrade/obsolete-pending-to-removed-staging.md
- microsoft/knowledge/upgrade/obsoletion-requires-reason-and-tag.md
- microsoft/knowledge/upgrade/upgrade-codeunit-subtype.md
- microsoft/knowledge/upgrade/datatransfer-for-bulk-init.md
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
Agentic PR Review - Round 3Recommendation: Request ChangesWhat this PR doesThis PR extracts the Italian withholding tax code from base objects into WHT-prefixed object extensions. Since round 2, commit Those changes look like build-error cleanup, but the PR is still not ready. The IT Default and Clean build jobs are still Status of previous suggestions
New observations (commits since round 2)None - commit Risk assessment and necessityRisk: This is still high risk. The PR touches vendor master data, general journal lines, purchase posting, manual vendor payments, permissions, role centers, and withholding tax posting. The field move and manual payment behavior can affect upgrade, dependent extensions, and financially sensitive WHT values. Necessity: Extracting the IT withholding tax customization is still a valid direction. It should not merge until the required checks pass, the work item is linked, the field move has an upgrade-safe path or clear proof, focused WHT regression coverage exists, and manual payment WHT values are preserved.
|
| { | ||
| addafter("Vendor Sheet - Print") | ||
| { | ||
| action("Withholding Taxes") |
There was a problem hiding this comment.
The new WHT Finance Manager role-center extension re-adds six withholding-tax actions without any ToolTip properties (Withholding Taxes, Contribution, Summary Withholding Payment, Compensation Details, Certifications, and Withhold Tax Code).
That leaves the new commands without hover/help text in the final UI after this refactor; add action-specific ToolTip text to each action before merge.
Agent judgement — not directly backed by a BCQuality knowledge article.
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| field(12117; "Country of Fiscal Domicile"; Code[10]) | ||
| { | ||
| Caption = 'Country/Region of Fiscal Domicile'; | ||
| DataClassification = EndUserIdentifiableInformation; |
There was a problem hiding this comment.
WHTVendorTemplIT.TableExt classifies "Contribution Fiscal Code" as CustomerContent, but the field stores a fiscal/tax code and is therefore direct end-user identifying data.
That under-classifies this moved field versus the corresponding Vendor field and can make GDPR/data-classification surfaces treat a tax identifier as generic customer content. Classify it as EndUserIdentifiableInformation instead.
| DataClassification = EndUserIdentifiableInformation; | |
| DataClassification = EndUserIdentifiableInformation; |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
The new Labels
|
|
The new page-scoped Labels
|
Agentic PR Review - Round 4Recommendation: Request ChangesWhat this PR doesThis PR extracts the Italian withholding tax code from base objects into WHT-prefixed object extensions. Since round 3, commit Those changes are still not enough. The current Status of previous suggestions
New observations (commits since round 3)None - commit Risk assessment and necessityRisk: This is still high risk. The PR touches vendor master data, general journal lines, purchase posting, manual vendor payments, permissions, role centers, and withholding tax posting. The failed IT builds prove the extraction is still incomplete, and the unresolved field move and manual payment behavior can affect upgrade, dependent extensions, and financially sensitive WHT values. Necessity: Extracting the IT withholding tax customization is still a valid direction. It should not merge until the required checks pass, the work item is linked, the field move has an upgrade-safe path or clear proof, focused WHT regression coverage exists, and manual payment WHT values are preserved.
|
This new card page adds field controls without explicit Caption properties and relies on inherited table captions instead.The caption rule expects page fields to declare their own user-facing labels so translation and page-specific wording do not depend on table metadata. Knowledge: Posting this finding as an issue comment because inline comment placement failed. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why |
| { | ||
| addafter("Last Date Modified") | ||
| { | ||
| field("Fiscal Code"; Rec."Fiscal Code") |
There was a problem hiding this comment.
The extension reintroduces a large block of Vendor Card fields without explicit Caption properties.
That leaves the UI dependent on table captions, and aliases such as First Name2/Last Name2 especially need deliberate page captions rather than inherited metadata.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| field(12109; "Date of Birth"; Date) | ||
| { | ||
| Caption = 'Date of Birth'; | ||
| DataClassification = CustomerContent; |
There was a problem hiding this comment.
The extracted Vendor field "Date of Birth" is classified as CustomerContent, but it stores directly identifying personal data.
Per the referenced guidance, table fields holding personal data should use the classification that matches the stored data; this field should be classified as EndUserIdentifiableInformation.
| DataClassification = CustomerContent; | |
| DataClassification = EndUserIdentifiableInformation; |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| Caption = 'Date of Birth'; | ||
| DataClassification = EndUserIdentifiableInformation; | ||
| } | ||
| field(12110; "Birth City"; Text[30]) |
There was a problem hiding this comment.
The extracted vendor-template fields "Birth City", "Birth Post Code", "Residence Post Code", and "Residence City" disable TableRelation validation with ValidateTableRelation = false but do not add any replacement OnValidate existence checks.
Because Vendor Template data is user-editable setup, this allows invalid postcode/city references to be stored and later propagated into vendors.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
The extracted table introduces
|
The label
|
The new page-level labels
|
| codeunit 12138 "WHT Gen. Jnl.-Post Line IT" | ||
| { | ||
| var | ||
| Text1130023: Label 'Because this invoice includes Withholding Tax, it should not be applied directly. Please use the function Payment Journals -> Payments -> Withh.Tax-Soc.Sec.'; |
There was a problem hiding this comment.
The new codeunit declares Text1130023 and uses it as the format string for Error(...).
That should be renamed with an approved Err suffix so the label's intended usage is visible and AA0074 does not flag it.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| using Microsoft.Foundation.Address; | ||
| using Microsoft.Utilities; | ||
|
|
||
| tableextension 12201 "WHT VEndor IT" extends Vendor |
There was a problem hiding this comment.
This refactor removes persisted WHT data fields from live tables (Vendor, Vendor Templ., Gen.
Journal Line, Vendor Bill Line, Purchase Header — same field-number pattern repeats across all of them) and reintroduces them with identical field numbers inside new table extensions, but the PR adds no Subtype = Upgrade codeunit, no OnUpgrade... trigger, and no DataTransfer/upgrade-tag migration path. Table-extension fields are physically stored in a separate companion SQL table from the base table, so keeping the same field number does not preserve existing customer data when storage moves from the base table to extension storage — upgraded tenants will come up with empty/default values in the new WHT fields unless explicit upgrade logic copies the old data.
Knowledge:
- microsoft/knowledge/upgrade/upgrade-codeunit-subtype.md
- microsoft/knowledge/upgrade/datatransfer-for-bulk-init.md
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
Agentic PR Review - Round 5Recommendation: Request ChangesWhat this PR doesThis PR extracts Italian withholding tax code from base objects into WHT-prefixed object extensions. Since round 4, commit The current head is still not ready. Status of previous suggestions
New observations (commits since round 4)S6 - Keep Social Security action in extension Risk assessment and necessityRisk: This remains high risk. The PR touches vendor data, general journal lines, purchase posting, manual vendor payments, permissions, role centers, and withholding tax posting. The failed IT builds prove the extraction is incomplete, and the unresolved upgrade and manual payment issues can affect financially sensitive WHT values. Necessity: Extracting the IT withholding tax customization is still a valid goal. It should not merge until the IT checks pass, the work item is linked, the field move is upgrade-safe, focused WHT regression coverage exists, and manual payment WHT values are preserved.
|
What & why
Linked work
Fixes AB#641996
How I validated this
What I tested and the outcome (required — be specific: scenarios, commands, screenshots for UI changes)
Risk & compatibility