diff --git a/Apps/W1/EDocument/app/src/Document/EDocument.Page.al b/Apps/W1/EDocument/app/src/Document/EDocument.Page.al
index 801a23f7df..388c63c964 100644
--- a/Apps/W1/EDocument/app/src/Document/EDocument.Page.al
+++ b/Apps/W1/EDocument/app/src/Document/EDocument.Page.al
@@ -395,6 +395,19 @@ page 6121 "E-Document"
EDocOrderMatch.RunMatching(Rec);
end;
}
+ action(DeleteRelatedDocument)
+ {
+ Caption = 'Delete Related Document';
+ ToolTip = 'Delete the related purchase document.';
+ Image = Delete;
+ Visible = IsIncomingDoc and IsProcessed;
+
+ trigger OnAction()
+ begin
+ if Confirm(StrSubstNo(this.ConfirmDeleteRelatedDocQst, this.RecordLinkTxt)) then
+ this.EDocumentHelper.DeleteRelatedRecord(Rec);
+ end;
+ }
}
group(Troubleshoot)
{
@@ -462,7 +475,6 @@ page 6121 "E-Document"
actionref(Cancel_promoteed; Cancel) { }
actionref(Approval_promoteed; GetApproval) { }
actionref(Preview_promoteed; ViewFile) { }
-
}
group(Category_Troubleshoot)
{
@@ -651,5 +663,6 @@ page 6121 "E-Document"
ShowRelink, ShowMapToOrder, HasErrorsOrWarnings, HasErrors, IsIncomingDoc, IsProcessed, CopilotVisible : Boolean;
EDocHasErrorOrWarningMsg: Label 'Errors or warnings found for E-Document. Please review below in "Error Messages" section.';
DocNotCreatedMsg: Label 'Failed to create new %1 from E-Document. Please review errors below.', Comment = '%1 - E-Document Document Type';
+ ConfirmDeleteRelatedDocQst: Label 'Do you want to delete the related document %1?', Comment = '%1 - related record ID';
}
diff --git a/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al b/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al
index ad49ffec3c..38a1c0f2cd 100644
--- a/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al
+++ b/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al
@@ -28,4 +28,5 @@ enum 6106 "E-Document Service Status"
value(17; "Order Linked") { Caption = 'Order linked'; }
value(18; "Pending") { Caption = 'Pending Document Link'; }
value(19; "Approval Error") { Caption = 'Approval error'; }
+ value(21; "Imported Document Deleted") { Caption = 'Imported document deleted'; }
}
diff --git a/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al
index f871f39042..1749cf9094 100644
--- a/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al
+++ b/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al
@@ -275,6 +275,21 @@ codeunit 6108 "E-Document Processing"
exit(GetPostedRecord(EDocument, RelatedRecord));
end;
+ ///
+ /// Deletes related record if it is not posted.
+ ///
+ /// E-Document record
+ procedure DeleteRelatedRecord(EDocument: Record "E-Document")
+ var
+ RecRef: RecordRef;
+ begin
+ if this.GetRelatedRecord(EDocument, RecRef) then
+ if RecRef.Number = Database::"Purchase Header" then
+ RecRef.Delete(true)
+ else
+ Error(this.CannotDeletePostedRecordErr);
+ end;
+
procedure GetTelemetryDimensions(EDocService: Record "E-Document Service"; var EDocument: Record "E-Document"; var Dimensions: Dictionary of [Text, Text])
var
EDocument2: Record "E-Document";
@@ -454,4 +469,5 @@ codeunit 6108 "E-Document Processing"
EDocTelemetryCategoryLbl: Label 'E-Document', Locked = true;
EDocTelemetryIdLbl: Label 'E-Doc %1', Locked = true;
EDocTok: Label 'W1 E-Document', Locked = true;
+ CannotDeletePostedRecordErr: Label 'Cannot delete related record because it is already posted.';
}
diff --git a/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al
index 99292f1b1a..e96a2bef90 100644
--- a/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al
+++ b/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al
@@ -198,7 +198,37 @@ codeunit 6103 "E-Document Subscription"
local procedure OnBeforeOnDeletePurchaseHeader(var PurchaseHeader: Record "Purchase Header"; var IsHandled: Boolean)
begin
if not IsNullGuid(PurchaseHeader."E-Document Link") then
- Error(DeleteNotAllowedErr);
+ if GuiAllowed() then
+ if not Confirm(this.ConfirmDeleteQst) then
+ Error('');
+ end;
+
+ [EventSubscriber(ObjectType::Table, Database::"Purchase Header", 'OnAfterDeleteEvent', '', false, false)]
+ local procedure OnAfterDeletePurchaseHeader(var Rec: Record "Purchase Header"; RunTrigger: Boolean)
+ var
+ EDocument: Record "E-Document";
+ EDocumentService: Record "E-Document Service";
+ EDocumentLog: Codeunit "E-Document Log";
+ EDocumentProcessing: Codeunit "E-Document Processing";
+ EDocServiceStatusDeleted: Enum "E-Document Service Status";
+ begin
+ if IsNullGuid(Rec."E-Document Link") then
+ exit;
+
+ if not EDocument.GetBySystemId(Rec."E-Document Link") then
+ exit;
+
+ EDocServiceStatusDeleted := Enum::"E-Document Service Status"::"Imported Document Deleted";
+ EDocumentService := EDocumentLog.GetLastServiceFromLog(EDocument);
+
+ Clear(EDocument."Document No.");
+ Clear(EDocument."Document Record ID");
+ if Rec."Document Type" = Rec."Document Type"::Order then
+ Clear(EDocument."Order No.");
+
+ EDocumentLog.InsertLog(EDocument, EDocumentService, EDocServiceStatusDeleted);
+ EDocumentProcessing.ModifyServiceStatus(EDocument, EDocumentService, EDocServiceStatusDeleted);
+ EDocumentProcessing.ModifyEDocumentStatus(EDocument, EDocServiceStatusDeleted);
end;
local procedure RunEDocumentCheck(Record: Variant; EDocumentProcPhase: Enum "E-Document Processing Phase")
@@ -270,6 +300,7 @@ codeunit 6103 "E-Document Subscription"
EDocService: Record "E-Document Service";
EDocumentLog: Codeunit "E-Document Log";
EDocLogHelper: Codeunit "E-Document Log Helper";
+ EDocumentProcessing: Codeunit "E-Document Processing";
PostedSourceDocumentHeader: RecordRef;
begin
PostedSourceDocumentHeader.GetTable(PostedRecord);
@@ -281,6 +312,7 @@ codeunit 6103 "E-Document Subscription"
EDocService := EDocumentLog.GetLastServiceFromLog(EDocument);
EDocLogHelper.InsertLog(EDocument, EDocService, Enum::"E-Document Service Status"::"Imported Document Created");
+ EDocumentProcessing.ModifyServiceStatus(EDocument, EDocService, Enum::"E-Document Service Status"::"Imported Document Created");
end;
local procedure CreateEDocumentFromPosedDocument(PostedRecord: Variant)
@@ -308,5 +340,5 @@ codeunit 6103 "E-Document Subscription"
EDocumentHelper: Codeunit "E-Document Helper";
EDocumentProcessingPhase: Enum "E-Document Processing Phase";
WrongAmountErr: Label 'Purchase Document cannot be released as Amount Incl. VAT: %1, is different from E-Document Amount Incl. VAT: %2', Comment = '%1 - Purchase document amount, %2 - E-document amount';
- DeleteNotAllowedErr: Label 'Deletion of Purchase Header linked to E-Document is not allowed.';
+ ConfirmDeleteQst: Label 'This purchase document is created from an E-Document. Do you want to proceed with deletion?';
}
diff --git a/Apps/W1/EDocument/edocument_workspace.code-workspace b/Apps/W1/EDocument/edocument_workspace.code-workspace
new file mode 100644
index 0000000000..35fb4f1ea3
--- /dev/null
+++ b/Apps/W1/EDocument/edocument_workspace.code-workspace
@@ -0,0 +1,24 @@
+{
+ "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
diff --git a/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al b/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al
index da634b7b85..e1fdd0df77 100644
--- a/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al
+++ b/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al
@@ -1430,6 +1430,7 @@ codeunit 139624 "E-Doc E2E Test"
end;
[Test]
+ [HandlerFunctions('DeleteConfirmationHandler')]
procedure DeleteLinkedPurchaseHeaderNoAllowedSuccess()
var
PurchaseHeader: Record "Purchase Header";
@@ -1445,9 +1446,8 @@ codeunit 139624 "E-Doc E2E Test"
PurchaseHeader.Modify();
Commit();
- // [THEN] Fails to delete
+ // [THEN] Show confirmation message and throw error if cancelled
asserterror PurchaseHeader.Delete(true);
- Assert.ExpectedError(DeleteNotAllowedErr);
// [GIVEN] Reset link
PurchaseHeader."E-Document Link" := NullGuid;
@@ -2233,6 +2233,7 @@ codeunit 139624 "E-Doc E2E Test"
end;
[Test]
+ [HandlerFunctions('DeleteConfirmationHandler')]
internal procedure DeleteLinkedPurchaseHeaderNoAllowedSuccess26()
var
PurchaseHeader: Record "Purchase Header";
@@ -2248,9 +2249,8 @@ codeunit 139624 "E-Doc E2E Test"
PurchaseHeader.Modify();
Commit();
- // [THEN] Fails to delete
+ // [THEN] Show confirmation message and throw error if cancelled
asserterror PurchaseHeader.Delete(true);
- Assert.ExpectedError(DeleteNotAllowedErr);
// [GIVEN] Reset link
PurchaseHeader."E-Document Link" := NullGuid;
@@ -2261,4 +2261,12 @@ codeunit 139624 "E-Doc E2E Test"
end;
#endif
+ [ConfirmHandler]
+ procedure DeleteConfirmationHandler(Message: Text[1024]; var Reply: Boolean)
+ var
+ ExpectedConfirmLbl: Label 'This purchase document is created from E-Document. Do you want to proceed with deletion?';
+ begin
+ Assert.ExpectedConfirm(ExpectedConfirmLbl, Message);
+ Reply := false;
+ end;
}
diff --git a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al
index 61041d9c2d..1431c62293 100644
--- a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al
+++ b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al
@@ -1340,6 +1340,59 @@ codeunit 139628 "E-Doc. Receive Test"
PurchaseHeader.Delete(true);
end;
+ [Test]
+ [HandlerFunctions('ConfirmHandlerYes')]
+ procedure RecreateReceivedPurchaseInvoice()
+ var
+ EDocService: Record "E-Document Service";
+ EDocServicePage: TestPage "E-Document Service";
+ EDocumentPage: TestPage "E-Document";
+ CreatedInvoiceNo: Text[20];
+ begin
+ // [FEATURE] [E-Document] [Receive]
+ // [SCENARIO] Delete and recreate purchase invoice from E-Document page
+ Initialize();
+
+ // [GIVEN] e-Document service to receive one single purchase invoice
+ LibraryEDoc.CreateTestReceiveServiceForEDoc(EDocService, Enum::"Service Integration"::"Mock");
+ BindSubscription(this.EDocImplState);
+
+ SetDefaultEDocServiceValues(EDocService);
+
+ // [GIVEN] Purchase invoice
+ CreatePurchaseInvoiceWithLines(this.PurchaseHeader, this.PurchaseLine, this.Vendor);
+
+ PurchOrderTestBuffer.ClearTempVariables();
+ PurchOrderTestBuffer.AddPurchaseDocToTemp(this.PurchaseHeader);
+
+ // [WHEN] Running Receive
+ EDocServicePage.OpenView();
+ EDocServicePage.Filter.SetFilter(Code, EDocService.Code);
+ EDocServicePage.Receive.Invoke();
+
+ // [THEN] Purchase invoice is created with corresponding values
+ EDocumentPage.OpenView();
+ EDocumentPage.Last();
+ CreatedInvoiceNo := EDocumentPage."Document No.".Value;
+
+ CheckPurchaseInvoiceCreatedWithCorrectValues(this.PurchaseHeader, this.CreatedPurchaseHeader, this.PurchaseLine, this.CreatedPurchaseLine, CreatedInvoiceNo);
+
+ // [WHEN] Delete created purchase invoice from E-Document page
+ EDocumentPage.DeleteRelatedDocument.Invoke();
+
+ // [THEN] Check that purchase invoice is deleted
+ this.Assert.AreEqual('', EDocumentPage."Document No.".Value, '');
+ CheckPurchaseInvoiceDeleted(this.CreatedPurchaseHeader, CreatedInvoiceNo);
+
+ // [WHEN] Recreate purchase invoice
+ EDocumentPage.CreateDocument.Invoke();
+
+ // [THEN] Check that purchase invoice is created again with corresponding values
+ CheckPurchaseInvoiceCreatedWithCorrectValues(this.PurchaseHeader, this.CreatedPurchaseHeader, this.PurchaseLine, this.CreatedPurchaseLine, EDocumentPage."Document No.".Value);
+
+ DeletePurchaseHeaders(this.PurchaseHeader, this.CreatedPurchaseHeader);
+ end;
+
[ModalPageHandler]
procedure SelectPOHandler(var POList: TestPage "Purchase Order List")
var
@@ -1397,6 +1450,36 @@ codeunit 139628 "E-Doc. Receive Test"
EDocument.DeleteAll();
end;
+ local procedure SetDefaultEDocServiceValues(var EDocService: Record "E-Document Service")
+ begin
+ 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."Create Journal Lines" := false;
+ EDocService.Modify(false);
+ end;
+
+ local procedure CreatePurchaseInvoiceWithLines(var PurchHeader: Record "Purchase Header"; var PurchLine: Record "Purchase Line"; var Vendor: Record Vendor)
+ var
+ i: Integer;
+ begin
+ this.LibraryPurchase.CreateVendorWithAddress(this.Vendor);
+ this.Vendor."Receive E-Document To" := this.Vendor."Receive E-Document To"::"Purchase Invoice";
+ this.Vendor.Modify(false);
+ this.LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Invoice, this.Vendor."No.");
+
+ for i := 1 to 3 do begin
+ this.LibraryPurchase.CreatePurchaseLine(PurchLine, PurchHeader, PurchLine.Type::Item, this.LibraryInventory.CreateItemNo(), this.LibraryRandom.RandInt(100));
+ PurchLine.Validate("Direct Unit Cost", this.LibraryRandom.RandDecInRange(1, 100, 2));
+ PurchLine.Modify(true);
+ end;
+ end;
+
local procedure CheckPurchaseHeadersAreEqual(var PurchHeader1: Record "Purchase Header"; var PurchHeader2: Record "Purchase Header")
begin
Assert.AreEqual(PurchHeader1."Pay-to Vendor No.", PurchHeader2."Pay-to Vendor No.", '');
@@ -1435,6 +1518,46 @@ codeunit 139628 "E-Doc. Receive Test"
Assert.AreEqual(PurchHeader."Amount Including VAT", Abs(GenJnlLine.Amount), '');
end;
+ local procedure CheckPurchaseInvoiceCreatedWithCorrectValues(PurchHeader: Record "Purchase Header"; var CreatedPurchHeader: Record "Purchase Header"; PurchLine: Record "Purchase Line"; CreatedPurchLine: Record "Purchase Line"; DocumentNo: Code[20])
+ begin
+ CreatedPurchHeader.Reset();
+ CreatedPurchHeader.SetRange("Document Type", CreatedPurchHeader."Document Type"::Invoice);
+ CreatedPurchHeader.SetRange("No.", DocumentNo);
+ CreatedPurchHeader.FindFirst();
+
+ CheckPurchaseHeadersAreEqual(PurchHeader, CreatedPurchHeader);
+
+ CreatedPurchLine.SetRange("Document Type", CreatedPurchHeader."Document Type");
+ CreatedPurchLine.SetRange("Document No.", CreatedPurchHeader."No.");
+ if CreatedPurchLine.FindSet() then
+ repeat
+ PurchLine.SetRange("Document Type", PurchHeader."Document Type");
+ PurchLine.SetRange("Document No.", PurchHeader."No.");
+ PurchLine.SetRange("Line No.", CreatedPurchLine."Line No.");
+ PurchLine.FindFirst();
+ CheckPurchaseLinesAreEqual(PurchLine, CreatedPurchLine);
+ until CreatedPurchLine.Next() = 0;
+ end;
+
+ local procedure CheckPurchaseInvoiceDeleted(var CreatedPurchHeader: Record "Purchase Header"; DocumentNo: Code[20])
+ begin
+ CreatedPurchHeader.Reset();
+ CreatedPurchHeader.SetRange("Document Type", CreatedPurchHeader."Document Type"::Invoice);
+ CreatedPurchHeader.SetRange("No.", DocumentNo);
+ Assert.RecordIsEmpty(CreatedPurchHeader);
+ end;
+
+ local procedure DeletePurchaseHeaders(var PurchHeader: Record "Purchase Header"; var CreatedPurchHeader: Record "Purchase Header")
+ begin
+ PurchHeader.SetHideValidationDialog(true);
+ PurchHeader."E-Document Link" := NullGuid;
+ PurchHeader.Delete(true);
+
+ CreatedPurchHeader.SetHideValidationDialog(true);
+ CreatedPurchHeader."E-Document Link" := NullGuid;
+ CreatedPurchHeader.Delete(true);
+ end;
+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"E-Document Create Purch. Doc.", 'OnBeforeProcessHeaderFieldsAssignment', '', false, false)]
local procedure OnBeforeProcessHeaderFieldsAssignment(var DocumentHeader: RecordRef; var PurchaseField: Record Field);
begin
@@ -2761,5 +2884,4 @@ codeunit 139628 "E-Doc. Receive Test"
#endif
-
}
\ No newline at end of file