Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[E-Document Core] - Skip duplicated E-Documents when receiving from service #27953

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ codeunit 6134 "E-Doc. Integration Management"
local procedure ReceiveSingleDocument(var EDocument: Record "E-Document"; var EDocumentService: Record "E-Document Service"; DocumentMetadata: Codeunit "Temp Blob"; IDocumentReceiver: Interface IDocumentReceiver): Boolean
var
ReceiveContext, FetchContextImpl : Codeunit ReceiveContext;
EDocumentContent: Codeunit "Temp Blob";
ErrorCount: Integer;
Success, IsFetchableType : Boolean;
begin
Expand All @@ -209,19 +210,22 @@ codeunit 6134 "E-Doc. Integration Management"
if not Success then
exit(false);

if not ReceiveContext.GetTempBlob().HasValue() then
EDocumentContent := ReceiveContext.GetTempBlob();
if not EDocumentContent.HasValue() then
exit(false);

IsFetchableType := IDocumentReceiver is IReceivedDocumentMarker;
if IsFetchableType then begin
ErrorCount := EDocumentErrorHelper.ErrorMessageCount(EDocument);
RunMarkFetched(EDocument, EDocumentService, ReceiveContext.GetTempBlob(), IDocumentReceiver, FetchContextImpl);
Success := EDocumentErrorHelper.ErrorMessageCount(EDocument) = ErrorCount;

if not Success then
exit(false);
end;

if HasDuplicate(EDocument, EDocumentContent, EDocumentService."Document Format") then
exit(false);

// Only after sucecssfully downloading and (optionally) marking as fetched, the document is considered imported
// Insert logs for downloading document
InsertLogAndEDocumentStatus(EDocument, EDocumentService, ReceiveContext.GetTempBlob(), ReceiveContext.Status().GetStatus());
Expand All @@ -234,6 +238,22 @@ codeunit 6134 "E-Doc. Integration Management"
exit(true);
end;

local procedure HasDuplicate(var IncomingEDocument: Record "E-Document"; var EDocumentContent: Codeunit "Temp Blob"; IEDocument: Interface "E-Document"): Boolean
var
EDocument: Record "E-Document";
EDocGetBasicInfo: Codeunit "E-Doc. Get Basic Info";
begin
EDocGetBasicInfo.SetValues(IEDocument, IncomingEDocument, EDocumentContent);
if not EDocGetBasicInfo.Run() then
exit(false);
EDocGetBasicInfo.GetValues(IEDocument, IncomingEDocument, EDocumentContent);

EDocument.SetFilter("Entry No", '<>%1', IncomingEDocument."Entry No");
EDocument.SetRange("Incoming E-Document No.", IncomingEDocument."Incoming E-Document No.");
EDocument.SetRange("Bill-to/Pay-to No.", IncomingEDocument."Bill-to/Pay-to No.");
EDocument.SetRange("Document Date", IncomingEDocument."Document Date");
exit(not EDocument.IsEmpty());
end;

#endregion

Expand Down Expand Up @@ -564,7 +584,6 @@ codeunit 6134 "E-Doc. Integration Management"
exit(true);
end;


#endregion

var
Expand Down
130 changes: 130 additions & 0 deletions Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,44 @@ codeunit 139628 "E-Doc. Receive Test"
PurchaseHeader.Delete(true);
end;

[Test]
[HandlerFunctions('ConfirmHandler')]
procedure ReceiveEDocumentDuplicate()
var
EDocService: Record "E-Document Service";
EDocument: Record "E-Document";
EDocument2: Record "E-Document";
Item: Record Item;
DocumentAttachment: Record "Document Attachment";
VATPostingSetup: Record "VAT Posting Setup";
DocumentVendor: Record Vendor;
begin
// [FEATURE] [E-Document] [Receive]
// [SCENARIO] Receive e-document twice so the duplicate will be skipped in creation
Initialize();
BindSubscription(EDocImplState);

// [GIVEN] e-Document service to receive one single purchase order
CreateEDocServiceToReceivePurchaseOrder(EDocService);
// [GIVEN] Vendor with VAT Posting Setup
CreateVendorWithVatPostingSetup(DocumentVendor, VATPostingSetup);
// [GIVEN] Item with item reference
CreateItemWithReference(Item, VATPostingSetup);
// [GIVEN] Incoming PEPPOL duplicated document
CreateIncomingDuplicatedPEPPOL(DocumentVendor);

// [WHEN] Running Receive
InvokeReceive(EDocService);

// [THEN] Only one E-Document is created
EDocument.FindLast();
EDocument2.SetRange("Bill-to/Pay-to No.", EDocument."Bill-to/Pay-to No.");
EDocument2.SetRange("Incoming E-Document No.", EDocument."Incoming E-Document No.");
EDocument2.SetRange("Document Date", EDocument."Document Date");
EDocument2.SetFilter("Entry No", '<>%1', EDocument."Entry No");
Assert.IsTrue(EDocument2.IsEmpty(), 'Duplicate E-Document created.');
end;

[ModalPageHandler]
procedure SelectPOHandler(var POList: TestPage "Purchase Order List")
var
Expand Down Expand Up @@ -1443,6 +1481,98 @@ codeunit 139628 "E-Doc. Receive Test"
PurchaseField.SetRange("No.", 10705);
end;


local procedure CreateEDocServiceToReceivePurchaseOrder(var EDocService: Record "E-Document Service")
begin
LibraryEDoc.CreateTestReceiveServiceForEDoc(EDocService, Enum::"Service Integration"::Mock);
SetDefaultEDocServiceValues(EDocService);
end;

local procedure CreateVendorWithVatPostingSetup(var DocumentVendor: Record Vendor; var VATPostingSetup: Record "VAT Posting Setup")
begin
LibraryPurchase.CreateVendorWithVATRegNo(DocumentVendor);
LibraryERM.CreateVATPostingSetupWithAccounts(VATPostingSetup, Enum::"Tax Calculation Type"::"Normal VAT", 1);
DocumentVendor."VAT Bus. Posting Group" := VATPostingSetup."VAT Bus. Posting Group";
DocumentVendor."Receive E-Document To" := Enum::"E-Document Type"::"Purchase Order";
DocumentVendor.Modify(false);
end;

local procedure CreateItemWithReference(var Item: Record Item; var VATPostingSetup: Record "VAT Posting Setup")
var
ItemReference: Record "Item Reference";
begin
Item.FindFirst();
Item."VAT Prod. Posting Group" := VATPostingSetup."VAT Prod. Posting Group";
Item.Modify(false);
ItemReference.DeleteAll(false);
ItemReference."Item No." := Item."No.";
ItemReference."Reference No." := '1000';
ItemReference.Insert(false);
end;

local procedure CreateIncomingDuplicatedPEPPOL(var DocumentVendor: Record Vendor)
var
TempXMLBuffer: Record "XML Buffer" temporary;
TempBlob: Codeunit "Temp Blob";
Document, Document2 : Text;
XMLInstream: InStream;
begin
TempXMLBuffer.LoadFromText(EDocReceiveFiles.GetDocument1());
TempXMLBuffer.Reset();
TempXMLBuffer.SetRange(Type, TempXMLBuffer.Type::Element);
TempXMLBuffer.SetRange(Path, '/Invoice/cac:AccountingSupplierParty/cac:Party/cbc:EndpointID');
TempXMLBuffer.FindFirst();
TempXMLBuffer.Value := DocumentVendor."VAT Registration No.";
TempXMLBuffer.Modify();

TempXMLBuffer.SetRange(Path, '/Invoice/cbc:ID');
TempXMLBuffer.FindFirst();
TempXMLBuffer.Value := LibraryRandom.RandText(20);

TempXMLBuffer.Reset();
TempXMLBuffer.FindFirst();
TempXMLBuffer.Save(TempBlob);

TempBlob.CreateInStream(XMLInstream, TextEncoding::UTF8);
XMLInstream.Read(Document);

LibraryVariableStorage.Clear();
LibraryVariableStorage.Enqueue(Document);
LibraryVariableStorage.Enqueue(2);
EDocImplState.SetVariableStorage(LibraryVariableStorage);
end;

local procedure CreatePurchaseOrder(var Item: Record Item; var DocumentVendor: Record Vendor)
begin
LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, DocumentVendor."No.");
LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item."No.", 10);
PurchaseLine.Validate("Direct Unit Cost", 100);
PurchaseLine.Modify(true);
end;

local procedure InvokeReceive(var EDocService: Record "E-Document Service")
var
EDocServicePage: TestPage "E-Document Service";
begin
EDocServicePage.OpenView();
EDocServicePage.Filter.SetFilter(Code, EDocService.Code);
EDocServicePage.Receive.Invoke();
end;

local procedure SetDefaultEDocServiceValues(var EDocService: Record "E-Document Service")
begin
EDocService."Document Format" := "E-Document Format"::"PEPPOL BIS 3.0";
EDocService."Lookup Account Mapping" := false;
EDocService."Lookup Item GTIN" := false;
EDocService."Lookup Item Reference" := false;
EDocService."Resolve Unit Of Measure" := false;
EDocService."Validate Line Discount" := false;
EDocService."Verify Totals" := false;
EDocService."Use Batch Processing" := false;
EDocService."Validate Receiving Company" := false;
EDocService.Modify(false);
end;

#pragma warning disable AS0018
#if not CLEAN26

Expand Down
Loading