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-Documents Core] - Manual multiple files import #8

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Apps/W1/EDocument/app/src/Document/EDocument.Page.al
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,13 @@ page 6121 "E-Document"
Visible = IsIncomingDoc and (not IsProcessed);

trigger OnAction()
var
EDocumentService: Record "E-Document Service";
begin
EDocImport.UploadDocument(Rec);
CurrPage.Update();
if EDocImport.ChooseEDocumentService(EDocumentService) then begin
EDocImport.UploadDocument(Rec, EDocumentService);
CurrPage.Update(false);
end;
end;
}
action(TextToAccountMapping)
Expand Down
59 changes: 59 additions & 0 deletions Apps/W1/EDocument/app/src/Document/EDocument.Table.al
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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.';
}
51 changes: 38 additions & 13 deletions Apps/W1/EDocument/app/src/Document/EDocuments.Page.al
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,42 @@ page 6122 "E-Documents"
{
area(Processing)
{
#if not CLEAN26
action(ImportManually)
{
Caption = 'New From File';
ToolTip = 'Create an electronic document by manually uploading a file.';
Image = Import;
Visible = false;
petemchlk marked this conversation as resolved.
Show resolved Hide resolved
ObsoleteState = Pending;
ObsoleteTag = '26.0';
ObsoleteReason = 'Functionality moved to "Import Files" action.';

trigger OnAction()
begin
NewFromFile();
end;
}
#endif
fileuploadaction(ImportManuallyMultiple)
{
Caption = 'Import Files';
ToolTip = 'Create electronic documents by uploading single or multiple files.';
Image = Import;
AllowedFileExtensions = '.xml';
AllowMultipleFiles = true;
petemchlk marked this conversation as resolved.
Show resolved Hide resolved

trigger OnAction(Files: List of [FileUpload])
var
EDocumentService: Record "E-Document Service";
EDocImport: Codeunit "E-Doc. Import";
begin
if EDocImport.ChooseEDocumentService(EDocumentService) then begin
EDocImport.UploadDocuments(Files, EDocumentService);
CurrPage.Update(false);
end;
end;
}
action(EDocumentServices)
{
RunObject = Page "E-Document Services";
Expand All @@ -88,27 +113,27 @@ page 6122 "E-Documents"
}
area(Promoted)
{
actionref(Promoted_ImportManually; ImportManually) { }
#if not CLEAN26
actionref(Promoted_ImportManually; ImportManually)
{
Visible = false;
ObsoleteState = Pending;
ObsoleteTag = '26.0';
ObsoleteReason = 'Functionality moved to "Import Files" action.';
}
#endif
actionref(Promoted_ImportManuallyMultiple; ImportManuallyMultiple) { }
actionref(Promoted_EDocumentServices; EDocumentServices) { }
}
}

var
DocNotCreatedQst: Label 'Failed to create new %1 from E-Document. Do you want to open E-Document and see the reported errors?', Comment = '%1 - E-Document Document Type';


local procedure NewFromFile()
var
EDocument: Record "E-Document";
EDocumentService: Record "E-Document Service";
EDocImport: Codeunit "E-Doc. Import";
EDocErrorHelper: Codeunit "E-Document Error Helper";
begin
EDocImport.UploadDocument(EDocument);
if EDocument."Entry No" <> 0 then begin
EDocImport.ProcessDocument(EDocument, false);
if EDocErrorHelper.HasErrors(EDocument) then
if Confirm(DocNotCreatedQst, true, EDocument."Document Type") then
Page.Run(Page::"E-Document", EDocument);
end;
if EDocImport.ChooseEDocumentService(EDocumentService) then
EDocImport.UploadDocument(EDocument, EDocumentService)
end;
}
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,15 +210,15 @@ 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;
Expand All @@ -234,7 +235,6 @@ codeunit 6134 "E-Doc. Integration Management"
exit(true);
end;

petemchlk marked this conversation as resolved.
Show resolved Hide resolved

#endregion

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


#endregion

var
Expand Down
139 changes: 118 additions & 21 deletions Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,30 @@ codeunit 6140 "E-Doc. Import"
tabledata "E-Document" = im,
tabledata "E-Doc. Imported Line" = imd;

internal procedure UploadDocument(var EDocument: Record "E-Document")
internal procedure UploadDocument(var EDocument: Record "E-Document"; EDocumentService: Record "E-Document Service")
var
EDocumentService: Record "E-Document Service";
TempBlob: Codeunit "Temp Blob";
OutStr: OutStream;
InStr: InStream;
FileName: Text;
begin
if Page.RunModal(Page::"E-Document Services", EDocumentService) <> Action::LookupOK then
exit;

if not UploadIntoStream('', '', '', FileName, InStr) then
exit;

TempBlob.CreateOutStream(OutStr);
CopyStream(OutStr, InStr);

EDocument.Direction := EDocument.Direction::Incoming;
EDocument."Document Type" := Enum::"E-Document Type"::None;
this.HandleSingleDocumentUpload(InStr, EDocument, EDocumentService);
end;

if EDocument."Entry No" = 0 then begin
EDocument.Insert(true);
EDocumentProcessing.InsertServiceStatus(EDocument, EDocumentService, Enum::"E-Document Service Status"::Imported);
end else begin
EDocument.Modify(true);
EDocumentProcessing.ModifyServiceStatus(EDocument, EDocumentService, Enum::"E-Document Service Status"::Imported);
end;
internal procedure UploadDocuments(Documents: List of [FileUpload]; EDocumentService: Record "E-Document Service")
var
EDocument: Record "E-Document";
DocumentInStream: InStream;
begin
if Documents.Count() = 0 then
exit;

EDocumentLog.InsertLog(EDocument, EDocumentService, TempBlob, Enum::"E-Document Service Status"::Imported);
EDocumentProcessing.ModifyEDocumentStatus(EDocument, Enum::"E-Document Service Status"::Imported);
if Documents.Count() = 1 then begin
Documents.Get(1).CreateInStream(DocumentInStream);
this.HandleSingleDocumentUpload(DocumentInStream, EDocument, EDocumentService)
end else
this.HandleMultipleDocumentUpload(Documents, EDocument, EDocumentService);
end;

internal procedure GetBasicInfo(var EDocument: Record "E-Document")
Expand Down Expand Up @@ -620,6 +614,32 @@ codeunit 6140 "E-Doc. Import"
until TempEDocImportedLine.Next() = 0;
end;

internal procedure ChooseEDocumentService(var EDocumentService: Record "E-Document Service"): Boolean
begin
exit(Page.RunModal(Page::"E-Document Services", EDocumentService) = Action::LookupOK);
end;

local procedure ImportEDocumentFromStream(var EDocument: Record "E-Document"; EDocumentService: Record "E-Document Service"; var InStr: InStream)
var
TempBlob: Codeunit "Temp Blob";
begin
CopyStream(TempBlob.CreateOutStream(), InStr);

EDocument.Direction := EDocument.Direction::Incoming;
EDocument."Document Type" := Enum::"E-Document Type"::None;

if EDocument."Entry No" = 0 then begin
EDocument.Insert(true);
EDocumentProcessing.InsertServiceStatus(EDocument, EDocumentService, Enum::"E-Document Service Status"::Imported);
end else begin
EDocument.Modify(true);
EDocumentProcessing.ModifyServiceStatus(EDocument, EDocumentService, Enum::"E-Document Service Status"::Imported);
end;

EDocumentLog.InsertLog(EDocument, EDocumentService, TempBlob, Enum::"E-Document Service Status"::Imported);
EDocumentProcessing.ModifyEDocumentStatus(EDocument, Enum::"E-Document Service Status"::Imported);
end;

internal procedure SetHideDialogs(Hide: Boolean)
begin
HideDialogs := Hide;
Expand All @@ -637,6 +657,79 @@ codeunit 6140 "E-Doc. Import"
end;
#endif

local procedure HandleMultipleDocumentUpload(var Documents: List of [FileUpload]; var EDocument: Record "E-Document"; EDocumentService: Record "E-Document Service")
petemchlk marked this conversation as resolved.
Show resolved Hide resolved
var
TempBlob: Codeunit "Temp Blob";
Document: FileUpload;
DocumentInstream: InStream;
NotProcessedDocuments: Integer;
begin
this.SetHideDialogs(true);

foreach Document in Documents do begin
Clear(EDocument);
Clear(DocumentInstream);
Clear(TempBlob);
Document.CreateInStream(DocumentInstream);
CopyStream(TempBlob.CreateOutStream(), DocumentInstream);
if HasDuplicate(EDocument, TempBlob, EDocumentService."Document Format") then
NotProcessedDocuments += 1
else
CreateEDocumentFromStream(EDocument, EDocumentService, DocumentInstream);
end;

if NotProcessedDocuments > 0 then
Message(StrSubstNo(DuplicatesMsg, NotProcessedDocuments, Documents.Count()))
else
Message(DocsImportedMsg);
end;

internal procedure HandleSingleDocumentUpload(DocumentInstream: InStream; var EDocument: Record "E-Document"; EDocumentService: Record "E-Document Service")
var
TempBlob: Codeunit "Temp Blob";
begin
CopyStream(TempBlob.CreateOutStream(), DocumentInstream);
if HasDuplicate(EDocument, TempBlob, EDocumentService."Document Format") then
Error(
EDocumentAlreadyExistErr,
EDocument.FieldCaption("Incoming E-Document No."),
EDocument."Incoming E-Document No.",
EDocument.FieldCaption("Bill-to/Pay-to No."),
EDocument."Bill-to/Pay-to No.",
EDocument.FieldCaption("Document Date"),
EDocument."Document Date")
else
CreateEDocumentFromStream(EDocument, EDocumentService, DocumentInstream);

if not this.HideDialogs and EDocErrorHelper.HasErrors(EDocument) then
if Confirm(DocNotCreatedQst, true, EDocument."Document Type") then
Page.Run(Page::"E-Document", EDocument);
end;

local procedure HasDuplicate(var IncomingEDocument: Record "E-Document"; var EDocumentContent: Codeunit "Temp Blob"; IEDocument: Interface "E-Document"): Boolean
var
EDocGetBasicInfo: Codeunit "E-Doc. Get Basic Info";
begin
// Commit before getting basic info with error handling (if Codeunit.Run then)
Commit();
EDocGetBasicInfo.SetValues(IEDocument, IncomingEDocument, EDocumentContent);
if not EDocGetBasicInfo.Run() then
exit(false);
EDocGetBasicInfo.GetValues(IEDocument, IncomingEDocument, EDocumentContent);

exit(IncomingEDocument.IsDuplicate());
end;

internal procedure CreateEDocumentFromStream(
var EDocument: Record "E-Document";
EDocumentService: Record "E-Document Service";
var DocumentInstream: InStream)
begin
DocumentInstream.ResetPosition();
this.ImportEDocumentFromStream(EDocument, EDocumentService, DocumentInstream);
this.ProcessDocument(EDocument, false);
end;

var
EDocumentLog: Codeunit "E-Document Log";
EDocImportHelper: Codeunit "E-Document Import Helper";
Expand All @@ -651,6 +744,10 @@ codeunit 6140 "E-Doc. Import"
DocTypeIsNotSupportedErr: Label 'Document type %1 is not supported.', Comment = '%1 - Document Type';
FailedToFindVendorErr: Label 'No vendor is set for Edocument';
CannotProcessEDocumentMsg: Label 'Cannot process E-Document %1 with Purchase Order %2 before Purchase Order has been matched and posted for E-Document %3.', Comment = '%1 - E-Document entry no, %2 - Purchase Order number, %3 - EDocument entry no.';
DocNotCreatedQst: Label 'Failed to create new %1 from E-Document. Do you want to open E-Document and see the reported errors?', Comment = '%1 - E-Document Document Type';
EDocumentAlreadyExistErr: Label 'E-Document with %1 %2, %3 %4 and %5 %6 already exists.', Comment = '%1 - Incoming E-Document No. field caption, %2 - Incoming E-Document No. value, %3 - Bill-to/Pay-to No. field caption, %4 - Bill-to/Pay-to No. value, %5 - Document Date field caption, %6 - Document Date value.';
DuplicatesMsg: Label '%1 of %2 uploaded documents were not imported because they already exist in the system.', Comment = '%1 - Not processed documents, %2 - Total documents';
DocsImportedMsg: Label 'Document(s) imported successfully.';

[IntegrationEvent(false, false)]
local procedure OnAfterProcessImportedDocument(var EDocument: Record "E-Document"; var DocumentHeader: RecordRef)
Expand Down
Loading