From 8d35b03ad593a8a1186436e762f6376b85790076 Mon Sep 17 00:00:00 2001
From: ventselartur <137783588+ventselartur@users.noreply.github.com>
Date: Thu, 7 May 2026 17:50:12 +0200
Subject: [PATCH 1/5] Fix: Improve UX on failing validation of additional field
values during E-Doc finalization (#7296)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement the new codeunit that binds to the certain events and save the
context, so that, when finalize is failed, it shows more details rather
than just an error message. Example:
Fixes
[AB#623716](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/623716)
— [Payables Agent] Draft could not be finalised due to field length
issues.
---------
Co-authored-by: Claude Sonnet 4.6
---
.../App/src/Processing/EDocImport.Codeunit.al | 5 +
.../Import/EDocImportErrorContext.Codeunit.al | 80 ++++
.../EDocCreatePurchCrMemo.Codeunit.al | 128 ++++++
.../EDocCreatePurchaseInvoice.Codeunit.al | 11 +-
.../EDocPurchDocHelper.Codeunit.al | 171 ++++++++
.../EDocPurchaseHistMapping.Codeunit.al | 7 +-
.../Processing/EDocProcessTest.Codeunit.al | 409 +++++++++++++++++-
7 files changed, 805 insertions(+), 6 deletions(-)
create mode 100644 src/Apps/W1/EDocument/App/src/Processing/Import/EDocImportErrorContext.Codeunit.al
create mode 100644 src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al
create mode 100644 src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al
diff --git a/src/Apps/W1/EDocument/App/src/Processing/EDocImport.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/EDocImport.Codeunit.al
index c5d9bf88eb..a349265ed3 100644
--- a/src/Apps/W1/EDocument/App/src/Processing/EDocImport.Codeunit.al
+++ b/src/Apps/W1/EDocument/App/src/Processing/EDocImport.Codeunit.al
@@ -136,13 +136,16 @@ codeunit 6140 "E-Doc. Import"
var
EDocDraftSessionTelemetry: Codeunit "E-Doc. Imp. Session Telemetry";
EDocumentErrorHelper: Codeunit "E-Document Error Helper";
+ EDocImportErrorContext: Codeunit "E-Doc. Import Error Context";
LastErrorText: Text;
begin
EDocumentErrorHelper.ClearErrorMessages(EDocument);
Commit();
+ BindSubscription(EDocImportErrorContext);
if not ImportEDocumentProcess.Run() then begin
LastErrorText := GetLastErrorText();
if LastErrorText <> '' then begin // We don't insert an error when empty, following the convention of empty error meaning "operation cancelled by user"
+ LastErrorText := EDocImportErrorContext.WrapErrorMessage(LastErrorText);
EDocument.SetRecFilter();
EDocument.FindFirst();
@@ -154,8 +157,10 @@ codeunit 6140 "E-Doc. Import"
end;
EDocDraftSessionTelemetry.SetText('Step', Format(ImportEDocumentProcess.GetStep()));
EDocDraftSessionTelemetry.SetBool('Success', false);
+ UnbindSubscription(EDocImportErrorContext);
exit(false);
end;
+ UnbindSubscription(EDocImportErrorContext);
exit(true);
end;
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/EDocImportErrorContext.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/EDocImportErrorContext.Codeunit.al
new file mode 100644
index 0000000000..0464aded9d
--- /dev/null
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/EDocImportErrorContext.Codeunit.al
@@ -0,0 +1,80 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+namespace Microsoft.eServices.EDocument.Processing.Import;
+
+codeunit 6199 "E-Doc. Import Error Context"
+{
+ Access = Internal;
+ InherentEntitlements = X;
+ InherentPermissions = X;
+ EventSubscriberInstance = Manual;
+
+ var
+ CurrentContext: Text;
+ AdditionalFieldContextLbl: Label 'While applying additional field "%1" (ID %2) with value ''%3''', Comment = '%1 = Field Name, %2 = Field Number, %3 = Value';
+ ValidatingFieldLbl: Label 'While validating field "%1"', Comment = '%1 = Field Caption';
+ WrapErrorLbl: Label '%1: %2', Comment = '%1 = Context, %2 = Original Error';
+
+ ///
+ /// Returns whether a context message is currently set.
+ ///
+ /// True if a context message is set, false otherwise.
+ procedure HasContext(): Boolean
+ begin
+ exit(CurrentContext <> '');
+ end;
+
+ ///
+ /// Wraps the original error message with the current context, if one is set.
+ ///
+ /// The original error message to wrap.
+ /// The error message prefixed with the current context, or the original message if no context is set.
+ procedure WrapErrorMessage(OriginalError: Text): Text
+ begin
+ if CurrentContext = '' then
+ exit(OriginalError);
+ exit(StrSubstNo(WrapErrorLbl, CurrentContext, OriginalError));
+ end;
+
+ ///
+ /// Clears the additional field context
+ ///
+ procedure ClearAdditionalFieldContext()
+ begin
+ CurrentContext := '';
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"E-Doc. Import Error Context", OnValidateFieldWithContext, '', false, false)]
+ local procedure ValidateFieldWithContextSubscriber(FieldCaption: Text)
+ begin
+ CurrentContext := StrSubstNo(ValidatingFieldLbl, FieldCaption);
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"E-Doc. Import Error Context", OnSetAdditionalFieldContext, '', false, false)]
+ local procedure SetAdditionalFieldContext(FieldName: Text; FieldNo: Integer; Value: Text)
+ begin
+ CurrentContext := StrSubstNo(AdditionalFieldContextLbl, FieldName, FieldNo, Value);
+ end;
+
+ ///
+ /// Sets the context to describe a field being validated during e-document import.
+ ///
+ /// The caption of the field being validated.
+ [IntegrationEvent(false, false)]
+ procedure OnValidateFieldWithContext(FieldCaption: Text)
+ begin
+ end;
+
+ ///
+ /// Sets the context to describe an additional field being applied
+ ///
+ /// The name of the additional field being applied.
+ /// The ID of the additional field being applied.
+ /// The value being applied to the field.
+ [IntegrationEvent(false, false)]
+ procedure OnSetAdditionalFieldContext(FieldName: Text; FieldNo: Integer; Value: Text)
+ begin
+ end;
+}
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al
new file mode 100644
index 0000000000..77ecf97e66
--- /dev/null
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al
@@ -0,0 +1,128 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+namespace Microsoft.eServices.EDocument.Processing.Import;
+
+using Microsoft.eServices.EDocument;
+using Microsoft.eServices.EDocument.Processing;
+using Microsoft.eServices.EDocument.Processing.Import.Purchase;
+using Microsoft.eServices.EDocument.Processing.Interfaces;
+using Microsoft.Finance.GeneralLedger.Setup;
+using Microsoft.Purchases.Document;
+using Microsoft.Purchases.Payables;
+using System.Telemetry;
+
+///
+/// Dealing with the creation of the purchase credit memo after the draft has been populated.
+///
+codeunit 6404 "E-Doc. Create Purch. Cr. Memo" implements IEDocumentFinishDraft, IEDocumentCreatePurchaseCreditMemo
+{
+ Access = Internal;
+
+ var
+ Telemetry: Codeunit "Telemetry";
+ CrMemoAlreadyExistsErr: Label 'A purchase credit memo with external document number %1 already exists for vendor %2.', Comment = '%1 = Vendor Cr. Memo No., %2 = Vendor No.';
+ DraftLineDoesNotContainTypeAndNumberErr: Label 'One of the draft lines do not contain the type and number. Please, specify these fields manually.';
+
+ procedure ApplyDraftToBC(EDocument: Record "E-Document"; EDocImportParameters: Record "E-Doc. Import Parameters"): RecordId
+ var
+ PurchaseHeader: Record "Purchase Header";
+ EDocPurchaseDocumentHelper: Codeunit "E-Doc. Purch. Doc. Helper";
+ EDocImpSessionTelemetry: Codeunit "E-Doc. Imp. Session Telemetry";
+ EmptyRecordId: RecordId;
+ IEDocumentFinishPurchaseCrMemo: Interface IEDocumentCreatePurchaseCreditMemo;
+ begin
+ IEDocumentFinishPurchaseCrMemo := EDocImportParameters."Processing Customizations";
+ if EDocImportParameters."Existing Doc. RecordId" <> EmptyRecordId then begin
+ EDocImpSessionTelemetry.SetBool('LinkedToExisting', true);
+ PurchaseHeader.Get(EDocImportParameters."Existing Doc. RecordId");
+ end else
+ PurchaseHeader := IEDocumentFinishPurchaseCrMemo.CreatePurchaseCreditMemo(EDocument);
+
+ EDocPurchaseDocumentHelper.FinalizeCreatedDocument(EDocument, PurchaseHeader);
+
+ exit(PurchaseHeader.RecordId);
+ end;
+
+ procedure RevertDraftActions(EDocument: Record "E-Document")
+ var
+ PurchaseHeader: Record "Purchase Header";
+ EDocPurchaseDocumentHelper: Codeunit "E-Doc. Purch. Doc. Helper";
+ begin
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ if not PurchaseHeader.FindFirst() then
+ exit;
+
+ PurchaseHeader.TestField("Document Type", "Purchase Document Type"::"Credit Memo");
+ EDocPurchaseDocumentHelper.RevertCreatedDocument(EDocument);
+ end;
+
+ procedure CreatePurchaseCreditMemo(EDocument: Record "E-Document"): Record "Purchase Header"
+ var
+ PurchaseHeader: Record "Purchase Header";
+ GLSetup: Record "General Ledger Setup";
+ VendorLedgerEntry: Record "Vendor Ledger Entry";
+ EDocumentPurchaseHeader: Record "E-Document Purchase Header";
+ EDocumentPurchaseLine: Record "E-Document Purchase Line";
+ EDocRecordLink: Record "E-Doc. Record Link";
+ EDocPurchaseDocumentHelper: Codeunit "E-Doc. Purch. Doc. Helper";
+ PurchCalcDiscByType: Codeunit "Purch - Calc Disc. By Type";
+ StopCreatingCreditMemo: Boolean;
+ VendorCrMemoNo: Code[35];
+ PurchaseLineNo: Integer;
+ begin
+ EDocumentPurchaseHeader.GetFromEDocument(EDocument);
+ if not EDocPurchaseDocumentHelper.AllDraftLinesHaveTypeAndNumber(EDocumentPurchaseHeader) then begin
+ Telemetry.LogMessage('0000SNH', 'Draft line does not contain type or number', Verbosity::Error, DataClassification::SystemMetadata, TelemetryScope::All);
+ Error(DraftLineDoesNotContainTypeAndNumberErr);
+ end;
+ EDocumentPurchaseHeader.TestField("E-Document Entry No.");
+ PurchaseHeader.SetRange("Buy-from Vendor No.", EDocumentPurchaseHeader."[BC] Vendor No.");
+ PurchaseHeader."Document Type" := "Purchase Document Type"::"Credit Memo";
+ PurchaseHeader."Pay-to Vendor No." := EDocumentPurchaseHeader."[BC] Vendor No.";
+ PurchaseHeader."Posting Description" := EDocumentPurchaseHeader."Posting Description";
+ if EDocumentPurchaseHeader."Document Date" <> 0D then
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Document Date"), EDocumentPurchaseHeader."Document Date");
+ if EDocumentPurchaseHeader."Due Date" <> 0D then
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Due Date"), EDocumentPurchaseHeader."Due Date");
+
+ VendorCrMemoNo := CopyStr(EDocumentPurchaseHeader."Sales Invoice No.", 1, MaxStrLen(PurchaseHeader."Vendor Cr. Memo No."));
+ VendorLedgerEntry.SetLoadFields("Entry No.");
+ VendorLedgerEntry.ReadIsolation := VendorLedgerEntry.ReadIsolation::ReadUncommitted;
+ StopCreatingCreditMemo := PurchaseHeader.FindPostedDocumentWithSameExternalDocNo(VendorLedgerEntry, VendorCrMemoNo);
+ if StopCreatingCreditMemo then begin
+ Telemetry.LogMessage('0000SNI', CrMemoAlreadyExistsErr, Verbosity::Error, DataClassification::OrganizationIdentifiableInformation, TelemetryScope::All);
+ Error(CrMemoAlreadyExistsErr, VendorCrMemoNo, EDocumentPurchaseHeader."[BC] Vendor No.");
+ end;
+
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Vendor Cr. Memo No."), VendorCrMemoNo);
+ if EDocumentPurchaseHeader."Purchase Order No." <> '' then
+ PurchaseHeader."Vendor Order No." := CopyStr(EDocumentPurchaseHeader."Purchase Order No.", 1, MaxStrLen(PurchaseHeader."Vendor Order No."));
+ PurchaseHeader.Insert(true);
+ PurchaseHeader.Modify();
+
+ GLSetup.GetRecordOnce();
+ if EDocumentPurchaseHeader."Currency Code" <> GLSetup.GetCurrencyCode('') then
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Currency Code"), EDocumentPurchaseHeader."Currency Code");
+
+ if EDocumentPurchaseHeader."Applies-to Doc. No." <> '' then
+ PurchaseHeader."Applies-to Doc. No." := CopyStr(EDocumentPurchaseHeader."Applies-to Doc. No.", 1, MaxStrLen(PurchaseHeader."Applies-to Doc. No."));
+
+ PurchaseHeader.Modify();
+
+ EDocRecordLink.InsertEDocumentHeaderLink(EDocumentPurchaseHeader, PurchaseHeader);
+
+ PurchaseLineNo := EDocPurchaseDocumentHelper.GetLastPurchaseLineNo("Purchase Document Type"::"Credit Memo", PurchaseHeader."No.");
+ EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
+ if EDocumentPurchaseLine.FindSet() then
+ repeat
+ PurchaseLineNo += 10000;
+ EDocPurchaseDocumentHelper.CreatePurchaseLineFromDraft(PurchaseHeader, EDocumentPurchaseLine, EDocumentPurchaseHeader."Total Discount" > 0, PurchaseLineNo);
+ until EDocumentPurchaseLine.Next() = 0;
+
+ PurchaseHeader.Modify();
+ PurchCalcDiscByType.ApplyInvDiscBasedOnAmt(EDocumentPurchaseHeader."Total Discount", PurchaseHeader);
+ exit(PurchaseHeader);
+ end;
+}
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
index 5744937013..a896f0d4d1 100644
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
@@ -112,6 +112,7 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
EDocumentPurchaseLine: Record "E-Document Purchase Line";
PurchaseLine: Record "Purchase Line";
EDocRecordLink: Record "E-Doc. Record Link";
+ EDocPurchaseDocumentHelper: Codeunit "E-Doc. Purch. Doc. Helper";
PurchCalcDiscByType: Codeunit "Purch - Calc Disc. By Type";
EDocLineByReceipt: Query "E-Doc. Line by Receipt";
LastReceiptNo: Code[20];
@@ -132,9 +133,9 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
PurchaseHeader."Pay-to Vendor No." := EDocumentPurchaseHeader."[BC] Vendor No.";
PurchaseHeader."Posting Description" := EDocumentPurchaseHeader."Posting Description";
if EDocumentPurchaseHeader."Document Date" <> 0D then
- PurchaseHeader.Validate("Document Date", EDocumentPurchaseHeader."Document Date");
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Document Date"), EDocumentPurchaseHeader."Document Date");
if EDocumentPurchaseHeader."Due Date" <> 0D then
- PurchaseHeader.Validate("Due Date", EDocumentPurchaseHeader."Due Date");
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Due Date"), EDocumentPurchaseHeader."Due Date");
VendorInvoiceNo := CopyStr(EDocumentPurchaseHeader."Sales Invoice No.", 1, MaxStrLen(PurchaseHeader."Vendor Invoice No."));
VendorLedgerEntry.SetLoadFields("Entry No.");
@@ -145,7 +146,9 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
Error(InvoiceAlreadyExistsErr, VendorInvoiceNo, EDocumentPurchaseHeader."[BC] Vendor No.");
end;
- PurchaseHeader.Validate("Vendor Invoice No.", VendorInvoiceNo);
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Vendor Invoice No."), VendorInvoiceNo);
+ if EDocumentPurchaseHeader."Purchase Order No." <> '' then
+ PurchaseHeader."Vendor Order No." := CopyStr(EDocumentPurchaseHeader."Purchase Order No.", 1, MaxStrLen(PurchaseHeader."Vendor Order No."));
PurchaseHeader.Insert(true);
PurchaseHeader."Invoice Received Date" := PurchaseHeader."Document Date";
@@ -154,7 +157,7 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
// Validate of currency has to happen after insert.
GLSetup.GetRecordOnce();
if EDocumentPurchaseHeader."Currency Code" <> GLSetup.GetCurrencyCode('') then begin
- PurchaseHeader.Validate("Currency Code", EDocumentPurchaseHeader."Currency Code");
+ EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Currency Code"), EDocumentPurchaseHeader."Currency Code");
PurchaseHeader.Modify();
end;
EDocRecordLink.InsertEDocumentHeaderLink(EDocumentPurchaseHeader, PurchaseHeader);
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al
new file mode 100644
index 0000000000..c380aee6e6
--- /dev/null
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al
@@ -0,0 +1,171 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+namespace Microsoft.eServices.EDocument.Processing.Import;
+
+using Microsoft.eServices.EDocument;
+using Microsoft.eServices.EDocument.Processing;
+using Microsoft.eServices.EDocument.Processing.Import.Purchase;
+using Microsoft.Finance.Dimension;
+using Microsoft.Foundation.Attachment;
+using Microsoft.Purchases.Document;
+using Microsoft.Purchases.Posting;
+
+///
+/// Shared logic for creating BC purchase documents (invoices and credit memos) from e-document draft data.
+///
+codeunit 6402 "E-Doc. Purch. Doc. Helper"
+{
+ Access = Internal;
+ InherentEntitlements = X;
+ InherentPermissions = X;
+ Permissions = tabledata "Dimension Set Tree Node" = im,
+ tabledata "Dimension Set Entry" = im;
+
+ procedure CreatePurchaseLineFromDraft(PurchaseHeader: Record "Purchase Header"; EDocumentPurchaseLine: Record "E-Document Purchase Line"; HasTotalDiscount: Boolean; LineNo: Integer)
+ var
+ PurchaseLine: Record "Purchase Line";
+ EDocRecordLink: Record "E-Doc. Record Link";
+ EDocumentPurchaseHistMapping: Codeunit "E-Doc. Purchase Hist. Mapping";
+ DimensionManagement: Codeunit DimensionManagement;
+ PurchaseLineCombinedDimensions: array[10] of Integer;
+ GlobalDim1, GlobalDim2 : Code[20];
+ begin
+ PurchaseLine."Document Type" := PurchaseHeader."Document Type";
+ PurchaseLine."Document No." := PurchaseHeader."No.";
+ PurchaseLine."Line No." := LineNo;
+ PurchaseLine."Unit of Measure Code" := CopyStr(EDocumentPurchaseLine."[BC] Unit of Measure", 1, MaxStrLen(PurchaseLine."Unit of Measure Code"));
+ PurchaseLine."Variant Code" := EDocumentPurchaseLine."[BC] Variant Code";
+ PurchaseLine.Type := EDocumentPurchaseLine."[BC] Purchase Line Type";
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("No."), EDocumentPurchaseLine."[BC] Purchase Type No.");
+ if (PurchaseLine.Type = PurchaseLine.Type::"G/L Account") and HasTotalDiscount then
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Allow Invoice Disc."), true);
+ PurchaseLine.Description := EDocumentPurchaseLine.Description;
+
+ if EDocumentPurchaseLine."[BC] Item Reference No." <> '' then
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Item Reference No."), EDocumentPurchaseLine."[BC] Item Reference No.");
+
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo(Quantity), EDocumentPurchaseLine.Quantity);
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Direct Unit Cost"), EDocumentPurchaseLine."Unit Price");
+ if EDocumentPurchaseLine."Total Discount" > 0 then
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Line Discount Amount"), EDocumentPurchaseLine."Total Discount");
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Deferral Code"), EDocumentPurchaseLine."[BC] Deferral Code");
+
+ PurchaseLineCombinedDimensions[1] := PurchaseLine."Dimension Set ID";
+ PurchaseLineCombinedDimensions[2] := EDocumentPurchaseLine."[BC] Dimension Set ID";
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Dimension Set ID"), DimensionManagement.GetCombinedDimensionSetID(PurchaseLineCombinedDimensions, GlobalDim1, GlobalDim2));
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Shortcut Dimension 1 Code"), EDocumentPurchaseLine."[BC] Shortcut Dimension 1 Code");
+ ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Shortcut Dimension 2 Code"), EDocumentPurchaseLine."[BC] Shortcut Dimension 2 Code");
+ EDocumentPurchaseHistMapping.ApplyAdditionalFieldsFromHistoryToPurchaseLine(EDocumentPurchaseLine, PurchaseLine);
+ PurchaseLine.Insert();
+ EDocRecordLink.InsertEDocumentLineLink(EDocumentPurchaseLine, PurchaseLine);
+ end;
+
+ procedure ValidateFieldWithContext(var Rec: Record "Purchase Header"; FieldNo: Integer; Value: Variant)
+ var
+ VariantRec: Variant;
+ begin
+ VariantRec := Rec;
+ ValidateFieldWithContext(VariantRec, FieldNo, Value);
+ Rec := VariantRec;
+ end;
+
+ procedure ValidateFieldWithContext(var Rec: Record "Purchase Line"; FieldNo: Integer; Value: Variant)
+ var
+ VariantRec: Variant;
+ begin
+ VariantRec := Rec;
+ ValidateFieldWithContext(VariantRec, FieldNo, Value);
+ Rec := VariantRec;
+ end;
+
+ local procedure ValidateFieldWithContext(var RecVariant: Variant; FieldNo: Integer; Value: Variant)
+ var
+ EDocImportErrorContext: Codeunit "E-Doc. Import Error Context";
+ RecRef: RecordRef;
+ FldRef: FieldRef;
+ begin
+ RecRef.GetTable(RecVariant);
+ FldRef := RecRef.Field(FieldNo);
+ EDocImportErrorContext.OnValidateFieldWithContext(FldRef.Caption());
+ FldRef.Validate(Value);
+ RecRef.SetTable(RecVariant);
+ end;
+
+ procedure AllDraftLinesHaveTypeAndNumber(EDocumentPurchaseHeader: Record "E-Document Purchase Header"): Boolean
+ var
+ EDocumentPurchaseLine: Record "E-Document Purchase Line";
+ begin
+ EDocumentPurchaseLine.SetLoadFields("[BC] Purchase Line Type", "[BC] Purchase Type No.");
+ EDocumentPurchaseLine.ReadIsolation(IsolationLevel::ReadCommitted);
+ EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocumentPurchaseHeader."E-Document Entry No.");
+ if not EDocumentPurchaseLine.FindSet() then
+ exit(true);
+ repeat
+ if EDocumentPurchaseLine."[BC] Purchase Line Type" = EDocumentPurchaseLine."[BC] Purchase Line Type"::" " then
+ exit(false);
+ if EDocumentPurchaseLine."[BC] Purchase Type No." = '' then
+ exit(false);
+ until EDocumentPurchaseLine.Next() = 0;
+ exit(true);
+ end;
+
+ [TryFunction]
+ procedure TryValidateDocumentTotals(PurchaseHeader: Record "Purchase Header")
+ var
+ PurchPost: Codeunit "Purch.-Post";
+ begin
+ PurchPost.CheckDocumentTotalAmounts(PurchaseHeader);
+ end;
+
+ procedure GetLastPurchaseLineNo(DocumentType: Enum "Purchase Document Type"; DocumentNo: Code[20]): Integer
+ var
+ PurchaseLine: Record "Purchase Line";
+ begin
+ PurchaseLine.SetLoadFields("Line No.");
+ PurchaseLine.ReadIsolation := IsolationLevel::ReadUncommitted;
+ PurchaseLine.SetRange("Document Type", DocumentType);
+ PurchaseLine.SetRange("Document No.", DocumentNo);
+ if PurchaseLine.FindLast() then
+ exit(PurchaseLine."Line No.");
+ end;
+
+ procedure FinalizeCreatedDocument(EDocument: Record "E-Document"; var PurchaseHeader: Record "Purchase Header")
+ var
+ EDocumentPurchaseHeader: Record "E-Document Purchase Header";
+ DocumentAttachmentMgt: Codeunit "Document Attachment Mgmt";
+ EDocImpSessionTelemetry: Codeunit "E-Doc. Imp. Session Telemetry";
+ begin
+ EDocumentPurchaseHeader.GetFromEDocument(EDocument);
+
+ PurchaseHeader.SetRecFilter();
+ PurchaseHeader.FindFirst();
+ PurchaseHeader."Doc. Amount Incl. VAT" := EDocumentPurchaseHeader.Total;
+ PurchaseHeader."Doc. Amount VAT" := EDocumentPurchaseHeader."Total VAT";
+ PurchaseHeader.TestField("No.");
+ PurchaseHeader."E-Document Link" := EDocument.SystemId;
+ PurchaseHeader.Modify();
+
+ DocumentAttachmentMgt.CopyAttachments(EDocument, PurchaseHeader);
+ DocumentAttachmentMgt.DeleteAttachedDocuments(EDocument);
+
+ EDocImpSessionTelemetry.SetBool('Totals Validation', TryValidateDocumentTotals(PurchaseHeader));
+ end;
+
+ procedure RevertCreatedDocument(EDocument: Record "E-Document")
+ var
+ PurchaseHeader: Record "Purchase Header";
+ DocumentAttachmentMgt: Codeunit "Document Attachment Mgmt";
+ begin
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ if not PurchaseHeader.FindFirst() then
+ exit;
+
+ DocumentAttachmentMgt.CopyAttachments(PurchaseHeader, EDocument);
+ DocumentAttachmentMgt.DeleteAttachedDocuments(PurchaseHeader);
+
+ Clear(PurchaseHeader."E-Document Link");
+ PurchaseHeader.Modify();
+ end;
+}
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al
index 8b2e8ffbdb..80786575f1 100644
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/Purchase/History/EDocPurchaseHistMapping.Codeunit.al
@@ -212,8 +212,10 @@ codeunit 6120 "E-Doc. Purchase Hist. Mapping"
var
EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
EDocPurchLineField: Record "E-Document Line - Field";
+ EDocImportErrorContext: Codeunit "E-Doc. Import Error Context";
NewPurchLineRecordRef: RecordRef;
NewPurchLineFieldRef: FieldRef;
+ FieldValue: Variant;
begin
if not EDocPurchLineFieldSetup.FindSet() then
exit;
@@ -223,7 +225,10 @@ codeunit 6120 "E-Doc. Purchase Hist. Mapping"
continue;
EDocPurchLineField.Get(EDocumentPurchaseLine, EDocPurchLineFieldSetup);
NewPurchLineFieldRef := NewPurchLineRecordRef.Field(EDocPurchLineFieldSetup."Field No.");
- NewPurchLineFieldRef.Validate(EDocPurchLineField.GetValue());
+ FieldValue := EDocPurchLineField.GetValue();
+ EDocImportErrorContext.OnSetAdditionalFieldContext(NewPurchLineFieldRef.Name(), EDocPurchLineFieldSetup."Field No.", EDocPurchLineField.GetValueAsText());
+ NewPurchLineFieldRef.Validate(FieldValue);
+ EDocImportErrorContext.ClearAdditionalFieldContext();
until EDocPurchLineFieldSetup.Next() = 0;
NewPurchLineRecordRef.SetTable(PurchaseLine);
end;
diff --git a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
index 82e79a65fb..6b5953545d 100644
--- a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
+++ b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
@@ -25,11 +25,13 @@ using Microsoft.Purchases.Vendor;
using Microsoft.Sales.Customer;
using System.IO;
using System.TestLibraries.Utilities;
+using System.Utilities;
codeunit 139883 "E-Doc Process Test"
{
Subtype = Test;
TestType = IntegrationTest;
+ TestPermissions = Disabled;
var
Customer: Record Customer;
@@ -581,6 +583,333 @@ codeunit 139883 "E-Doc Process Test"
Assert.AreNotEqual(Location.Code, PurchaseLine."Location Code", 'The location code should not be set on the purchase line.');
end;
+ [Test]
+ procedure AdditionalFieldWithInvalidValueEnrichesErrorMessage()
+ var
+ EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
+ PurchaseInvoiceLine: Record "Purch. Inv. Line";
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ PurchaseHeader: Record "Purchase Header";
+ EDocPurchLineField: Record "E-Document Line - Field";
+ EDocPurchaseLine: Record "E-Document Purchase Line";
+ ErrorMessage: Record "Error Message";
+ EDocImport: Codeunit "E-Doc. Import";
+ EDocumentErrorHelper: Codeunit "E-Document Error Helper";
+ begin
+ // [SCENARIO] An additional field is configured with an invalid value that fails FieldRef.Validate.
+ // The error message should contain the additional field name, ID, and value.
+ Initialize(Enum::"Service Integration"::"Mock");
+
+ // [GIVEN] An additional field is configured for Location Code (Code[10])
+ EDocPurchLineFieldSetup."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineFieldSetup.Insert();
+
+ // [GIVEN] An inbound e-document is received and a draft created
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+
+ // [GIVEN] A value that does not exist as a Location Code
+ EDocPurchLineField."E-Document Entry No." := EDocument."Entry No";
+ EDocPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
+ EDocPurchaseLine.FindFirst();
+ EDocPurchLineField."Line No." := EDocPurchaseLine."Line No.";
+ EDocPurchLineField."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineField."Code Value" := 'INVALID';
+ EDocPurchLineField.Insert();
+
+ // [WHEN] Finalizing the draft
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+
+ // [THEN] The e-document should have an error
+ EDocument.Get(EDocument."Entry No");
+ Assert.IsTrue(EDocumentErrorHelper.HasErrors(EDocument), 'The e-document should have errors');
+
+ // [THEN] The error message should reference the additional field name, ID, and value
+ ErrorMessage.SetRange("Context Record ID", EDocument.RecordId());
+ ErrorMessage.SetRange("Message Type", ErrorMessage."Message Type"::Error);
+ ErrorMessage.FindFirst();
+ Assert.ExpectedMessage('While applying additional field "Location Code"', ErrorMessage."Message");
+ Assert.ExpectedMessage(Format(PurchaseInvoiceLine.FieldNo("Location Code")), ErrorMessage."Message");
+ Assert.ExpectedMessage('INVALID', ErrorMessage."Message");
+
+ // [THEN] No purchase invoice should have been created
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ Assert.RecordIsEmpty(PurchaseHeader);
+ end;
+
+ [Test]
+ procedure AdditionalFieldValueExceedingFieldLengthEnrichesErrorMessage()
+ var
+ EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
+ PurchaseInvoiceLine: Record "Purch. Inv. Line";
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ PurchaseHeader: Record "Purchase Header";
+ EDocPurchLineField: Record "E-Document Line - Field";
+ EDocPurchaseLine: Record "E-Document Purchase Line";
+ ErrorMessage: Record "Error Message";
+ EDocImport: Codeunit "E-Doc. Import";
+ EDocumentErrorHelper: Codeunit "E-Document Error Helper";
+ FieldValue: Code[2048];
+ begin
+ // [SCENARIO] An additional field is configured with a value that exceeds the target field's maximum length.
+ // The error message should reference the additional field name, ID, and the overlong value.
+ Initialize(Enum::"Service Integration"::"Mock");
+
+ // [GIVEN] An additional field is configured for Location Code (Code[10])
+ EDocPurchLineFieldSetup."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineFieldSetup.Insert();
+
+ // [GIVEN] An inbound e-document is received and a draft created
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+
+ // [GIVEN] A value that exceeds the target field length (Code[10])
+ FieldValue := 'LONGLOCCODE1'; // 12 characters, exceeds Code[10]
+ EDocPurchLineField."E-Document Entry No." := EDocument."Entry No";
+ EDocPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
+ EDocPurchaseLine.FindFirst();
+ EDocPurchLineField."Line No." := EDocPurchaseLine."Line No.";
+ EDocPurchLineField."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineField."Code Value" := FieldValue;
+ EDocPurchLineField.Insert();
+
+ // [WHEN] Finalizing the draft
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+
+ // [THEN] The e-document should have an error
+ EDocument.Get(EDocument."Entry No");
+ Assert.IsTrue(EDocumentErrorHelper.HasErrors(EDocument), 'The e-document should have errors');
+
+ // [THEN] The error message should reference the additional field name and value
+ ErrorMessage.SetRange("Context Record ID", EDocument.RecordId());
+ ErrorMessage.SetRange("Message Type", ErrorMessage."Message Type"::Error);
+ ErrorMessage.FindFirst();
+ Assert.ExpectedMessage('While applying additional field "Location Code"', ErrorMessage."Message");
+ Assert.ExpectedMessage(FieldValue, ErrorMessage."Message");
+
+ // [THEN] No purchase invoice should have been created
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ Assert.RecordIsEmpty(PurchaseHeader);
+ end;
+
+ [Test]
+ procedure StandardFieldValidationFailureEnrichesErrorMessage()
+ var
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocumentPurchaseHeader: Record "E-Document Purchase Header";
+ PurchaseHeader: Record "Purchase Header";
+ ErrorMessage: Record "Error Message";
+ EDocImport: Codeunit "E-Doc. Import";
+ EDocumentErrorHelper: Codeunit "E-Document Error Helper";
+ begin
+ // [SCENARIO] A standard field validation fails during purchase invoice creation.
+ // The error message should contain the field caption.
+ Initialize(Enum::"Service Integration"::"Mock");
+
+ // [GIVEN] An inbound e-document is received and a draft created
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+
+ // [GIVEN] The draft has an invalid currency code
+ EDocumentPurchaseHeader.GetFromEDocument(EDocument);
+ EDocumentPurchaseHeader."Currency Code" := 'INVCURR';
+ EDocumentPurchaseHeader.Modify();
+
+ // [WHEN] Finalizing the draft
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+
+ // [THEN] The e-document should have an error
+ EDocument.Get(EDocument."Entry No");
+ Assert.IsTrue(EDocumentErrorHelper.HasErrors(EDocument), 'The e-document should have errors');
+
+ // [THEN] The error message should reference the Currency Code field
+ ErrorMessage.SetRange("Context Record ID", EDocument.RecordId());
+ ErrorMessage.SetRange("Message Type", ErrorMessage."Message Type"::Error);
+ ErrorMessage.FindFirst();
+ Assert.ExpectedMessage('While validating field "Currency Code"', ErrorMessage."Message");
+
+ // [THEN] No purchase invoice should have been created
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ Assert.RecordIsEmpty(PurchaseHeader);
+ end;
+
+ [Test]
+ procedure SuccessfulImportWithAdditionalFieldsHasNoErrors()
+ var
+ EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
+ PurchaseInvoiceLine: Record "Purch. Inv. Line";
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ PurchaseHeader: Record "Purchase Header";
+ EDocPurchLineField: Record "E-Document Line - Field";
+ EDocPurchaseLine: Record "E-Document Purchase Line";
+ ErrorMessage: Record "Error Message";
+ Location: Record Location;
+ EDocImport: Codeunit "E-Doc. Import";
+ EDocumentErrorHelper: Codeunit "E-Document Error Helper";
+ begin
+ // [SCENARIO] Additional fields are configured with valid values.
+ // The import should succeed with no errors or warnings.
+ Initialize(Enum::"Service Integration"::"Mock");
+
+ // [GIVEN] An additional field is configured for Location Code
+ EDocPurchLineFieldSetup."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineFieldSetup.Insert();
+
+ // [GIVEN] A valid location exists
+ Location.Code := 'VALIDLOC';
+ if Location.Insert() then;
+
+ // [GIVEN] An inbound e-document is received and a draft created
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+
+ // [GIVEN] The additional field has a valid value
+ EDocPurchLineField."E-Document Entry No." := EDocument."Entry No";
+ EDocPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
+ EDocPurchaseLine.FindFirst();
+ EDocPurchLineField."Line No." := EDocPurchaseLine."Line No.";
+ EDocPurchLineField."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineField."Code Value" := 'VALIDLOC';
+ EDocPurchLineField.Insert();
+
+ // [WHEN] Finalizing the draft
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ Assert.IsTrue(EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams), 'The finalization should succeed');
+
+ // [THEN] The e-document should have no errors
+ EDocument.Get(EDocument."Entry No");
+ Assert.IsFalse(EDocumentErrorHelper.HasErrors(EDocument), 'The e-document should not have errors');
+
+ // [THEN] No error or warning messages should exist
+ ErrorMessage.SetRange("Context Record ID", EDocument.RecordId());
+ Assert.RecordIsEmpty(ErrorMessage);
+
+ // [THEN] A purchase invoice should have been created
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ Assert.RecordIsNotEmpty(PurchaseHeader);
+ end;
+
+ [Test]
+ procedure MultipleAdditionalFieldsFailureOnSecondHasCorrectContext()
+ var
+ EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
+ PurchaseInvoiceLine: Record "Purch. Inv. Line";
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ PurchaseHeader: Record "Purchase Header";
+ EDocPurchLineField: Record "E-Document Line - Field";
+ EDocPurchaseLine: Record "E-Document Purchase Line";
+ ErrorMessage: Record "Error Message";
+ Location: Record Location;
+ EDocImport: Codeunit "E-Doc. Import";
+ EDocumentErrorHelper: Codeunit "E-Document Error Helper";
+ begin
+ // [SCENARIO] Two additional fields are configured. The first has a valid value, the second has an invalid value.
+ // The error message should reference the second field, not the first.
+ Initialize(Enum::"Service Integration"::"Mock");
+
+ // [GIVEN] Two additional fields configured: Location Code and Bin Code
+ EDocPurchLineFieldSetup."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineFieldSetup.Insert();
+ Clear(EDocPurchLineFieldSetup);
+ EDocPurchLineFieldSetup."Field No." := PurchaseInvoiceLine.FieldNo("Bin Code");
+ EDocPurchLineFieldSetup.Insert();
+
+ // [GIVEN] A valid location exists
+ Location.Code := 'MULTILOC';
+ if Location.Insert() then;
+
+ // [GIVEN] An inbound e-document is received and a draft created
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+
+ // [GIVEN] First field (Location Code) has a valid value, second field (Bin Code) has an invalid value
+ EDocPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
+ EDocPurchaseLine.FindFirst();
+
+ EDocPurchLineField."E-Document Entry No." := EDocument."Entry No";
+ EDocPurchLineField."Line No." := EDocPurchaseLine."Line No.";
+ EDocPurchLineField."Field No." := PurchaseInvoiceLine.FieldNo("Location Code");
+ EDocPurchLineField."Code Value" := 'MULTILOC';
+ EDocPurchLineField.Insert();
+
+ Clear(EDocPurchLineField);
+ EDocPurchLineField."E-Document Entry No." := EDocument."Entry No";
+ EDocPurchLineField."Line No." := EDocPurchaseLine."Line No.";
+ EDocPurchLineField."Field No." := PurchaseInvoiceLine.FieldNo("Bin Code");
+ EDocPurchLineField."Code Value" := 'INVALIDBIN';
+ EDocPurchLineField.Insert();
+
+ // [WHEN] Finalizing the draft
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+
+ // [THEN] The e-document should have an error
+ EDocument.Get(EDocument."Entry No");
+ Assert.IsTrue(EDocumentErrorHelper.HasErrors(EDocument), 'The e-document should have errors');
+
+ // [THEN] The error message should reference the second field (Bin Code), not the first (Location Code)
+ ErrorMessage.SetRange("Context Record ID", EDocument.RecordId());
+ ErrorMessage.SetRange("Message Type", ErrorMessage."Message Type"::Error);
+ ErrorMessage.FindFirst();
+ Assert.ExpectedMessage('Bin Code', ErrorMessage."Message");
+ Assert.ExpectedMessage('INVALIDBIN', ErrorMessage."Message");
+
+ // [THEN] No purchase invoice should have been created
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ Assert.RecordIsEmpty(PurchaseHeader);
+ end;
+
+ [Test]
+ procedure NoAdditionalFieldsStandardFieldFailureStillEnriched()
+ var
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocumentPurchaseHeader: Record "E-Document Purchase Header";
+ PurchaseHeader: Record "Purchase Header";
+ ErrorMessage: Record "Error Message";
+ EDocImport: Codeunit "E-Doc. Import";
+ EDocumentErrorHelper: Codeunit "E-Document Error Helper";
+ begin
+ // [SCENARIO] No additional fields are configured. A standard field validation fails.
+ // The error message should still be enriched with the field context.
+ Initialize(Enum::"Service Integration"::"Mock");
+
+ // [GIVEN] An inbound e-document is received and a draft created (no additional fields configured)
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+
+ // [GIVEN] The draft has an invalid currency code
+ EDocumentPurchaseHeader.GetFromEDocument(EDocument);
+ EDocumentPurchaseHeader."Currency Code" := 'BADCURR';
+ EDocumentPurchaseHeader.Modify();
+
+ // [WHEN] Finalizing the draft
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+
+ // [THEN] The e-document should have an error
+ EDocument.Get(EDocument."Entry No");
+ Assert.IsTrue(EDocumentErrorHelper.HasErrors(EDocument), 'The e-document should have errors');
+
+ // [THEN] The error message should contain the Currency Code field context
+ ErrorMessage.SetRange("Context Record ID", EDocument.RecordId());
+ ErrorMessage.SetRange("Message Type", ErrorMessage."Message Type"::Error);
+ ErrorMessage.FindFirst();
+ Assert.ExpectedMessage('Currency Code', ErrorMessage."Message");
+
+ // [THEN] No purchase invoice should have been created
+ PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
+ Assert.RecordIsEmpty(PurchaseHeader);
+ end;
+
[Test]
procedure PreparingPurchaseDraftFindsItemReference()
var
@@ -760,6 +1089,84 @@ codeunit 139883 "E-Doc Process Test"
EditDimensionSetEntries.OK().Invoke();
end;
+ [Test]
+ procedure ProcessingInboundCreditNoteCreatesCorrectDocumentType()
+ var
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ PurchaseHeader: Record "Purchase Header";
+ PurchaseLine: Record "Purchase Line";
+ EDocRecordLink: Record "E-Doc. Record Link";
+ begin
+ // [SCENARIO] A PEPPOL CreditNote processed through the full pipeline creates a Purchase Credit Memo with correct content
+ Initialize(Enum::"Service Integration"::"Mock");
+ EDocumentService."Read into Draft Impl." := "E-Doc. Read into Draft"::PEPPOL;
+ EDocumentService.Modify();
+
+ EDocRecordLink.DeleteAll();
+
+ // [GIVEN] An inbound credit note e-document is received and fully processed
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-creditnote-0.xml', TempEDocImportParams), 'The credit note e-document should be processed');
+
+ // [THEN] The E-Document type is Purchase Credit Memo
+ EDocument.Get(EDocument."Entry No");
+ Assert.AreEqual("E-Document Type"::"Purchase Credit Memo", EDocument."Document Type", 'The document type should be Purchase Credit Memo.');
+
+ // [THEN] A Purchase Credit Memo header is created with correct fields
+ PurchaseHeader.Get(EDocument."Document Record ID");
+ Assert.AreEqual("Purchase Document Type"::"Credit Memo", PurchaseHeader."Document Type", 'The purchase header document type should be Credit Memo.');
+ Assert.AreEqual(EDocument.SystemId, PurchaseHeader."E-Document Link", 'The E-Document link should be set on the purchase header.');
+ Assert.AreEqual('CN-5001', PurchaseHeader."Vendor Cr. Memo No.", 'The vendor credit memo number should match the CreditNote ID.');
+ Assert.AreEqual(Vendor."No.", PurchaseHeader."Buy-from Vendor No.", 'The vendor should be resolved from the CreditNote.');
+ Assert.AreEqual(2500, PurchaseHeader."Doc. Amount Incl. VAT", 'The document amount incl. VAT should match the CreditNote total.');
+ Assert.AreEqual('5', PurchaseHeader."Vendor Order No.", 'The Vendor Order No. should match the OrderReference from the CreditNote.');
+
+ // [THEN] The purchase credit memo has the correct number of lines
+ PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type");
+ PurchaseLine.SetRange("Document No.", PurchaseHeader."No.");
+ Assert.RecordCount(PurchaseLine, 1);
+
+ // [THEN] Links are created between e-document and purchase records
+ EDocRecordLink.SetRange("Target Table No.", Database::"Purchase Header");
+ EDocRecordLink.SetRange("Target SystemId", PurchaseHeader.SystemId);
+ Assert.RecordCount(EDocRecordLink, 1);
+ end;
+
+ [Test]
+ procedure ProcessingInboundInvoiceStillCreatesCorrectDocumentType()
+ var
+ EDocument: Record "E-Document";
+ TempEDocImportParams: Record "E-Doc. Import Parameters";
+ PurchaseHeader: Record "Purchase Header";
+ PurchaseLine: Record "Purchase Line";
+ begin
+ // [SCENARIO] After the refactoring, a PEPPOL Invoice still creates a Purchase Invoice with correct content (regression check)
+ Initialize(Enum::"Service Integration"::"Mock");
+ EDocumentService."Read into Draft Impl." := "E-Doc. Read into Draft"::PEPPOL;
+ EDocumentService.Modify();
+
+ TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The invoice e-document should be processed');
+
+ // [THEN] The E-Document type is Purchase Invoice
+ EDocument.Get(EDocument."Entry No");
+ Assert.AreEqual("E-Document Type"::"Purchase Invoice", EDocument."Document Type", 'The document type should be Purchase Invoice.');
+
+ // [THEN] A Purchase Invoice header is created with correct fields
+ PurchaseHeader.Get(EDocument."Document Record ID");
+ Assert.AreEqual("Purchase Document Type"::Invoice, PurchaseHeader."Document Type", 'The purchase header document type should be Invoice.');
+ Assert.AreEqual('103033', PurchaseHeader."Vendor Invoice No.", 'The vendor invoice number should match the Invoice ID.');
+ Assert.AreEqual('2', PurchaseHeader."Vendor Order No.", 'The vendor order number should match the OrderReference from the Invoice.');
+ Assert.AreEqual(Vendor."No.", PurchaseHeader."Buy-from Vendor No.", 'The vendor should be resolved from the Invoice.');
+ Assert.AreEqual(14140, PurchaseHeader."Doc. Amount Incl. VAT", 'The document amount incl. VAT should match the Invoice total.');
+
+ // [THEN] The purchase invoice has the correct number of lines (2 from peppol-invoice-0.xml)
+ PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type");
+ PurchaseLine.SetRange("Document No.", PurchaseHeader."No.");
+ Assert.RecordCount(PurchaseLine, 2);
+ end;
+
local procedure Initialize(Integration: Enum "Service Integration")
var
TransformationRule: Record "Transformation Rule";
@@ -792,7 +1199,7 @@ codeunit 139883 "E-Doc Process Test"
Currency.Init();
Currency.Validate(Code, 'XYZ');
if Currency.Insert(true) then
- LibraryERM.CreateExchangeRate(Currency.Code, WorkDate(), 1.0, 1.0);
+ LibraryERM.CreateExchangeRate(Currency.Code, Today(), 1.0, 1.0);
EDocument.DeleteAll();
EDocumentServiceStatus.DeleteAll();
From eff08fe1e76e95807c56100117b0f438ae0de7ef Mon Sep 17 00:00:00 2001
From: ventselartur
Date: Fri, 15 May 2026 13:06:12 +0200
Subject: [PATCH 2/5] remove unnecessary new file
EDocCreatePurchCrMemo.Codeunit.al
---
.../EDocCreatePurchCrMemo.Codeunit.al | 128 ------------------
1 file changed, 128 deletions(-)
delete mode 100644 src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al
deleted file mode 100644
index 77ecf97e66..0000000000
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchCrMemo.Codeunit.al
+++ /dev/null
@@ -1,128 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-namespace Microsoft.eServices.EDocument.Processing.Import;
-
-using Microsoft.eServices.EDocument;
-using Microsoft.eServices.EDocument.Processing;
-using Microsoft.eServices.EDocument.Processing.Import.Purchase;
-using Microsoft.eServices.EDocument.Processing.Interfaces;
-using Microsoft.Finance.GeneralLedger.Setup;
-using Microsoft.Purchases.Document;
-using Microsoft.Purchases.Payables;
-using System.Telemetry;
-
-///
-/// Dealing with the creation of the purchase credit memo after the draft has been populated.
-///
-codeunit 6404 "E-Doc. Create Purch. Cr. Memo" implements IEDocumentFinishDraft, IEDocumentCreatePurchaseCreditMemo
-{
- Access = Internal;
-
- var
- Telemetry: Codeunit "Telemetry";
- CrMemoAlreadyExistsErr: Label 'A purchase credit memo with external document number %1 already exists for vendor %2.', Comment = '%1 = Vendor Cr. Memo No., %2 = Vendor No.';
- DraftLineDoesNotContainTypeAndNumberErr: Label 'One of the draft lines do not contain the type and number. Please, specify these fields manually.';
-
- procedure ApplyDraftToBC(EDocument: Record "E-Document"; EDocImportParameters: Record "E-Doc. Import Parameters"): RecordId
- var
- PurchaseHeader: Record "Purchase Header";
- EDocPurchaseDocumentHelper: Codeunit "E-Doc. Purch. Doc. Helper";
- EDocImpSessionTelemetry: Codeunit "E-Doc. Imp. Session Telemetry";
- EmptyRecordId: RecordId;
- IEDocumentFinishPurchaseCrMemo: Interface IEDocumentCreatePurchaseCreditMemo;
- begin
- IEDocumentFinishPurchaseCrMemo := EDocImportParameters."Processing Customizations";
- if EDocImportParameters."Existing Doc. RecordId" <> EmptyRecordId then begin
- EDocImpSessionTelemetry.SetBool('LinkedToExisting', true);
- PurchaseHeader.Get(EDocImportParameters."Existing Doc. RecordId");
- end else
- PurchaseHeader := IEDocumentFinishPurchaseCrMemo.CreatePurchaseCreditMemo(EDocument);
-
- EDocPurchaseDocumentHelper.FinalizeCreatedDocument(EDocument, PurchaseHeader);
-
- exit(PurchaseHeader.RecordId);
- end;
-
- procedure RevertDraftActions(EDocument: Record "E-Document")
- var
- PurchaseHeader: Record "Purchase Header";
- EDocPurchaseDocumentHelper: Codeunit "E-Doc. Purch. Doc. Helper";
- begin
- PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
- if not PurchaseHeader.FindFirst() then
- exit;
-
- PurchaseHeader.TestField("Document Type", "Purchase Document Type"::"Credit Memo");
- EDocPurchaseDocumentHelper.RevertCreatedDocument(EDocument);
- end;
-
- procedure CreatePurchaseCreditMemo(EDocument: Record "E-Document"): Record "Purchase Header"
- var
- PurchaseHeader: Record "Purchase Header";
- GLSetup: Record "General Ledger Setup";
- VendorLedgerEntry: Record "Vendor Ledger Entry";
- EDocumentPurchaseHeader: Record "E-Document Purchase Header";
- EDocumentPurchaseLine: Record "E-Document Purchase Line";
- EDocRecordLink: Record "E-Doc. Record Link";
- EDocPurchaseDocumentHelper: Codeunit "E-Doc. Purch. Doc. Helper";
- PurchCalcDiscByType: Codeunit "Purch - Calc Disc. By Type";
- StopCreatingCreditMemo: Boolean;
- VendorCrMemoNo: Code[35];
- PurchaseLineNo: Integer;
- begin
- EDocumentPurchaseHeader.GetFromEDocument(EDocument);
- if not EDocPurchaseDocumentHelper.AllDraftLinesHaveTypeAndNumber(EDocumentPurchaseHeader) then begin
- Telemetry.LogMessage('0000SNH', 'Draft line does not contain type or number', Verbosity::Error, DataClassification::SystemMetadata, TelemetryScope::All);
- Error(DraftLineDoesNotContainTypeAndNumberErr);
- end;
- EDocumentPurchaseHeader.TestField("E-Document Entry No.");
- PurchaseHeader.SetRange("Buy-from Vendor No.", EDocumentPurchaseHeader."[BC] Vendor No.");
- PurchaseHeader."Document Type" := "Purchase Document Type"::"Credit Memo";
- PurchaseHeader."Pay-to Vendor No." := EDocumentPurchaseHeader."[BC] Vendor No.";
- PurchaseHeader."Posting Description" := EDocumentPurchaseHeader."Posting Description";
- if EDocumentPurchaseHeader."Document Date" <> 0D then
- EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Document Date"), EDocumentPurchaseHeader."Document Date");
- if EDocumentPurchaseHeader."Due Date" <> 0D then
- EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Due Date"), EDocumentPurchaseHeader."Due Date");
-
- VendorCrMemoNo := CopyStr(EDocumentPurchaseHeader."Sales Invoice No.", 1, MaxStrLen(PurchaseHeader."Vendor Cr. Memo No."));
- VendorLedgerEntry.SetLoadFields("Entry No.");
- VendorLedgerEntry.ReadIsolation := VendorLedgerEntry.ReadIsolation::ReadUncommitted;
- StopCreatingCreditMemo := PurchaseHeader.FindPostedDocumentWithSameExternalDocNo(VendorLedgerEntry, VendorCrMemoNo);
- if StopCreatingCreditMemo then begin
- Telemetry.LogMessage('0000SNI', CrMemoAlreadyExistsErr, Verbosity::Error, DataClassification::OrganizationIdentifiableInformation, TelemetryScope::All);
- Error(CrMemoAlreadyExistsErr, VendorCrMemoNo, EDocumentPurchaseHeader."[BC] Vendor No.");
- end;
-
- EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Vendor Cr. Memo No."), VendorCrMemoNo);
- if EDocumentPurchaseHeader."Purchase Order No." <> '' then
- PurchaseHeader."Vendor Order No." := CopyStr(EDocumentPurchaseHeader."Purchase Order No.", 1, MaxStrLen(PurchaseHeader."Vendor Order No."));
- PurchaseHeader.Insert(true);
- PurchaseHeader.Modify();
-
- GLSetup.GetRecordOnce();
- if EDocumentPurchaseHeader."Currency Code" <> GLSetup.GetCurrencyCode('') then
- EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Currency Code"), EDocumentPurchaseHeader."Currency Code");
-
- if EDocumentPurchaseHeader."Applies-to Doc. No." <> '' then
- PurchaseHeader."Applies-to Doc. No." := CopyStr(EDocumentPurchaseHeader."Applies-to Doc. No.", 1, MaxStrLen(PurchaseHeader."Applies-to Doc. No."));
-
- PurchaseHeader.Modify();
-
- EDocRecordLink.InsertEDocumentHeaderLink(EDocumentPurchaseHeader, PurchaseHeader);
-
- PurchaseLineNo := EDocPurchaseDocumentHelper.GetLastPurchaseLineNo("Purchase Document Type"::"Credit Memo", PurchaseHeader."No.");
- EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
- if EDocumentPurchaseLine.FindSet() then
- repeat
- PurchaseLineNo += 10000;
- EDocPurchaseDocumentHelper.CreatePurchaseLineFromDraft(PurchaseHeader, EDocumentPurchaseLine, EDocumentPurchaseHeader."Total Discount" > 0, PurchaseLineNo);
- until EDocumentPurchaseLine.Next() = 0;
-
- PurchaseHeader.Modify();
- PurchCalcDiscByType.ApplyInvDiscBasedOnAmt(EDocumentPurchaseHeader."Total Discount", PurchaseHeader);
- exit(PurchaseHeader);
- end;
-}
From 6679521b9bc2b3d3debe8d8065e3ebe4fad318b9 Mon Sep 17 00:00:00 2001
From: ventselartur
Date: Fri, 15 May 2026 13:19:52 +0200
Subject: [PATCH 3/5] remove unused references
---
.../EDocCreatePurchaseInvoice.Codeunit.al | 2 -
.../EDocPurchDocHelper.Codeunit.al | 132 ------------------
.../Processing/EDocProcessTest.Codeunit.al | 78 -----------
3 files changed, 212 deletions(-)
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
index a896f0d4d1..b684b1fcfd 100644
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocCreatePurchaseInvoice.Codeunit.al
@@ -147,8 +147,6 @@ codeunit 6117 "E-Doc. Create Purchase Invoice" implements IEDocumentFinishDraft,
end;
EDocPurchaseDocumentHelper.ValidateFieldWithContext(PurchaseHeader, PurchaseHeader.FieldNo("Vendor Invoice No."), VendorInvoiceNo);
- if EDocumentPurchaseHeader."Purchase Order No." <> '' then
- PurchaseHeader."Vendor Order No." := CopyStr(EDocumentPurchaseHeader."Purchase Order No.", 1, MaxStrLen(PurchaseHeader."Vendor Order No."));
PurchaseHeader.Insert(true);
PurchaseHeader."Invoice Received Date" := PurchaseHeader."Document Date";
diff --git a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al
index c380aee6e6..007eb6dd13 100644
--- a/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al
+++ b/src/Apps/W1/EDocument/App/src/Processing/Import/FinishDraft/EDocPurchDocHelper.Codeunit.al
@@ -4,13 +4,7 @@
// ------------------------------------------------------------------------------------------------
namespace Microsoft.eServices.EDocument.Processing.Import;
-using Microsoft.eServices.EDocument;
-using Microsoft.eServices.EDocument.Processing;
-using Microsoft.eServices.EDocument.Processing.Import.Purchase;
-using Microsoft.Finance.Dimension;
-using Microsoft.Foundation.Attachment;
using Microsoft.Purchases.Document;
-using Microsoft.Purchases.Posting;
///
/// Shared logic for creating BC purchase documents (invoices and credit memos) from e-document draft data.
@@ -20,47 +14,6 @@ codeunit 6402 "E-Doc. Purch. Doc. Helper"
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;
- Permissions = tabledata "Dimension Set Tree Node" = im,
- tabledata "Dimension Set Entry" = im;
-
- procedure CreatePurchaseLineFromDraft(PurchaseHeader: Record "Purchase Header"; EDocumentPurchaseLine: Record "E-Document Purchase Line"; HasTotalDiscount: Boolean; LineNo: Integer)
- var
- PurchaseLine: Record "Purchase Line";
- EDocRecordLink: Record "E-Doc. Record Link";
- EDocumentPurchaseHistMapping: Codeunit "E-Doc. Purchase Hist. Mapping";
- DimensionManagement: Codeunit DimensionManagement;
- PurchaseLineCombinedDimensions: array[10] of Integer;
- GlobalDim1, GlobalDim2 : Code[20];
- begin
- PurchaseLine."Document Type" := PurchaseHeader."Document Type";
- PurchaseLine."Document No." := PurchaseHeader."No.";
- PurchaseLine."Line No." := LineNo;
- PurchaseLine."Unit of Measure Code" := CopyStr(EDocumentPurchaseLine."[BC] Unit of Measure", 1, MaxStrLen(PurchaseLine."Unit of Measure Code"));
- PurchaseLine."Variant Code" := EDocumentPurchaseLine."[BC] Variant Code";
- PurchaseLine.Type := EDocumentPurchaseLine."[BC] Purchase Line Type";
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("No."), EDocumentPurchaseLine."[BC] Purchase Type No.");
- if (PurchaseLine.Type = PurchaseLine.Type::"G/L Account") and HasTotalDiscount then
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Allow Invoice Disc."), true);
- PurchaseLine.Description := EDocumentPurchaseLine.Description;
-
- if EDocumentPurchaseLine."[BC] Item Reference No." <> '' then
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Item Reference No."), EDocumentPurchaseLine."[BC] Item Reference No.");
-
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo(Quantity), EDocumentPurchaseLine.Quantity);
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Direct Unit Cost"), EDocumentPurchaseLine."Unit Price");
- if EDocumentPurchaseLine."Total Discount" > 0 then
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Line Discount Amount"), EDocumentPurchaseLine."Total Discount");
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Deferral Code"), EDocumentPurchaseLine."[BC] Deferral Code");
-
- PurchaseLineCombinedDimensions[1] := PurchaseLine."Dimension Set ID";
- PurchaseLineCombinedDimensions[2] := EDocumentPurchaseLine."[BC] Dimension Set ID";
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Dimension Set ID"), DimensionManagement.GetCombinedDimensionSetID(PurchaseLineCombinedDimensions, GlobalDim1, GlobalDim2));
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Shortcut Dimension 1 Code"), EDocumentPurchaseLine."[BC] Shortcut Dimension 1 Code");
- ValidateFieldWithContext(PurchaseLine, PurchaseLine.FieldNo("Shortcut Dimension 2 Code"), EDocumentPurchaseLine."[BC] Shortcut Dimension 2 Code");
- EDocumentPurchaseHistMapping.ApplyAdditionalFieldsFromHistoryToPurchaseLine(EDocumentPurchaseLine, PurchaseLine);
- PurchaseLine.Insert();
- EDocRecordLink.InsertEDocumentLineLink(EDocumentPurchaseLine, PurchaseLine);
- end;
procedure ValidateFieldWithContext(var Rec: Record "Purchase Header"; FieldNo: Integer; Value: Variant)
var
@@ -71,15 +24,6 @@ codeunit 6402 "E-Doc. Purch. Doc. Helper"
Rec := VariantRec;
end;
- procedure ValidateFieldWithContext(var Rec: Record "Purchase Line"; FieldNo: Integer; Value: Variant)
- var
- VariantRec: Variant;
- begin
- VariantRec := Rec;
- ValidateFieldWithContext(VariantRec, FieldNo, Value);
- Rec := VariantRec;
- end;
-
local procedure ValidateFieldWithContext(var RecVariant: Variant; FieldNo: Integer; Value: Variant)
var
EDocImportErrorContext: Codeunit "E-Doc. Import Error Context";
@@ -92,80 +36,4 @@ codeunit 6402 "E-Doc. Purch. Doc. Helper"
FldRef.Validate(Value);
RecRef.SetTable(RecVariant);
end;
-
- procedure AllDraftLinesHaveTypeAndNumber(EDocumentPurchaseHeader: Record "E-Document Purchase Header"): Boolean
- var
- EDocumentPurchaseLine: Record "E-Document Purchase Line";
- begin
- EDocumentPurchaseLine.SetLoadFields("[BC] Purchase Line Type", "[BC] Purchase Type No.");
- EDocumentPurchaseLine.ReadIsolation(IsolationLevel::ReadCommitted);
- EDocumentPurchaseLine.SetRange("E-Document Entry No.", EDocumentPurchaseHeader."E-Document Entry No.");
- if not EDocumentPurchaseLine.FindSet() then
- exit(true);
- repeat
- if EDocumentPurchaseLine."[BC] Purchase Line Type" = EDocumentPurchaseLine."[BC] Purchase Line Type"::" " then
- exit(false);
- if EDocumentPurchaseLine."[BC] Purchase Type No." = '' then
- exit(false);
- until EDocumentPurchaseLine.Next() = 0;
- exit(true);
- end;
-
- [TryFunction]
- procedure TryValidateDocumentTotals(PurchaseHeader: Record "Purchase Header")
- var
- PurchPost: Codeunit "Purch.-Post";
- begin
- PurchPost.CheckDocumentTotalAmounts(PurchaseHeader);
- end;
-
- procedure GetLastPurchaseLineNo(DocumentType: Enum "Purchase Document Type"; DocumentNo: Code[20]): Integer
- var
- PurchaseLine: Record "Purchase Line";
- begin
- PurchaseLine.SetLoadFields("Line No.");
- PurchaseLine.ReadIsolation := IsolationLevel::ReadUncommitted;
- PurchaseLine.SetRange("Document Type", DocumentType);
- PurchaseLine.SetRange("Document No.", DocumentNo);
- if PurchaseLine.FindLast() then
- exit(PurchaseLine."Line No.");
- end;
-
- procedure FinalizeCreatedDocument(EDocument: Record "E-Document"; var PurchaseHeader: Record "Purchase Header")
- var
- EDocumentPurchaseHeader: Record "E-Document Purchase Header";
- DocumentAttachmentMgt: Codeunit "Document Attachment Mgmt";
- EDocImpSessionTelemetry: Codeunit "E-Doc. Imp. Session Telemetry";
- begin
- EDocumentPurchaseHeader.GetFromEDocument(EDocument);
-
- PurchaseHeader.SetRecFilter();
- PurchaseHeader.FindFirst();
- PurchaseHeader."Doc. Amount Incl. VAT" := EDocumentPurchaseHeader.Total;
- PurchaseHeader."Doc. Amount VAT" := EDocumentPurchaseHeader."Total VAT";
- PurchaseHeader.TestField("No.");
- PurchaseHeader."E-Document Link" := EDocument.SystemId;
- PurchaseHeader.Modify();
-
- DocumentAttachmentMgt.CopyAttachments(EDocument, PurchaseHeader);
- DocumentAttachmentMgt.DeleteAttachedDocuments(EDocument);
-
- EDocImpSessionTelemetry.SetBool('Totals Validation', TryValidateDocumentTotals(PurchaseHeader));
- end;
-
- procedure RevertCreatedDocument(EDocument: Record "E-Document")
- var
- PurchaseHeader: Record "Purchase Header";
- DocumentAttachmentMgt: Codeunit "Document Attachment Mgmt";
- begin
- PurchaseHeader.SetRange("E-Document Link", EDocument.SystemId);
- if not PurchaseHeader.FindFirst() then
- exit;
-
- DocumentAttachmentMgt.CopyAttachments(PurchaseHeader, EDocument);
- DocumentAttachmentMgt.DeleteAttachedDocuments(PurchaseHeader);
-
- Clear(PurchaseHeader."E-Document Link");
- PurchaseHeader.Modify();
- end;
}
diff --git a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
index 6b5953545d..384b46cd55 100644
--- a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
+++ b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
@@ -1089,84 +1089,6 @@ codeunit 139883 "E-Doc Process Test"
EditDimensionSetEntries.OK().Invoke();
end;
- [Test]
- procedure ProcessingInboundCreditNoteCreatesCorrectDocumentType()
- var
- EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
- PurchaseHeader: Record "Purchase Header";
- PurchaseLine: Record "Purchase Line";
- EDocRecordLink: Record "E-Doc. Record Link";
- begin
- // [SCENARIO] A PEPPOL CreditNote processed through the full pipeline creates a Purchase Credit Memo with correct content
- Initialize(Enum::"Service Integration"::"Mock");
- EDocumentService."Read into Draft Impl." := "E-Doc. Read into Draft"::PEPPOL;
- EDocumentService.Modify();
-
- EDocRecordLink.DeleteAll();
-
- // [GIVEN] An inbound credit note e-document is received and fully processed
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-creditnote-0.xml', TempEDocImportParams), 'The credit note e-document should be processed');
-
- // [THEN] The E-Document type is Purchase Credit Memo
- EDocument.Get(EDocument."Entry No");
- Assert.AreEqual("E-Document Type"::"Purchase Credit Memo", EDocument."Document Type", 'The document type should be Purchase Credit Memo.');
-
- // [THEN] A Purchase Credit Memo header is created with correct fields
- PurchaseHeader.Get(EDocument."Document Record ID");
- Assert.AreEqual("Purchase Document Type"::"Credit Memo", PurchaseHeader."Document Type", 'The purchase header document type should be Credit Memo.');
- Assert.AreEqual(EDocument.SystemId, PurchaseHeader."E-Document Link", 'The E-Document link should be set on the purchase header.');
- Assert.AreEqual('CN-5001', PurchaseHeader."Vendor Cr. Memo No.", 'The vendor credit memo number should match the CreditNote ID.');
- Assert.AreEqual(Vendor."No.", PurchaseHeader."Buy-from Vendor No.", 'The vendor should be resolved from the CreditNote.');
- Assert.AreEqual(2500, PurchaseHeader."Doc. Amount Incl. VAT", 'The document amount incl. VAT should match the CreditNote total.');
- Assert.AreEqual('5', PurchaseHeader."Vendor Order No.", 'The Vendor Order No. should match the OrderReference from the CreditNote.');
-
- // [THEN] The purchase credit memo has the correct number of lines
- PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type");
- PurchaseLine.SetRange("Document No.", PurchaseHeader."No.");
- Assert.RecordCount(PurchaseLine, 1);
-
- // [THEN] Links are created between e-document and purchase records
- EDocRecordLink.SetRange("Target Table No.", Database::"Purchase Header");
- EDocRecordLink.SetRange("Target SystemId", PurchaseHeader.SystemId);
- Assert.RecordCount(EDocRecordLink, 1);
- end;
-
- [Test]
- procedure ProcessingInboundInvoiceStillCreatesCorrectDocumentType()
- var
- EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
- PurchaseHeader: Record "Purchase Header";
- PurchaseLine: Record "Purchase Line";
- begin
- // [SCENARIO] After the refactoring, a PEPPOL Invoice still creates a Purchase Invoice with correct content (regression check)
- Initialize(Enum::"Service Integration"::"Mock");
- EDocumentService."Read into Draft Impl." := "E-Doc. Read into Draft"::PEPPOL;
- EDocumentService.Modify();
-
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The invoice e-document should be processed');
-
- // [THEN] The E-Document type is Purchase Invoice
- EDocument.Get(EDocument."Entry No");
- Assert.AreEqual("E-Document Type"::"Purchase Invoice", EDocument."Document Type", 'The document type should be Purchase Invoice.');
-
- // [THEN] A Purchase Invoice header is created with correct fields
- PurchaseHeader.Get(EDocument."Document Record ID");
- Assert.AreEqual("Purchase Document Type"::Invoice, PurchaseHeader."Document Type", 'The purchase header document type should be Invoice.');
- Assert.AreEqual('103033', PurchaseHeader."Vendor Invoice No.", 'The vendor invoice number should match the Invoice ID.');
- Assert.AreEqual('2', PurchaseHeader."Vendor Order No.", 'The vendor order number should match the OrderReference from the Invoice.');
- Assert.AreEqual(Vendor."No.", PurchaseHeader."Buy-from Vendor No.", 'The vendor should be resolved from the Invoice.');
- Assert.AreEqual(14140, PurchaseHeader."Doc. Amount Incl. VAT", 'The document amount incl. VAT should match the Invoice total.');
-
- // [THEN] The purchase invoice has the correct number of lines (2 from peppol-invoice-0.xml)
- PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type");
- PurchaseLine.SetRange("Document No.", PurchaseHeader."No.");
- Assert.RecordCount(PurchaseLine, 2);
- end;
-
local procedure Initialize(Integration: Enum "Service Integration")
var
TransformationRule: Record "Transformation Rule";
From 6019e3b1e9997bf56bbddd46aa417d5f0a9c81fb Mon Sep 17 00:00:00 2001
From: ventselartur
Date: Fri, 15 May 2026 14:12:38 +0200
Subject: [PATCH 4/5] add missing id range to app.json
---
src/Apps/W1/EDocument/App/app.json | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/Apps/W1/EDocument/App/app.json b/src/Apps/W1/EDocument/App/app.json
index 42a39ca645..c7b0e49a5b 100644
--- a/src/Apps/W1/EDocument/App/app.json
+++ b/src/Apps/W1/EDocument/App/app.json
@@ -57,6 +57,10 @@
{
"from": 6234,
"to": 6234
+ },
+ {
+ "from": 6401,
+ "to": 6410
}
],
"resourceExposurePolicy": {
From d125b1a8c61b58251ca004ac9202bcd1731b8c59 Mon Sep 17 00:00:00 2001
From: ventselartur
Date: Fri, 15 May 2026 14:52:43 +0200
Subject: [PATCH 5/5] Fix AA0237: rename non-temporary variable
TempEDocImportParams to EDocImportParams
The variable is not declared as temporary, so the 'Temp' prefix
violates analyzer rule AA0237.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.../Processing/EDocProcessTest.Codeunit.al | 60 +++++++++----------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
index 384b46cd55..508b6732ee 100644
--- a/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
+++ b/src/Apps/W1/EDocument/Test/src/Processing/EDocProcessTest.Codeunit.al
@@ -589,7 +589,7 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
PurchaseInvoiceLine: Record "Purch. Inv. Line";
EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocImportParams: Record "E-Doc. Import Parameters";
PurchaseHeader: Record "Purchase Header";
EDocPurchLineField: Record "E-Document Line - Field";
EDocPurchaseLine: Record "E-Document Purchase Line";
@@ -606,8 +606,8 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineFieldSetup.Insert();
// [GIVEN] An inbound e-document is received and a draft created
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', EDocImportParams), 'The draft for the e-document should be created');
// [GIVEN] A value that does not exist as a Location Code
EDocPurchLineField."E-Document Entry No." := EDocument."Entry No";
@@ -619,8 +619,8 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineField.Insert();
// [WHEN] Finalizing the draft
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParams);
// [THEN] The e-document should have an error
EDocument.Get(EDocument."Entry No");
@@ -645,7 +645,7 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
PurchaseInvoiceLine: Record "Purch. Inv. Line";
EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocImportParams: Record "E-Doc. Import Parameters";
PurchaseHeader: Record "Purchase Header";
EDocPurchLineField: Record "E-Document Line - Field";
EDocPurchaseLine: Record "E-Document Purchase Line";
@@ -663,8 +663,8 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineFieldSetup.Insert();
// [GIVEN] An inbound e-document is received and a draft created
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', EDocImportParams), 'The draft for the e-document should be created');
// [GIVEN] A value that exceeds the target field length (Code[10])
FieldValue := 'LONGLOCCODE1'; // 12 characters, exceeds Code[10]
@@ -677,8 +677,8 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineField.Insert();
// [WHEN] Finalizing the draft
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParams);
// [THEN] The e-document should have an error
EDocument.Get(EDocument."Entry No");
@@ -700,7 +700,7 @@ codeunit 139883 "E-Doc Process Test"
procedure StandardFieldValidationFailureEnrichesErrorMessage()
var
EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocImportParams: Record "E-Doc. Import Parameters";
EDocumentPurchaseHeader: Record "E-Document Purchase Header";
PurchaseHeader: Record "Purchase Header";
ErrorMessage: Record "Error Message";
@@ -712,8 +712,8 @@ codeunit 139883 "E-Doc Process Test"
Initialize(Enum::"Service Integration"::"Mock");
// [GIVEN] An inbound e-document is received and a draft created
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', EDocImportParams), 'The draft for the e-document should be created');
// [GIVEN] The draft has an invalid currency code
EDocumentPurchaseHeader.GetFromEDocument(EDocument);
@@ -721,8 +721,8 @@ codeunit 139883 "E-Doc Process Test"
EDocumentPurchaseHeader.Modify();
// [WHEN] Finalizing the draft
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParams);
// [THEN] The e-document should have an error
EDocument.Get(EDocument."Entry No");
@@ -745,7 +745,7 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
PurchaseInvoiceLine: Record "Purch. Inv. Line";
EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocImportParams: Record "E-Doc. Import Parameters";
PurchaseHeader: Record "Purchase Header";
EDocPurchLineField: Record "E-Document Line - Field";
EDocPurchaseLine: Record "E-Document Purchase Line";
@@ -767,8 +767,8 @@ codeunit 139883 "E-Doc Process Test"
if Location.Insert() then;
// [GIVEN] An inbound e-document is received and a draft created
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', EDocImportParams), 'The draft for the e-document should be created');
// [GIVEN] The additional field has a valid value
EDocPurchLineField."E-Document Entry No." := EDocument."Entry No";
@@ -780,8 +780,8 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineField.Insert();
// [WHEN] Finalizing the draft
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- Assert.IsTrue(EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams), 'The finalization should succeed');
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ Assert.IsTrue(EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParams), 'The finalization should succeed');
// [THEN] The e-document should have no errors
EDocument.Get(EDocument."Entry No");
@@ -802,7 +802,7 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineFieldSetup: Record "ED Purchase Line Field Setup";
PurchaseInvoiceLine: Record "Purch. Inv. Line";
EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocImportParams: Record "E-Doc. Import Parameters";
PurchaseHeader: Record "Purchase Header";
EDocPurchLineField: Record "E-Document Line - Field";
EDocPurchaseLine: Record "E-Document Purchase Line";
@@ -827,8 +827,8 @@ codeunit 139883 "E-Doc Process Test"
if Location.Insert() then;
// [GIVEN] An inbound e-document is received and a draft created
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', EDocImportParams), 'The draft for the e-document should be created');
// [GIVEN] First field (Location Code) has a valid value, second field (Bin Code) has an invalid value
EDocPurchaseLine.SetRange("E-Document Entry No.", EDocument."Entry No");
@@ -848,8 +848,8 @@ codeunit 139883 "E-Doc Process Test"
EDocPurchLineField.Insert();
// [WHEN] Finalizing the draft
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParams);
// [THEN] The e-document should have an error
EDocument.Get(EDocument."Entry No");
@@ -871,7 +871,7 @@ codeunit 139883 "E-Doc Process Test"
procedure NoAdditionalFieldsStandardFieldFailureStillEnriched()
var
EDocument: Record "E-Document";
- TempEDocImportParams: Record "E-Doc. Import Parameters";
+ EDocImportParams: Record "E-Doc. Import Parameters";
EDocumentPurchaseHeader: Record "E-Document Purchase Header";
PurchaseHeader: Record "Purchase Header";
ErrorMessage: Record "Error Message";
@@ -883,8 +883,8 @@ codeunit 139883 "E-Doc Process Test"
Initialize(Enum::"Service Integration"::"Mock");
// [GIVEN] An inbound e-document is received and a draft created (no additional fields configured)
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
- Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', TempEDocImportParams), 'The draft for the e-document should be created');
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Prepare draft";
+ Assert.IsTrue(LibraryEDoc.CreateInboundPEPPOLDocumentToState(EDocument, EDocumentService, 'peppol/peppol-invoice-0.xml', EDocImportParams), 'The draft for the e-document should be created');
// [GIVEN] The draft has an invalid currency code
EDocumentPurchaseHeader.GetFromEDocument(EDocument);
@@ -892,8 +892,8 @@ codeunit 139883 "E-Doc Process Test"
EDocumentPurchaseHeader.Modify();
// [WHEN] Finalizing the draft
- TempEDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
- EDocImport.ProcessIncomingEDocument(EDocument, TempEDocImportParams);
+ EDocImportParams."Step to Run" := "Import E-Document Steps"::"Finish draft";
+ EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParams);
// [THEN] The e-document should have an error
EDocument.Get(EDocument."Entry No");