From 3e81f6a4a07661656640280db87833876e3fc627 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Wed, 11 Dec 2024 15:16:15 +0100 Subject: [PATCH 01/14] add EDocument app workspace --- .../EDocument/edocument_workspace.code-workspace | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Apps/W1/EDocument/edocument_workspace.code-workspace diff --git a/Apps/W1/EDocument/edocument_workspace.code-workspace b/Apps/W1/EDocument/edocument_workspace.code-workspace new file mode 100644 index 0000000000..f10f2a03cc --- /dev/null +++ b/Apps/W1/EDocument/edocument_workspace.code-workspace @@ -0,0 +1,16 @@ +{ + "folders": [ + { + "name": "app", + "path": "app" + }, + { + "name": "test", + "path": "test" + }, + { + "name": "demo data", + "path": "demo data" + } + ] +} \ No newline at end of file From f4c11e284549a39e0b356ae69c618198edd0bdc0 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Thu, 12 Dec 2024 11:10:12 +0100 Subject: [PATCH 02/14] add code analyzers settings to code workspace --- Apps/W1/EDocument/edocument_workspace.code-workspace | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Apps/W1/EDocument/edocument_workspace.code-workspace b/Apps/W1/EDocument/edocument_workspace.code-workspace index f10f2a03cc..35fb4f1ea3 100644 --- a/Apps/W1/EDocument/edocument_workspace.code-workspace +++ b/Apps/W1/EDocument/edocument_workspace.code-workspace @@ -1,4 +1,12 @@ { + "settings": { + "al.enableCodeAnalysis": true, + "al.codeAnalyzers": [ + "${CodeCop}", + "${UICop}", + "${AppSourceCop}" + ] + }, "folders": [ { "name": "app", From aba4c1f2bcfe2bb5159b4707a5499aa65d070d9d Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Thu, 9 Jan 2025 19:46:41 +0100 Subject: [PATCH 03/14] add test, add check for duplicate on receiving e documents --- .../EDocIntegrationManagement.Codeunit.al | 27 +++- .../src/Receive/EDocReceiveTest.Codeunit.al | 129 ++++++++++++++++++ 2 files changed, 154 insertions(+), 2 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index 28af37ac3a..2a22479ab4 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -199,6 +199,7 @@ codeunit 6134 "E-Doc. Integration Management" var ReceiveContext, FetchContextImpl : Codeunit ReceiveContext; ErrorCount: Integer; + EDocumentContent: Codeunit "Temp Blob"; Success, IsFetchableType : Boolean; begin ReceiveContext.Status().SetStatus(Enum::"E-Document Service Status"::Imported); @@ -209,7 +210,9 @@ 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; @@ -217,11 +220,13 @@ codeunit 6134 "E-Doc. Integration Management" ErrorCount := EDocumentErrorHelper.ErrorMessageCount(EDocument); RunMarkFetched(EDocument, EDocumentService, ReceiveContext.GetTempBlob(), IDocumentReceiver, FetchContextImpl); Success := EDocumentErrorHelper.ErrorMessageCount(EDocument) = ErrorCount; - if not Success then exit(false); end; + if not CheckNoDuplicateExists(EDocumentService, EDocument, EDocumentContent) 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()); @@ -564,6 +569,24 @@ codeunit 6134 "E-Doc. Integration Management" exit(true); end; + local procedure CheckNoDuplicateExists(var EDocumentService: Record "E-Document Service"; var EDocument: Record "E-Document"; var DocumentMetadata: Codeunit "Temp Blob"): Boolean + var + EDocGetBasicInfo: Codeunit "E-Doc. Get Basic Info"; + IEDocument: Interface "E-Document"; + EDocument2: Record "E-Document"; + begin + IEDocument := EDocumentService."Document Format"; + EDocGetBasicInfo.SetValues(IEDocument, EDocument, DocumentMetadata); + EDocGetBasicInfo.Run(); + EDocGetBasicInfo.GetValues(IEDocument, EDocument, DocumentMetadata); + + EDocument2.SetRange("Incoming E-Document No.", EDocument."Incoming E-Document No."); + EDocument2.SetRange("Bill-to/Pay-to No.", EDocument."Bill-to/Pay-to No."); + EDocument2.SetFilter("Entry No", '<>%1', EDocument."Entry No"); + EDocument2.SetRange("Document Date", EDocument."Document Date"); + exit(EDocument2.IsEmpty()); + end; + #endregion diff --git a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al index 98a2793f6b..7235f54e1f 100644 --- a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al @@ -1342,6 +1342,47 @@ codeunit 139628 "E-Doc. Receive Test" PurchaseHeader.Delete(true); end; + [Test] + [HandlerFunctions('SelectPOHandlerCancel,ConfirmHandler')] + procedure ReceiveTheSameEDocumentTwice() + var + EDocService: Record "E-Document Service"; + EDocument: 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); + // [GIVEN] Purchase order created for vendor + CreatePurchaseOrder(Item, DocumentVendor); + + // [WHEN] Running Receive + InvokeReceive(EDocService); + + // [THEN] Attachments are imported and linked with e-Document + EDocument.FindLast(); + DocumentAttachment.SetRange("No.", Format(EDocument."Entry No")); + DocumentAttachment.SetRange("Table ID", Database::"E-Document"); + DocumentAttachment.SetRange("E-Document Entry No.", EDocument."Entry No"); + DocumentAttachment.SetRange("E-Document Attachment", true); + Assert.RecordCount(DocumentAttachment, 2); + end; + + + [ModalPageHandler] procedure SelectPOHandler(var POList: TestPage "Purchase Order List") var @@ -1443,6 +1484,94 @@ 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.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 From 87a9c7f951ad0f013440485d23bfdaa51f899121 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Fri, 10 Jan 2025 14:34:40 +0100 Subject: [PATCH 04/14] minor changes --- .../EDocIntegrationManagement.Codeunit.al | 11 ++++---- .../src/Receive/EDocReceiveTest.Codeunit.al | 25 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index 2a22479ab4..6515d62516 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -569,16 +569,17 @@ codeunit 6134 "E-Doc. Integration Management" exit(true); end; - local procedure CheckNoDuplicateExists(var EDocumentService: Record "E-Document Service"; var EDocument: Record "E-Document"; var DocumentMetadata: Codeunit "Temp Blob"): Boolean + local procedure CheckNoDuplicateExists(EDocumentService: Record "E-Document Service"; var EDocument: Record "E-Document"; var EDocumentContent: Codeunit "Temp Blob"): Boolean var + EDocument2: Record "E-Document"; EDocGetBasicInfo: Codeunit "E-Doc. Get Basic Info"; IEDocument: Interface "E-Document"; - EDocument2: Record "E-Document"; begin IEDocument := EDocumentService."Document Format"; - EDocGetBasicInfo.SetValues(IEDocument, EDocument, DocumentMetadata); - EDocGetBasicInfo.Run(); - EDocGetBasicInfo.GetValues(IEDocument, EDocument, DocumentMetadata); + EDocGetBasicInfo.SetValues(IEDocument, EDocument, EDocumentContent); + if not EDocGetBasicInfo.Run() then + exit(true); + EDocGetBasicInfo.GetValues(IEDocument, EDocument, EDocumentContent); EDocument2.SetRange("Incoming E-Document No.", EDocument."Incoming E-Document No."); EDocument2.SetRange("Bill-to/Pay-to No.", EDocument."Bill-to/Pay-to No."); diff --git a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al index 7235f54e1f..329bb906fc 100644 --- a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al @@ -1343,11 +1343,12 @@ codeunit 139628 "E-Doc. Receive Test" end; [Test] - [HandlerFunctions('SelectPOHandlerCancel,ConfirmHandler')] - procedure ReceiveTheSameEDocumentTwice() + [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"; @@ -1366,23 +1367,19 @@ codeunit 139628 "E-Doc. Receive Test" CreateItemWithReference(Item, VATPostingSetup); // [GIVEN] Incoming PEPPOL duplicated document CreateIncomingDuplicatedPEPPOL(DocumentVendor); - // [GIVEN] Purchase order created for vendor - CreatePurchaseOrder(Item, DocumentVendor); // [WHEN] Running Receive InvokeReceive(EDocService); - // [THEN] Attachments are imported and linked with e-Document + // [THEN] Only one E-Document is created EDocument.FindLast(); - DocumentAttachment.SetRange("No.", Format(EDocument."Entry No")); - DocumentAttachment.SetRange("Table ID", Database::"E-Document"); - DocumentAttachment.SetRange("E-Document Entry No.", EDocument."Entry No"); - DocumentAttachment.SetRange("E-Document Attachment", true); - Assert.RecordCount(DocumentAttachment, 2); + 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 @@ -1528,6 +1525,10 @@ codeunit 139628 "E-Doc. Receive Test" 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); From a64c42676151bebb6be0515dbaf55b909c96cbc5 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Fri, 10 Jan 2025 14:43:47 +0100 Subject: [PATCH 05/14] remove empty lines --- .../app/src/Integration/EDocIntegrationManagement.Codeunit.al | 2 -- 1 file changed, 2 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index 6515d62516..e89f0f4d20 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -211,7 +211,6 @@ codeunit 6134 "E-Doc. Integration Management" exit(false); EDocumentContent := ReceiveContext.GetTempBlob(); - if not EDocumentContent.HasValue() then exit(false); @@ -588,7 +587,6 @@ codeunit 6134 "E-Doc. Integration Management" exit(EDocument2.IsEmpty()); end; - #endregion var From f1a211e47d63a914b9ecd1e0110008342bbc41c7 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Mon, 13 Jan 2025 14:12:55 +0100 Subject: [PATCH 06/14] pr fixes --- .../EDocIntegrationManagement.Codeunit.al | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index e89f0f4d20..24216fe242 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -198,8 +198,8 @@ 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; - ErrorCount: Integer; EDocumentContent: Codeunit "Temp Blob"; + ErrorCount: Integer; Success, IsFetchableType : Boolean; begin ReceiveContext.Status().SetStatus(Enum::"E-Document Service Status"::Imported); @@ -223,7 +223,7 @@ codeunit 6134 "E-Doc. Integration Management" exit(false); end; - if not CheckNoDuplicateExists(EDocumentService, EDocument, EDocumentContent) then + if not HasNoDuplicate(EDocument, EDocumentContent, EDocumentService."Document Format") then exit(false); // Only after sucecssfully downloading and (optionally) marking as fetched, the document is considered imported @@ -239,6 +239,25 @@ codeunit 6134 "E-Doc. Integration Management" end; + local procedure HasNoDuplicate(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(true); + 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(EDocument.IsEmpty()); + end; + + + #endregion #region Actions @@ -568,25 +587,6 @@ codeunit 6134 "E-Doc. Integration Management" exit(true); end; - local procedure CheckNoDuplicateExists(EDocumentService: Record "E-Document Service"; var EDocument: Record "E-Document"; var EDocumentContent: Codeunit "Temp Blob"): Boolean - var - EDocument2: Record "E-Document"; - EDocGetBasicInfo: Codeunit "E-Doc. Get Basic Info"; - IEDocument: Interface "E-Document"; - begin - IEDocument := EDocumentService."Document Format"; - EDocGetBasicInfo.SetValues(IEDocument, EDocument, EDocumentContent); - if not EDocGetBasicInfo.Run() then - exit(true); - EDocGetBasicInfo.GetValues(IEDocument, EDocument, EDocumentContent); - - EDocument2.SetRange("Incoming E-Document No.", EDocument."Incoming E-Document No."); - EDocument2.SetRange("Bill-to/Pay-to No.", EDocument."Bill-to/Pay-to No."); - EDocument2.SetFilter("Entry No", '<>%1', EDocument."Entry No"); - EDocument2.SetRange("Document Date", EDocument."Document Date"); - exit(EDocument2.IsEmpty()); - end; - #endregion var From 5290d81547b4d70a8889feebb83b329687995c33 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Mon, 13 Jan 2025 14:25:06 +0100 Subject: [PATCH 07/14] change assert to use helper function --- Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al index 329bb906fc..ca81a4734c 100644 --- a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al @@ -1377,7 +1377,7 @@ codeunit 139628 "E-Doc. Receive Test" 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.'); + Assert.RecordIsEmpty(EDocument2); end; [ModalPageHandler] From 69e59dcd6ae7502f6c60c8a39f701ec446489a52 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Mon, 13 Jan 2025 20:18:22 +0100 Subject: [PATCH 08/14] restore assert with message, change function name --- .../src/Integration/EDocIntegrationManagement.Codeunit.al | 6 +++--- .../EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index 24216fe242..1479bfe6fc 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -223,7 +223,7 @@ codeunit 6134 "E-Doc. Integration Management" exit(false); end; - if not HasNoDuplicate(EDocument, EDocumentContent, EDocumentService."Document Format") then + if HasDuplicate(EDocument, EDocumentContent, EDocumentService."Document Format") then exit(false); // Only after sucecssfully downloading and (optionally) marking as fetched, the document is considered imported @@ -239,14 +239,14 @@ codeunit 6134 "E-Doc. Integration Management" end; - local procedure HasNoDuplicate(var IncomingEDocument: Record "E-Document"; var EDocumentContent: Codeunit "Temp Blob"; IEDocument: Interface "E-Document"): Boolean + 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(true); + exit(false); EDocGetBasicInfo.GetValues(IEDocument, IncomingEDocument, EDocumentContent); EDocument.SetFilter("Entry No", '<>%1', IncomingEDocument."Entry No"); diff --git a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al index ca81a4734c..329bb906fc 100644 --- a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al @@ -1377,7 +1377,7 @@ codeunit 139628 "E-Doc. Receive Test" 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.RecordIsEmpty(EDocument2); + Assert.IsTrue(EDocument2.IsEmpty(), 'Duplicate E-Document created.'); end; [ModalPageHandler] From e710746cabbc7b3681974323bd3911a3d9e54a40 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Mon, 13 Jan 2025 20:37:47 +0100 Subject: [PATCH 09/14] fix --- .../app/src/Integration/EDocIntegrationManagement.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index 1479bfe6fc..d39ec1b3a5 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -253,7 +253,7 @@ codeunit 6134 "E-Doc. Integration Management" 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(EDocument.IsEmpty()); + exit(not EDocument.IsEmpty()); end; From d1a005df76f17f8c4b7d7ba111b9e700145e82fe Mon Sep 17 00:00:00 2001 From: Grasiele Matuleviciute Date: Fri, 17 Jan 2025 10:34:47 +0200 Subject: [PATCH 10/14] Removed empty lines --- .../app/src/Integration/EDocIntegrationManagement.Codeunit.al | 3 --- 1 file changed, 3 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index d39ec1b3a5..b36bc3b91e 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -238,7 +238,6 @@ 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"; @@ -256,8 +255,6 @@ codeunit 6134 "E-Doc. Integration Management" exit(not EDocument.IsEmpty()); end; - - #endregion #region Actions From 062deeb17f610e58321daa347b76a6bc5b58deee Mon Sep 17 00:00:00 2001 From: Grasiele Matuleviciute Date: Fri, 17 Jan 2025 12:00:15 +0200 Subject: [PATCH 11/14] Removed workspace file --- .../edocument_workspace.code-workspace | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 Apps/W1/EDocument/edocument_workspace.code-workspace diff --git a/Apps/W1/EDocument/edocument_workspace.code-workspace b/Apps/W1/EDocument/edocument_workspace.code-workspace deleted file mode 100644 index 35fb4f1ea3..0000000000 --- a/Apps/W1/EDocument/edocument_workspace.code-workspace +++ /dev/null @@ -1,24 +0,0 @@ -{ - "settings": { - "al.enableCodeAnalysis": true, - "al.codeAnalyzers": [ - "${CodeCop}", - "${UICop}", - "${AppSourceCop}" - ] - }, - "folders": [ - { - "name": "app", - "path": "app" - }, - { - "name": "test", - "path": "test" - }, - { - "name": "demo data", - "path": "demo data" - } - ] -} \ No newline at end of file From 4693f94e5a15cce152356b381a8d487626e3b9fc Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Tue, 4 Feb 2025 16:43:48 +0100 Subject: [PATCH 12/14] move e-document duplicate skipping to process stage --- .../EDocIntegrationManagement.Codeunit.al | 20 ------------------- .../app/src/Processing/EDocImport.Codeunit.al | 16 +++++++++++++++ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index b36bc3b91e..0a520f95bf 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -223,9 +223,6 @@ codeunit 6134 "E-Doc. Integration Management" 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()); @@ -238,23 +235,6 @@ 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 #region Actions diff --git a/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al index 0591dfdb3b..98e55b533e 100644 --- a/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al @@ -354,6 +354,11 @@ codeunit 6140 "E-Doc. Import" exit; end; + if HasDuplicate(EDocument) then begin + EDocument.Delete(true); + exit; + end; + ParseDocumentLines(EDocument, EDocService, TempBlob, SourceDocumentHeader, SourceDocumentLine, TempEDocMapping); if EDocErrorHelper.HasErrors(EDocument) then begin EDocServiceStatus := Enum::"E-Document Service Status"::"Imported document processing error"; @@ -620,6 +625,17 @@ codeunit 6140 "E-Doc. Import" until TempEDocImportedLine.Next() = 0; end; + local procedure HasDuplicate(var IncomingEDocument: Record "E-Document"): Boolean + var + EDocument: Record "E-Document"; + begin + 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; + internal procedure SetHideDialogs(Hide: Boolean) begin HideDialogs := Hide; From 244c4cf34a414014f967b96aab1c710de25279e3 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Tue, 11 Feb 2025 14:00:21 +0100 Subject: [PATCH 13/14] clear integrattion managment codeunit --- .../app/src/Integration/EDocIntegrationManagement.Codeunit.al | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index 0a520f95bf..f3fd6449c3 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -198,7 +198,6 @@ 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 @@ -210,8 +209,7 @@ codeunit 6134 "E-Doc. Integration Management" if not Success then exit(false); - EDocumentContent := ReceiveContext.GetTempBlob(); - if not EDocumentContent.HasValue() then + if not ReceiveContext.GetTempBlob().HasValue() then exit(false); IsFetchableType := IDocumentReceiver is IReceivedDocumentMarker; From 52c7957f7061afc6f88be7a83f1d84a28134c317 Mon Sep 17 00:00:00 2001 From: Piotr Michalak Date: Tue, 11 Feb 2025 14:52:32 +0100 Subject: [PATCH 14/14] Update E-Document table from pullrequest #9 --- .../app/src/Document/EDocument.Table.al | 59 +++++++++++++++++++ .../app/src/Processing/EDocImport.Codeunit.al | 13 +--- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/Apps/W1/EDocument/app/src/Document/EDocument.Table.al b/Apps/W1/EDocument/app/src/Document/EDocument.Table.al index 4ec6ab4122..520480cd9f 100644 --- a/Apps/W1/EDocument/app/src/Document/EDocument.Table.al +++ b/Apps/W1/EDocument/app/src/Document/EDocument.Table.al @@ -6,6 +6,7 @@ namespace Microsoft.eServices.EDocument; using Microsoft.Foundation.Reporting; using Microsoft.Finance.Currency; +using Microsoft.Foundation.Attachment; using Microsoft.Utilities; using System.Automation; using System.IO; @@ -195,6 +196,61 @@ table 6121 "E-Document" } } + trigger OnDelete() + begin + if (Rec.Status = Rec.Status::Processed) then + Error(this.DeleteProcessedNotAllowedErr); + + if (Rec."Document Record ID".TableNo <> 0) then + Error(this.DeleteLinkedNotAllowedErr); + + if (not Rec.IsDuplicate()) then + Error(this.DeleteUniqueNotAllowedErr); + + this.DeleteRelatedRecords(); + end; + + internal procedure IsDuplicate(): Boolean + var + EDocument: Record "E-Document"; + begin + EDocument.SetRange("Incoming E-Document No.", Rec."Incoming E-Document No."); + EDocument.SetRange("Bill-to/Pay-to No.", Rec."Bill-to/Pay-to No."); + EDocument.SetRange("Document Date", Rec."Document Date"); + EDocument.SetFilter("Entry No", '<>%1', Rec."Entry No"); + exit(not EDocument.IsEmpty()); + end; + + local procedure DeleteRelatedRecords() + var + DocumentAttachment: Record "Document Attachment"; + EDocMappingLog: Record "E-Doc. Mapping Log"; + EDocumentIntegrationLog: Record "E-Document Integration Log"; + EDocumentLog: Record "E-Document Log"; + EDocumentServiceStatus: Record "E-Document Service Status"; + begin + EDocumentLog.SetRange("E-Doc. Entry No", Rec."Entry No"); + if not EDocumentLog.IsEmpty() then + EDocumentLog.DeleteAll(true); + + EDocumentIntegrationLog.SetRange("E-Doc. Entry No", Rec."Entry No"); + if not EDocumentIntegrationLog.IsEmpty() then + EDocumentIntegrationLog.DeleteAll(true); + + EDocumentServiceStatus.SetRange("E-Document Entry No", Rec."Entry No"); + if not EDocumentServiceStatus.IsEmpty() then + EDocumentServiceStatus.DeleteAll(true); + + DocumentAttachment.SetRange("E-Document Attachment", true); + DocumentAttachment.SetRange("E-Document Entry No.", Rec."Entry No"); + if not DocumentAttachment.IsEmpty() then + DocumentAttachment.DeleteAll(true); + + EDocMappingLog.SetRange("E-Doc Entry No.", Rec."Entry No"); + if not EDocMappingLog.IsEmpty() then + EDocMappingLog.DeleteAll(true); + end; + internal procedure OpenEDocument(EDocumentRecordId: RecordId) var EDocument: Record "E-Document"; @@ -227,4 +283,7 @@ table 6121 "E-Document" var ToStringLbl: Label '%1,%2,%3,%4', Locked = true; + DeleteLinkedNotAllowedErr: Label 'The E-Document is linked to sales or purchase document and cannot be deleted.'; + DeleteProcessedNotAllowedErr: Label 'The E-Document has already been processed and cannot be deleted.'; + DeleteUniqueNotAllowedErr: Label 'Only duplicate E-Documents can be deleted.'; } diff --git a/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al index 98e55b533e..15cc425999 100644 --- a/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al @@ -354,7 +354,7 @@ codeunit 6140 "E-Doc. Import" exit; end; - if HasDuplicate(EDocument) then begin + if EDocument.IsDuplicate() then begin EDocument.Delete(true); exit; end; @@ -625,17 +625,6 @@ codeunit 6140 "E-Doc. Import" until TempEDocImportedLine.Next() = 0; end; - local procedure HasDuplicate(var IncomingEDocument: Record "E-Document"): Boolean - var - EDocument: Record "E-Document"; - begin - 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; - internal procedure SetHideDialogs(Hide: Boolean) begin HideDialogs := Hide;