Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ codeunit 5988 "Serv-Documents Mgt."
end;

UseAsExternalDocumentNo := ServInvHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::Invoice, ServInvHeader."No.", UseAsExternalDocumentNo);

Expand Down Expand Up @@ -997,7 +997,7 @@ codeunit 5988 "Serv-Documents Mgt."
ServLogMgt.ServCrMemoPost(ServHeader."No.", ServCrMemoHeader."No.");

UseAsExternalDocumentNo := ServCrMemoHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::"Credit Memo", ServCrMemoHeader."No.", UseAsExternalDocumentNo);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ codeunit 5988 "Serv-Documents Mgt."
end;

UseAsExternalDocumentNo := ServInvHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::Invoice, ServInvHeader."No.", UseAsExternalDocumentNo);

Expand Down Expand Up @@ -1054,7 +1054,7 @@ codeunit 5988 "Serv-Documents Mgt."
ServLogMgt.ServCrMemoPost(ServHeader."No.", ServCrMemoHeader."No.");

UseAsExternalDocumentNo := ServCrMemoHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::"Credit Memo", ServCrMemoHeader."No.", UseAsExternalDocumentNo);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ codeunit 5988 "Serv-Documents Mgt."
end;

UseAsExternalDocumentNo := ServInvHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::Invoice, ServInvHeader."No.", UseAsExternalDocumentNo);

Expand Down Expand Up @@ -997,7 +997,7 @@ codeunit 5988 "Serv-Documents Mgt."
ServLogMgt.ServCrMemoPost(ServHeader."No.", ServCrMemoHeader."No.");

UseAsExternalDocumentNo := ServCrMemoHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::"Credit Memo", ServCrMemoHeader."No.", UseAsExternalDocumentNo);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2656,10 +2656,10 @@ codeunit 136108 "Service Posting - Invoice"
// [WHEN] Service invoice is being posted
LibraryService.PostServiceOrder(ServiceHeader, true, false, true);

// [THEN] Created customer ledger entry has External Document No. = ServiceHeader."No."
// [THEN] Created customer ledger entry has External Document No. = ''
CustLedgerEntry.SetRange("Customer No.", CustomerNo);
CustLedgerEntry.FindFirst();
CustLedgerEntry.TestField("External Document No.", ServiceHeader."No.");
CustLedgerEntry.TestField("External Document No.", '');
end;

[Test]
Expand Down Expand Up @@ -3222,6 +3222,51 @@ codeunit 136108 "Service Posting - Invoice"
ActivityLog.DeleteAll();
end;

[Test]
[Scope('OnPrem')]
procedure PostServiceOrderWithoutExternalDocNoLeavesGLEntriesBlank()
var
ServiceHeader: Record "Service Header";
ServiceItemLine: Record "Service Item Line";
ServiceLine: Record "Service Line";
ServiceItem: Record "Service Item";
ServiceInvoiceHeader: Record "Service Invoice Header";
GLEntry: Record "G/L Entry";
Customer: Record Customer;
ServiceMgtSetup: Record "Service Mgt. Setup";
begin
// [FEATURE] [AI test 0.4]
// [SCENARIO 638182] GL entries have blank External Document No. when service order is posted without External Document No.
Initialize();

// [GIVEN] Service Mgt. Setup with "Ext. Doc. No. Mandatory" disabled
ServiceMgtSetup.Get();
ServiceMgtSetup.Validate("Ext. Doc. No. Mandatory", false);
ServiceMgtSetup.Modify(true);

// [GIVEN] Service Order "SO" for Customer "C" with blank External Document No.
LibrarySales.CreateCustomer(Customer);
LibraryService.CreateServiceItem(ServiceItem, Customer."No.");
LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::Order, Customer."No.");
LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, ServiceItem."No.");
CreateServiceLineWithItem(ServiceLine, ServiceHeader, ServiceItem."No.");
ServiceHeader.Validate("External Document No.", '');
ServiceHeader.Modify(true);

// [WHEN] Post service order with Ship and Invoice
LibraryService.PostServiceOrder(ServiceHeader, true, false, true);

// [THEN] GL entries for posted service invoice have blank External Document No.
ServiceInvoiceHeader.SetRange("Order No.", ServiceHeader."No.");
ServiceInvoiceHeader.FindFirst();
GLEntry.SetRange("Document Type", GLEntry."Document Type"::Invoice);
GLEntry.SetRange("Document No.", ServiceInvoiceHeader."No.");
GLEntry.FindSet();
repeat
Assert.AreEqual('', GLEntry."External Document No.", 'External Document No. should be blank on G/L Entry when not specified on Service Order');
until GLEntry.Next() = 0;
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Service-Post", OnSetCommitBehavior, '', false, false)]
local procedure OnSetCommitBehaviorHandler(var IgnoreCommit: Boolean)
begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ codeunit 5988 "Serv-Documents Mgt."
end;

UseAsExternalDocumentNo := ServInvHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::Invoice, ServInvHeader."No.", UseAsExternalDocumentNo);

Expand Down Expand Up @@ -997,7 +997,7 @@ codeunit 5988 "Serv-Documents Mgt."
ServLogMgt.ServCrMemoPost(ServHeader."No.", ServCrMemoHeader."No.");

UseAsExternalDocumentNo := ServCrMemoHeader."External Document No.";
if UseAsExternalDocumentNo = '' then
if (UseAsExternalDocumentNo = '') and ServMgtSetup."Ext. Doc. No. Mandatory" then
UseAsExternalDocumentNo := ServHeader."No.";
SetGenJnlLineDocNos(GenJnlLineDocType::"Credit Memo", ServCrMemoHeader."No.", UseAsExternalDocumentNo);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2656,10 +2656,10 @@ codeunit 136108 "Service Posting - Invoice"
// [WHEN] Service invoice is being posted
LibraryService.PostServiceOrder(ServiceHeader, true, false, true);

// [THEN] Created customer ledger entry has External Document No. = ServiceHeader."No."
// [THEN] Created customer ledger entry has External Document No. = ''
CustLedgerEntry.SetRange("Customer No.", CustomerNo);
CustLedgerEntry.FindFirst();
CustLedgerEntry.TestField("External Document No.", ServiceHeader."No.");
CustLedgerEntry.TestField("External Document No.", '');
end;

[Test]
Expand Down Expand Up @@ -3175,6 +3175,51 @@ codeunit 136108 "Service Posting - Invoice"
ActivityLog.DeleteAll();
end;

[Test]
[Scope('OnPrem')]
procedure PostServiceOrderWithoutExternalDocNoLeavesGLEntriesBlank()
var
ServiceHeader: Record "Service Header";
ServiceItemLine: Record "Service Item Line";
ServiceLine: Record "Service Line";
ServiceItem: Record "Service Item";
ServiceInvoiceHeader: Record "Service Invoice Header";
GLEntry: Record "G/L Entry";
Customer: Record Customer;
ServiceMgtSetup: Record "Service Mgt. Setup";
begin
// [FEATURE] [AI test 0.4]
// [SCENARIO 638182] GL entries have blank External Document No. when service order is posted without External Document No.
Initialize();

// [GIVEN] Service Mgt. Setup with "Ext. Doc. No. Mandatory" disabled
ServiceMgtSetup.Get();
ServiceMgtSetup.Validate("Ext. Doc. No. Mandatory", false);
ServiceMgtSetup.Modify(true);

// [GIVEN] Service Order "SO" for Customer "C" with blank External Document No.
LibrarySales.CreateCustomer(Customer);
LibraryService.CreateServiceItem(ServiceItem, Customer."No.");
LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::Order, Customer."No.");
LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, ServiceItem."No.");
CreateServiceLineWithItem(ServiceLine, ServiceHeader, ServiceItem."No.");
ServiceHeader.Validate("External Document No.", '');
ServiceHeader.Modify(true);

// [WHEN] Post service order with Ship and Invoice
LibraryService.PostServiceOrder(ServiceHeader, true, false, true);

// [THEN] GL entries for posted service invoice have blank External Document No.
ServiceInvoiceHeader.SetRange("Order No.", ServiceHeader."No.");
ServiceInvoiceHeader.FindFirst();
GLEntry.SetRange("Document Type", GLEntry."Document Type"::Invoice);
GLEntry.SetRange("Document No.", ServiceInvoiceHeader."No.");
GLEntry.FindSet();

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{🟡\ Medium\ Severity\ —\ Agent} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

GLEntry.FindSet() is called as a standalone statement (return value discarded) immediately before a repeat…until GLEntry.Next() = 0 loop.

Because AL's repeat…until is a do-while construct it always executes the loop body at least once, regardless of whether FindSet found any records. If no GL entries exist the loop body runs once on the default (empty) GLEntry variable, GLEntry."External Document No." equals '' by default, and Assert.AreEqual('', '', …) passes vacuously. The test would silently pass even when the posting path produces no GL entries.

Recommendation:

  • replace the standalone GLEntry.FindSet() call with a guarded assertion, e.g. Assert.IsTrue(GLEntry.FindSet(), 'Expected GL entries for invoice ' + ServiceInvoiceHeader."No."); before the repeat block.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

Assert.IsTrue(GLEntry.FindSet(), 'Expected GL entries to exist for posted invoice ' + ServiceInvoiceHeader."No.");
        repeat
            Assert.AreEqual('', GLEntry."External Document No.", 'External Document No. should be blank on G/L Entry when not specified on Service Order');
        until GLEntry.Next() = 0;

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

repeat
Assert.AreEqual('', GLEntry."External Document No.", 'External Document No. should be blank on G/L Entry when not specified on Service Order');
until GLEntry.Next() = 0;
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Service-Post", OnSetCommitBehavior, '', false, false)]
local procedure OnSetCommitBehaviorHandler(var IgnoreCommit: Boolean)
begin
Expand Down
Loading