From 0d6049fb5376e62954e0ccc7edd5a742c7df24fd Mon Sep 17 00:00:00 2001 From: Neelesh Kumar Singhal Date: Tue, 30 Jun 2026 23:22:17 +0530 Subject: [PATCH 1/9] Fix and Automation --- .../Sales/Customer/CustomerCard.Page.al | 3 +- .../ERM/ERMCustomerStatistics.Codeunit.al | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al index a80df697cc..c78e901d6d 100644 --- a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2389,6 +2389,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2440,8 +2441,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al index 26b7019b52..282a6a4020 100644 --- a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al @@ -293,6 +293,40 @@ codeunit 134389 "ERM Customer Statistics" Assert.AreEqual(Round(InvoiceAmountLCY), Customer.CalcOverdueBalance(), OverDueBalanceErr); end; + [Test] + procedure OverdueBalanceUsesWorkDateWhenCustomerCardOpenedWithExistingDateFilter() + var + Customer: Record Customer; + CustomerCard: TestPage "Customer Card"; + OverdueAmount: Decimal; + NotOverdueAmount: Decimal; + begin + // [FEATURE] [UI] [Overdue Balance] + // [SCENARIO 638790] Overdue Balance (LCY) on Customer Card uses 0D..WORKDATE even when the page is opened from a document or journal that already applied a "Date Filter". + Initialize(); + + // [GIVEN] Customer with two posted sales invoices. + LibrarySales.CreateCustomer(Customer); + // [GIVEN] Invoice "A" is overdue: Due Date < WORKDATE, Amount = "X". + OverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", CalcDate('<-2M>', WorkDate()), CalcDate('<-1M>', WorkDate())); + // [GIVEN] Invoice "B" is not yet due: Due Date > WORKDATE, Amount = "Y". + NotOverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", WorkDate(), CalcDate('<2M>', WorkDate())); + + // [GIVEN] Customer Card is opened on the customer. + CustomerCard.OpenView(); + CustomerCard.GotoRecord(Customer); + + // [WHEN] A "Date Filter" covering both due dates is applied to the record, simulating opening the card from a document or journal. + CustomerCard.FILTER.SetFilter("Date Filter", Format(CalcDate('<3M>', WorkDate()))); + + // [THEN] Overdue Balance (LCY) shows only the overdue invoice amount "X". + CustomerCard."Balance Due (LCY)".AssertEquals(OverdueAmount); + // [THEN] Balance (LCY) shows the total of both invoices "X" + "Y". + CustomerCard."Balance (LCY)".AssertEquals(OverdueAmount + NotOverdueAmount); + + CustomerCard.Close(); + end; + [Test] [Scope('OnPrem')] procedure UTCheckEmptyBilltoCustomer() @@ -1242,6 +1276,21 @@ codeunit 134389 "ERM Customer Statistics" exit(SalesHeader."Amount Including VAT"); end; + local procedure CreateAndPostInvoiceWithDueDate(CustomerNo: Code[20]; PostingDate: Date; DueDate: Date): Decimal + var + SalesHeader: Record "Sales Header"; + SalesLine: Record "Sales Line"; + begin + CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Invoice, CustomerNo, PostingDate); + SalesHeader.Validate("Due Date", DueDate); + SalesHeader.Modify(true); + LibrarySales.CreateSalesLine( + SalesLine, SalesHeader, SalesLine.Type::Item, CreateItemWithUnitPrice(), LibraryRandom.RandDec(10, 2)); + SalesHeader.CalcFields("Amount Including VAT"); + LibrarySales.PostSalesDocument(SalesHeader, true, true); + exit(SalesHeader."Amount Including VAT"); + end; + local procedure CreateAndPostSalesDocument(CustomerNo: Code[20]; CurrencyCode: Code[10]): Decimal var SalesHeader: Record "Sales Header"; From f9c3ae5a467daa055b07c2cedce7a6c99c7e9aa1 Mon Sep 17 00:00:00 2001 From: Neelesh Kumar Singhal Date: Thu, 2 Jul 2026 17:28:31 +0530 Subject: [PATCH 2/9] test commit --- src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al index c78e901d6d..5ea24c7f2a 100644 --- a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2413,6 +2413,7 @@ page 21 "Customer Card" var ApplicationAreaMgmtFacade: Codeunit "Application Area Mgmt. Facade"; begin + // Set the default country code to '*' to ensure that the country code is not filtered by default when the page is opened. This allows for a more flexible view of customer records without being restricted to a specific country. PrevCountryCode := '*'; FoundationOnly := ApplicationAreaMgmtFacade.IsFoundationEnabled(); From df3a4cdc482cae7a4b50672a7943f0748daba484 Mon Sep 17 00:00:00 2001 From: v-nesinghal Date: Fri, 3 Jul 2026 18:24:59 +0530 Subject: [PATCH 3/9] Miapp --- src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al | 3 +-- 10 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al index 6fe594e412..6e9f0b274c 100644 --- a/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2459,6 +2459,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2510,8 +2511,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al index da61a60c5e..3f40ee0abb 100644 --- a/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2413,6 +2413,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2464,8 +2465,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al index 2580cd9a73..9ba8e34c68 100644 --- a/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2451,6 +2451,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2502,8 +2503,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al index 6514fbfb7b..1494890df1 100644 --- a/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2457,6 +2457,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2508,8 +2509,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al index 93d63aee9c..27394f139a 100644 --- a/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2447,6 +2447,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2501,8 +2502,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al index fe12742e22..e0dd66e501 100644 --- a/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2541,6 +2541,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2592,8 +2593,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al index 3c45633ae7..ef99770223 100644 --- a/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2558,6 +2558,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2609,8 +2610,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al index 228ccd9a9c..08ed3cc9ae 100644 --- a/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2403,6 +2403,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2454,8 +2455,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al index 43c879be66..4830a1d307 100644 --- a/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2419,6 +2419,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2470,8 +2471,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else diff --git a/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al index 8fafeea501..556e07c534 100644 --- a/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2529,6 +2529,7 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); + Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2584,8 +2585,6 @@ page 21 "Customer Card" begin OnBeforeOnOpenPage(Rec); - if Rec.GetFilter("Date Filter") = '' then - Rec.SetRange("Date Filter", 0D, WorkDate()); if GuiAllowed() then OnOpenPageFunc() else From d4c04d17cb88f721e51a807e442fb5e2eab5153f Mon Sep 17 00:00:00 2001 From: v-nesinghal Date: Fri, 3 Jul 2026 18:28:46 +0530 Subject: [PATCH 4/9] Remove test commit --- src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al index 5ea24c7f2a..c78e901d6d 100644 --- a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2413,7 +2413,6 @@ page 21 "Customer Card" var ApplicationAreaMgmtFacade: Codeunit "Application Area Mgmt. Facade"; begin - // Set the default country code to '*' to ensure that the country code is not filtered by default when the page is opened. This allows for a more flexible view of customer records without being restricted to a specific country. PrevCountryCode := '*'; FoundationOnly := ApplicationAreaMgmtFacade.IsFoundationEnabled(); From 5ec8e30087280b206e4920384e07ce3e40bedd03 Mon Sep 17 00:00:00 2001 From: v-nesinghal Date: Wed, 8 Jul 2026 18:57:15 +0530 Subject: [PATCH 5/9] Suggestion Changes --- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 6 +- .../Sales/Customer/CustomerCard.Page.al | 7 +- .../ERM/ERMCustomerStatistics.Codeunit.al | 80 +++++++++++-------- 12 files changed, 101 insertions(+), 46 deletions(-) diff --git a/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al index 6e9f0b274c..90cbb2a965 100644 --- a/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2452,6 +2452,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2513,8 +2514,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al index 3f40ee0abb..aa15eca34c 100644 --- a/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2406,6 +2406,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2467,8 +2468,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al index 9ba8e34c68..ded18c0d37 100644 --- a/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2444,6 +2444,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2505,8 +2506,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al index 1494890df1..c62cdd2fee 100644 --- a/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2450,6 +2450,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2511,8 +2512,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al index 27394f139a..46670f12c0 100644 --- a/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2440,6 +2440,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2504,8 +2505,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al index e0dd66e501..8473ed7198 100644 --- a/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2534,6 +2534,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2595,8 +2596,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al index ef99770223..1c62670504 100644 --- a/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2551,6 +2551,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2612,8 +2613,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al index 08ed3cc9ae..348b11fde9 100644 --- a/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2396,6 +2396,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2457,8 +2458,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al index 4830a1d307..dcebc13335 100644 --- a/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2412,6 +2412,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2473,8 +2474,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al index 556e07c534..24cde19595 100644 --- a/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2522,6 +2522,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2587,8 +2588,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al index c78e901d6d..25eace6196 100644 --- a/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/W1/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2382,6 +2382,7 @@ page 21 "Customer Card" CRMCouplingManagement: Codeunit "CRM Coupling Management"; WorkflowWebhookManagement: Codeunit "Workflow Webhook Management"; begin + Rec.SetRange("Date Filter", 0D, WorkDate()); if NewMode then CreateCustomerFromTemplate() else @@ -2389,7 +2390,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then @@ -2443,8 +2443,11 @@ page 21 "Customer Card" if GuiAllowed() then OnOpenPageFunc() - else + else begin + if Rec.GetFilter("Date Filter") = '' then + Rec.SetRange("Date Filter", 0D, WorkDate()); OnOpenBackground(); + end; OnAfterOnOpenPage(Rec, xRec); end; diff --git a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al index 282a6a4020..6f02eabf4c 100644 --- a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al @@ -293,40 +293,6 @@ codeunit 134389 "ERM Customer Statistics" Assert.AreEqual(Round(InvoiceAmountLCY), Customer.CalcOverdueBalance(), OverDueBalanceErr); end; - [Test] - procedure OverdueBalanceUsesWorkDateWhenCustomerCardOpenedWithExistingDateFilter() - var - Customer: Record Customer; - CustomerCard: TestPage "Customer Card"; - OverdueAmount: Decimal; - NotOverdueAmount: Decimal; - begin - // [FEATURE] [UI] [Overdue Balance] - // [SCENARIO 638790] Overdue Balance (LCY) on Customer Card uses 0D..WORKDATE even when the page is opened from a document or journal that already applied a "Date Filter". - Initialize(); - - // [GIVEN] Customer with two posted sales invoices. - LibrarySales.CreateCustomer(Customer); - // [GIVEN] Invoice "A" is overdue: Due Date < WORKDATE, Amount = "X". - OverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", CalcDate('<-2M>', WorkDate()), CalcDate('<-1M>', WorkDate())); - // [GIVEN] Invoice "B" is not yet due: Due Date > WORKDATE, Amount = "Y". - NotOverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", WorkDate(), CalcDate('<2M>', WorkDate())); - - // [GIVEN] Customer Card is opened on the customer. - CustomerCard.OpenView(); - CustomerCard.GotoRecord(Customer); - - // [WHEN] A "Date Filter" covering both due dates is applied to the record, simulating opening the card from a document or journal. - CustomerCard.FILTER.SetFilter("Date Filter", Format(CalcDate('<3M>', WorkDate()))); - - // [THEN] Overdue Balance (LCY) shows only the overdue invoice amount "X". - CustomerCard."Balance Due (LCY)".AssertEquals(OverdueAmount); - // [THEN] Balance (LCY) shows the total of both invoices "X" + "Y". - CustomerCard."Balance (LCY)".AssertEquals(OverdueAmount + NotOverdueAmount); - - CustomerCard.Close(); - end; - [Test] [Scope('OnPrem')] procedure UTCheckEmptyBilltoCustomer() @@ -1153,6 +1119,52 @@ codeunit 134389 "ERM Customer Statistics" Assert.AreEqual(CustomerStatistics.GetTotalAmountLCY.AsDecimal(), Customer.GetTotalAmountLCY(), CustomerCardFactboxTotalErr); end; + + [Test] + procedure OverdueBalanceIsolatedFromLeakedWideDateFilterOnCustomer() + var + Customer: Record Customer; + EarliestDate: Date; + LatestDate: Date; + OverdueAmount: Decimal; + NotOverdueAmount: Decimal; + begin + // [FEATURE] [Overdue Balance] [Cue] + // [SCENARIO 640988] Both Customer.CalcOverdueBalance (used by the Customer Card background calculation that feeds the overdue payments cue) and the "Balance Due (LCY)" FlowField (which the card evaluates after resetting the Date Filter to 0D..WORKDATE in OnAfterGetCurrRecord) return only overdue amounts, even when a wider "Date Filter" is inherited on the Customer record from a document or journal. + Initialize(); + + // [GIVEN] Reference dates that bracket both WORKDATE and Today so the fixture is deterministic regardless of their relative order. + if WorkDate() < Today() then begin + EarliestDate := WorkDate(); + LatestDate := Today(); + end else begin + EarliestDate := Today(); + LatestDate := WorkDate(); + end; + + // [GIVEN] Create customer with two posted sales invoices. + LibrarySales.CreateCustomer(Customer); + // [GIVEN] CreateInvoice "A" is overdue against both WORKDATE and Today: Due Date < min(WORKDATE, Today), Amount = "X". + OverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", CalcDate('<-2M>', EarliestDate), CalcDate('<-1M>', EarliestDate)); + // [GIVEN] Create Invoice "B" is not yet due against either WORKDATE or Today: Due Date > max(WORKDATE, Today), Amount = "Y". + NotOverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", WorkDate(), CalcDate('<2M>', LatestDate)); + + // [GIVEN] A wider "Date Filter" is applied on the Customer record, simulating one inherited from a document or journal and captured by StartBackgroundCalculations before any reset. + Customer.SetFilter("Date Filter", '..%1', CalcDate('<3M>', LatestDate)); + + // [WHEN] CalcOverdueBalance is called on the Customer (the same call the background task makes after Customer.SetView). + Assert.AreEqual(Round(OverdueAmount), Customer.CalcOverdueBalance(), OverDueBalanceErr); + + // [WHEN] The Customer Card's OnAfterGetCurrRecord unconditionally resets the "Date Filter" to 0D..WORKDATE. + Customer.SetRange("Date Filter", 0D, WorkDate()); + + // [THEN] Verify "Balance Due (LCY)" sums only the overdue invoice amount. + Customer.CalcFields("Balance Due (LCY)", "Balance (LCY)"); + Assert.AreEqual(OverdueAmount, Customer."Balance Due (LCY)", OverDueBalanceErr); + // [THEN] Verify "Balance (LCY)" sums both invoice amounts. + Assert.AreEqual(OverdueAmount + NotOverdueAmount, Customer."Balance (LCY)", 'Balance (LCY) should include both invoices.'); + end; + local procedure Initialize() var Currency: Record Currency; From 17417f1cfd8bb2997665f13c2d3c214643df8800 Mon Sep 17 00:00:00 2001 From: v-nesinghal Date: Thu, 9 Jul 2026 03:32:46 +0530 Subject: [PATCH 6/9] Correction test automation --- .../ERM/ERMCustomerStatistics.Codeunit.al | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al index 6f02eabf4c..04e633b58b 100644 --- a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al @@ -1124,13 +1124,14 @@ codeunit 134389 "ERM Customer Statistics" procedure OverdueBalanceIsolatedFromLeakedWideDateFilterOnCustomer() var Customer: Record Customer; + CustomerCard: TestPage "Customer Card"; EarliestDate: Date; LatestDate: Date; OverdueAmount: Decimal; NotOverdueAmount: Decimal; begin // [FEATURE] [Overdue Balance] [Cue] - // [SCENARIO 640988] Both Customer.CalcOverdueBalance (used by the Customer Card background calculation that feeds the overdue payments cue) and the "Balance Due (LCY)" FlowField (which the card evaluates after resetting the Date Filter to 0D..WORKDATE in OnAfterGetCurrRecord) return only overdue amounts, even when a wider "Date Filter" is inherited on the Customer record from a document or journal. + // [SCENARIO 640988] Both Customer.CalcOverdueBalance (used by the Customer Card background calculation that feeds the overdue payments cue) and the "Balance Due (LCY)" FlowField shown on the Customer Card return only overdue amounts, even when a wider "Date Filter" is inherited on the Customer record from a document or journal. Initialize(); // [GIVEN] Reference dates that bracket both WORKDATE and Today so the fixture is deterministic regardless of their relative order. @@ -1144,25 +1145,28 @@ codeunit 134389 "ERM Customer Statistics" // [GIVEN] Create customer with two posted sales invoices. LibrarySales.CreateCustomer(Customer); - // [GIVEN] CreateInvoice "A" is overdue against both WORKDATE and Today: Due Date < min(WORKDATE, Today), Amount = "X". + // [GIVEN] Invoice "A" is overdue against both WORKDATE and Today: Due Date < min(WORKDATE, Today), Amount = "X". OverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", CalcDate('<-2M>', EarliestDate), CalcDate('<-1M>', EarliestDate)); - // [GIVEN] Create Invoice "B" is not yet due against either WORKDATE or Today: Due Date > max(WORKDATE, Today), Amount = "Y". + // [GIVEN] Invoice "B" is not yet due against either WORKDATE or Today: Due Date > max(WORKDATE, Today), Amount = "Y". NotOverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", WorkDate(), CalcDate('<2M>', LatestDate)); // [GIVEN] A wider "Date Filter" is applied on the Customer record, simulating one inherited from a document or journal and captured by StartBackgroundCalculations before any reset. Customer.SetFilter("Date Filter", '..%1', CalcDate('<3M>', LatestDate)); - // [WHEN] CalcOverdueBalance is called on the Customer (the same call the background task makes after Customer.SetView). + // [WHEN] CalcOverdueBalance is called on the Customer (the same call the background task makes after Customer.SetView for the overdue payments cue). + // [THEN] Only the overdue invoice amount is returned, proving the cue calculation is isolated from the leaked wider Date Filter. Assert.AreEqual(Round(OverdueAmount), Customer.CalcOverdueBalance(), OverDueBalanceErr); - // [WHEN] The Customer Card's OnAfterGetCurrRecord unconditionally resets the "Date Filter" to 0D..WORKDATE. - Customer.SetRange("Date Filter", 0D, WorkDate()); + // [WHEN] The Customer Card is opened for the customer with a leaked wider "Date Filter" applied by the caller (document/journal path). + CustomerCard.OpenView(); + CustomerCard.FILTER.SetFilter("Date Filter", StrSubstNo('..%1', CalcDate('<3M>', LatestDate))); + CustomerCard.FILTER.SetFilter("No.", Customer."No."); - // [THEN] Verify "Balance Due (LCY)" sums only the overdue invoice amount. - Customer.CalcFields("Balance Due (LCY)", "Balance (LCY)"); - Assert.AreEqual(OverdueAmount, Customer."Balance Due (LCY)", OverDueBalanceErr); - // [THEN] Verify "Balance (LCY)" sums both invoice amounts. - Assert.AreEqual(OverdueAmount + NotOverdueAmount, Customer."Balance (LCY)", 'Balance (LCY) should include both invoices.'); + // [THEN] "Balance Due (LCY)" shown on the Customer Card reflects only the overdue invoice amount, proving OnAfterGetCurrRecord resets the "Date Filter" to 0D..WORKDATE before FlowFields are evaluated. + Assert.AreEqual(OverdueAmount, CustomerCard."Balance Due (LCY)".AsDecimal(), OverDueBalanceErr); + // [THEN] "Balance (LCY)" on the Customer Card still sums both invoices. + Assert.AreEqual(OverdueAmount + NotOverdueAmount, CustomerCard."Balance (LCY)".AsDecimal(), 'Balance (LCY) should include both invoices.'); + CustomerCard.Close(); end; local procedure Initialize() From 10476ea7a6aeeb5204c7048c725525604178f046 Mon Sep 17 00:00:00 2001 From: v-nesinghal Date: Thu, 9 Jul 2026 15:50:48 +0530 Subject: [PATCH 7/9] Suggestion fix --- .../ERM/ERMCustomerStatistics.Codeunit.al | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al index 04e633b58b..c387b9a819 100644 --- a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al @@ -31,6 +31,9 @@ codeunit 134389 "ERM Customer Statistics" PaymentsLCYAndAmountLCYMustMatchErr: Label 'Payemnts (LCY) and Amount (LCY) must match.'; CustomerCardFactboxTotalErr: Label 'Customer card factbox total is not Correct'; LotNoErr: Label 'Lot No. should have value.'; + DateFilterNotResetErr: Label 'Date Filter upper bound on the Customer Card should be reset to WORKDATE() before StartBackgroundCalculations captures Rec.GetView().'; + DateFilterLeakedErr: Label 'Date Filter on the Customer Card should no longer contain the leaked wider upper bound.'; + BalanceLCYShouldIncludeBothInvoicesErr: Label 'Balance (LCY) should include both invoices.'; [Test] [Scope('OnPrem')] @@ -1124,6 +1127,7 @@ codeunit 134389 "ERM Customer Statistics" procedure OverdueBalanceIsolatedFromLeakedWideDateFilterOnCustomer() var Customer: Record Customer; + CustomerForBackgroundTask: Record Customer; CustomerCard: TestPage "Customer Card"; EarliestDate: Date; LatestDate: Date; @@ -1131,7 +1135,7 @@ codeunit 134389 "ERM Customer Statistics" NotOverdueAmount: Decimal; begin // [FEATURE] [Overdue Balance] [Cue] - // [SCENARIO 640988] Both Customer.CalcOverdueBalance (used by the Customer Card background calculation that feeds the overdue payments cue) and the "Balance Due (LCY)" FlowField shown on the Customer Card return only overdue amounts, even when a wider "Date Filter" is inherited on the Customer record from a document or journal. + // [SCENARIO 640988] The "Balance Due" overdue payments cue on the Customer Card (page variable OverdueBalance, filled by the "Customer Card Calculations" background task from Rec.GetView) and the "Balance Due (LCY)" FlowField both return only overdue amounts, even when a wider "Date Filter" is inherited on the Customer record from a document or journal. Initialize(); // [GIVEN] Reference dates that bracket both WORKDATE and Today so the fixture is deterministic regardless of their relative order. @@ -1150,22 +1154,25 @@ codeunit 134389 "ERM Customer Statistics" // [GIVEN] Invoice "B" is not yet due against either WORKDATE or Today: Due Date > max(WORKDATE, Today), Amount = "Y". NotOverdueAmount := CreateAndPostInvoiceWithDueDate(Customer."No.", WorkDate(), CalcDate('<2M>', LatestDate)); - // [GIVEN] A wider "Date Filter" is applied on the Customer record, simulating one inherited from a document or journal and captured by StartBackgroundCalculations before any reset. - Customer.SetFilter("Date Filter", '..%1', CalcDate('<3M>', LatestDate)); - - // [WHEN] CalcOverdueBalance is called on the Customer (the same call the background task makes after Customer.SetView for the overdue payments cue). - // [THEN] Only the overdue invoice amount is returned, proving the cue calculation is isolated from the leaked wider Date Filter. - Assert.AreEqual(Round(OverdueAmount), Customer.CalcOverdueBalance(), OverDueBalanceErr); - // [WHEN] The Customer Card is opened for the customer with a leaked wider "Date Filter" applied by the caller (document/journal path). CustomerCard.OpenView(); CustomerCard.FILTER.SetFilter("Date Filter", StrSubstNo('..%1', CalcDate('<3M>', LatestDate))); CustomerCard.FILTER.SetFilter("No.", Customer."No."); - // [THEN] "Balance Due (LCY)" shown on the Customer Card reflects only the overdue invoice amount, proving OnAfterGetCurrRecord resets the "Date Filter" to 0D..WORKDATE before FlowFields are evaluated. + // [THEN] OnAfterGetCurrRecordFunc resets the "Date Filter" on the Card record to 0D..WORKDATE before StartBackgroundCalculations captures the view, so the leaked upper bound past WORKDATE no longer applies on the page. + Assert.IsTrue(StrPos(CustomerCard.FILTER.GetFilter("Date Filter"), Format(WorkDate())) > 0, DateFilterNotResetErr); + Assert.IsTrue(StrPos(CustomerCard.FILTER.GetFilter("Date Filter"), Format(CalcDate('<3M>', LatestDate))) = 0, DateFilterLeakedErr); + + // [THEN] "Balance Due (LCY)" FlowField shown on the Customer Card reflects only the overdue invoice amount. Assert.AreEqual(OverdueAmount, CustomerCard."Balance Due (LCY)".AsDecimal(), OverDueBalanceErr); // [THEN] "Balance (LCY)" on the Customer Card still sums both invoices. - Assert.AreEqual(OverdueAmount + NotOverdueAmount, CustomerCard."Balance (LCY)".AsDecimal(), 'Balance (LCY) should include both invoices.'); + Assert.AreEqual(OverdueAmount + NotOverdueAmount, CustomerCard."Balance (LCY)".AsDecimal(), BalanceLCYShouldIncludeBothInvoicesErr); + + // [THEN] The "Balance Due" overdue payments cue (OverdueBalance page variable) is populated by the "Customer Card Calculations" background task which does Customer.SetView() and then Customer.CalcOverdueBalance(). Replaying that exact call path with the Date Filter now captured on the Card returns only the overdue amount, proving the cue value is isolated from the leaked wider Date Filter. + CustomerForBackgroundTask.Get(Customer."No."); + CustomerForBackgroundTask.SetFilter("Date Filter", CustomerCard.FILTER.GetFilter("Date Filter")); + Assert.AreEqual(Round(OverdueAmount), CustomerForBackgroundTask.CalcOverdueBalance(), OverDueBalanceErr); + CustomerCard.Close(); end; From d6faef4a823184e02a9759984ccdb6c6ddf71604 Mon Sep 17 00:00:00 2001 From: v-nesinghal Date: Fri, 10 Jul 2026 02:20:18 +0530 Subject: [PATCH 8/9] Miapp and Suggestion fix --- src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al | 1 - src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al | 2 ++ 11 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al index 90cbb2a965..be36d9b2ab 100644 --- a/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/APAC/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2460,7 +2460,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al index aa15eca34c..1c3b8231b4 100644 --- a/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/BE/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2414,7 +2414,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al index ded18c0d37..b22dba24fb 100644 --- a/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/ES/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2452,7 +2452,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al index c62cdd2fee..6aefbf928a 100644 --- a/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/FR/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2458,7 +2458,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al index 46670f12c0..04fca04161 100644 --- a/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/GB/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2448,7 +2448,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al index 8473ed7198..e7958ba098 100644 --- a/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/IT/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2542,7 +2542,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al index 1c62670504..00e3d00210 100644 --- a/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NA/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2559,7 +2559,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al index 348b11fde9..85c5ea26f2 100644 --- a/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NL/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2404,7 +2404,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al index dcebc13335..3cbd4c78cd 100644 --- a/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/NO/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2420,7 +2420,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al b/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al index 24cde19595..2106016f9b 100644 --- a/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al +++ b/src/Layers/RU/BaseApp/Sales/Customer/CustomerCard.Page.al @@ -2530,7 +2530,6 @@ page 21 "Customer Card" ActivateFields(); SetCreditLimitStyle(); - Rec.SetRange("Date Filter", 0D, WorkDate()); if CRMIntegrationEnabled or CDSIntegrationEnabled then begin CRMIsCoupledToRecord := CRMCouplingManagement.IsRecordCoupledToCRM(Rec.RecordId); if Rec."No." <> xRec."No." then diff --git a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al index c387b9a819..f9cfc29bd4 100644 --- a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al @@ -1165,6 +1165,8 @@ codeunit 134389 "ERM Customer Statistics" // [THEN] "Balance Due (LCY)" FlowField shown on the Customer Card reflects only the overdue invoice amount. Assert.AreEqual(OverdueAmount, CustomerCard."Balance Due (LCY)".AsDecimal(), OverDueBalanceErr); + // [THEN] "Balance Due" cue (OverdueBalance page variable, populated by the background task) also reflects only the overdue invoice amount. + Assert.AreEqual(OverdueAmount, CustomerCard."Balance Due".AsDecimal(), OverDueBalanceErr); // [THEN] "Balance (LCY)" on the Customer Card still sums both invoices. Assert.AreEqual(OverdueAmount + NotOverdueAmount, CustomerCard."Balance (LCY)".AsDecimal(), BalanceLCYShouldIncludeBothInvoicesErr); From 87e71e9bd52c4aa33c318262f0d686dc8a0491e1 Mon Sep 17 00:00:00 2001 From: v-nesinghal Date: Fri, 17 Jul 2026 00:00:08 +0530 Subject: [PATCH 9/9] changes --- .../W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al index f9cfc29bd4..562b1d73df 100644 --- a/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/ERMCustomerStatistics.Codeunit.al @@ -494,20 +494,21 @@ codeunit 134389 "ERM Customer Statistics" // [SCENARIO 258948] When Drill Down on Balance Due (LCY) is called from Customer Card, Due Date filter on opened Customer Ledger Entries Page = Date Filter. Initialize(); - // [GIVEN] Setup new Customer with a customer ledger entry + // [GIVEN] Setup new Customer with a customer ledger entry due on or before the work date LibrarySales.CreateCustomer(Customer); CreateBasicCustLedgerEntry(CustLedgerEntry, Customer."No."); - CustLedgerEntry.Validate("Due Date", LibraryRandom.RandDate(100)); + CustLedgerEntry.Validate("Due Date", CalcDate('<-1M>', WorkDate())); CustLedgerEntry.Modify(true); // [WHEN] The user drills down on Balance Due (LCY) field from Customer Card CustomerCard.OpenView(); CustomerLedgerEntries.Trap(); - CustomerCard.FILTER.SetFilter("Date Filter", Format(CustLedgerEntry."Due Date")); + // [WHEN] A wider Date Filter is inherited on the Customer Card (document/journal path) + CustomerCard.FILTER.SetFilter("Date Filter", StrSubstNo('..%1', CalcDate('<1M>', WorkDate()))); CustomerCard.GotoRecord(Customer); CustomerCard."Balance Due (LCY)".DrillDown(); - // [THEN] Customer Ledger Entries window opens, Due Date filter = Date Filter from Customer List. + // [THEN] The Customer Card normalizes the Date Filter to 0D..WORKDATE (Bug 640988), and the opened Customer Ledger Entries Page Due Date filter = that Date Filter. Assert.AreEqual(CustomerCard.FILTER.GetFilter("Date Filter"), CustomerLedgerEntries.FILTER.GetFilter("Due Date"), ''); // [THEN] Customer Ledger Entries window opens, showing the ledger entries for the selected customer @@ -1301,7 +1302,7 @@ codeunit 134389 "ERM Customer Statistics" exit(SalesHeader."Amount Including VAT"); end; - local procedure CreateAndPostInvoiceWithDueDate(CustomerNo: Code[20]; PostingDate: Date; DueDate: Date): Decimal + local procedure CreateAndPostInvoiceWithDueDate(CustomerNo: Code[20]; PostingDate: Date; DueDate: Date) AmountInclVAT: Decimal var SalesHeader: Record "Sales Header"; SalesLine: Record "Sales Line"; @@ -1312,8 +1313,8 @@ codeunit 134389 "ERM Customer Statistics" LibrarySales.CreateSalesLine( SalesLine, SalesHeader, SalesLine.Type::Item, CreateItemWithUnitPrice(), LibraryRandom.RandDec(10, 2)); SalesHeader.CalcFields("Amount Including VAT"); + AmountInclVAT := SalesHeader."Amount Including VAT"; LibrarySales.PostSalesDocument(SalesHeader, true, true); - exit(SalesHeader."Amount Including VAT"); end; local procedure CreateAndPostSalesDocument(CustomerNo: Code[20]; CurrencyCode: Code[10]): Decimal