Table 130 Incoming Document
- App
- Base Application
- Namespace
- Microsoft.EServices.EDocument
- Versions
- 17-28
Fields, 51Keys, 6Procedures, 83Events, 46Obsolete, 7
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/eServices/EDocument/IncomingDocument.Table.al2447 lines, Copyright (c) Microsoft Corporation. MIT
// ------------------------------------------------------------------------------------------------
// 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;
using Microsoft.Finance.Currency;
using Microsoft.Finance.GeneralLedger.Journal;
using Microsoft.Finance.GeneralLedger.Ledger;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Finance.VAT.Ledger;
using Microsoft.Purchases.Archive;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.History;
using Microsoft.Purchases.Vendor;
using Microsoft.Sales.Archive;
using Microsoft.Sales.Document;
using Microsoft.Sales.History;
using Microsoft.Utilities;
using System;
using System.Automation;
using System.Environment.Configuration;
using System.IO;
using System.Reflection;
using System.Security.AccessControl;
using System.Threading;
using System.Utilities;
table 130 "Incoming Document"
{
Caption = 'Incoming Document';
DataCaptionFields = "Vendor Name", "Vendor Invoice No.", Description;
DrillDownPageID = "Incoming Documents";
LookupPageID = "Incoming Documents";
Permissions = TableData "G/L Entry" = r;
DataClassification = CustomerContent;
fields
{
field(1; "Entry No."; Integer)
{
AutoIncrement = true;
Caption = 'Entry No.';
ToolTip = 'Specifies the number of the entry, as assigned from the specified number series when the entry was created.';
}
field(2; Description; Text[100])
{
Caption = 'Description';
ToolTip = 'Specifies the description of the incoming document. You must enter the description manually.';
}
field(3; "Created Date-Time"; DateTime)
{
Caption = 'Created Date-Time';
ToolTip = 'Specifies when the incoming document line was created.';
Editable = false;
}
field(4; "Created By User ID"; Guid)
{
Caption = 'Created By User ID';
DataClassification = EndUserPseudonymousIdentifiers;
Editable = false;
TableRelation = User;
}
field(5; "Created By User Name"; Code[50])
{
CalcFormula = lookup(User."User Name" where("User Security ID" = field("Created By User ID")));
Caption = 'Created By User Name';
ToolTip = 'Specifies the name of the user who created the incoming document line.';
Editable = false;
FieldClass = FlowField;
}
field(6; Released; Boolean)
{
Caption = 'Released';
ToolTip = 'Specifies if the incoming document has been approved.';
Editable = false;
}
field(7; "Released Date-Time"; DateTime)
{
Caption = 'Released Date-Time';
ToolTip = 'Specifies when the incoming document was approved.';
Editable = false;
}
field(8; "Released By User ID"; Guid)
{
Caption = 'Released By User ID';
DataClassification = EndUserPseudonymousIdentifiers;
Editable = false;
TableRelation = User;
}
field(9; "Released By User Name"; Code[50])
{
CalcFormula = lookup(User."User Name" where("User Security ID" = field("Released By User ID")));
Caption = 'Released By User Name';
ToolTip = 'Specifies the name of the user who approved the incoming document.';
Editable = false;
FieldClass = FlowField;
}
field(10; "Last Date-Time Modified"; DateTime)
{
Caption = 'Last Date-Time Modified';
ToolTip = 'Specifies when the incoming document line was last modified.';
Editable = false;
}
field(11; "Last Modified By User ID"; Guid)
{
Caption = 'Last Modified By User ID';
DataClassification = EndUserPseudonymousIdentifiers;
Editable = false;
TableRelation = User;
}
field(12; "Last Modified By User Name"; Code[50])
{
CalcFormula = lookup(User."User Name" where("User Security ID" = field("Last Modified By User ID")));
Caption = 'Last Modified By User Name';
ToolTip = 'Specifies the name of the user who last modified the incoming document line.';
Editable = false;
FieldClass = FlowField;
}
field(13; Posted; Boolean)
{
Caption = 'Posted';
ToolTip = 'Specifies if the document or journal line that was created for this incoming document has been posted.';
Editable = false;
}
field(14; "Posted Date-Time"; DateTime)
{
Caption = 'Posted Date-Time';
ToolTip = 'Specifies when the related document or journal line was posted.';
Editable = false;
}
field(15; "Document Type"; Enum "Incoming Related Document Type")
{
Caption = 'Document Type';
ToolTip = 'Specifies the type of document or journal that the incoming document can be connected to.';
Editable = false;
InitValue = " ";
}
field(16; "Document No."; Code[20])
{
Caption = 'Document No.';
ToolTip = 'Specifies the number of the related document or journal line that is created for the incoming document.';
Editable = false;
}
field(17; "Posting Date"; Date)
{
Caption = 'Posting Date';
ToolTip = 'Specifies when the document or journal line that relates to the incoming document was posted.';
ClosingDates = true;
Editable = false;
}
field(18; Status; Enum "Incoming Document Status")
{
Caption = 'Status';
ToolTip = 'Specifies the status of the incoming document record.';
Editable = false;
}
field(60; URL; Text[1024])
{
Caption = 'URL';
ToolTip = 'Specifies the location of the file that represents the incoming document.';
Editable = false;
}
field(23; "Vendor Name"; Text[100])
{
Caption = 'Vendor Name';
ToolTip = 'Specifies the name of the vendor on the incoming document. The field may be filled automatically.';
}
field(24; "Vendor VAT Registration No."; Text[30])
{
Caption = 'Vendor VAT Registration No.';
ToolTip = 'Specifies the VAT registration number of the vendor, if the document contains that number. The field may be filled automatically.';
}
field(25; "Vendor IBAN"; Code[50])
{
Caption = 'Vendor IBAN';
ToolTip = 'Specifies the new value that you want the OCR service to produce for this field going forward.';
}
field(26; "Document Date"; Date)
{
Caption = 'Document Date';
ToolTip = 'Specifies the date that is printed on the incoming document. This is the date when the vendor created the invoice, for example. The field may be filled automatically.';
}
field(27; "Vendor Bank Branch No."; Text[20])
{
Caption = 'Vendor Bank Branch No.';
ToolTip = 'Specifies the new value that you want the OCR service to produce for this field going forward.';
}
field(28; "Vendor Bank Account No."; Text[30])
{
Caption = 'Vendor Bank Account No.';
ToolTip = 'Specifies the bank account number of the vendor on the incoming document.';
}
field(29; "Vendor No."; Code[20])
{
Caption = 'Vendor No.';
ToolTip = 'Specifies the number of the vendor on the incoming document. The field may be filled automatically.';
TableRelation = Vendor;
}
field(30; "Data Exchange Type"; Code[20])
{
Caption = 'Data Exchange Type';
ToolTip = 'Specifies the data exchange type that is used to process the incoming document when it is an electronic document.';
TableRelation = "Data Exchange Type";
}
field(31; "OCR Data Corrected"; Boolean)
{
Caption = 'OCR Data Corrected';
InitValue = false;
}
field(32; "OCR Status"; Option)
{
Caption = 'OCR Status';
ToolTip = 'Specifies the status of the incoming document record when it takes part in the OCR process.';
Editable = false;
OptionCaption = ' ,Ready,Sent,Error,Success,Awaiting Verification';
OptionMembers = " ",Ready,Sent,Error,Success,"Awaiting Verification";
}
field(33; "OCR Track ID"; Text[20])
{
Caption = 'OCR Track ID';
ToolTip = 'Specifies the process stage of the track ID in relation to the OCR service.';
DataClassification = CustomerContent;
Editable = false;
}
field(38; "OCR Service Doc. Template Code"; Code[20])
{
Caption = 'OCR Service Doc. Template Code';
ToolTip = 'Specifies the code of the document template that you want the OCR service provider to use when they convert the incoming-document file to an electronic document. Chose the field to pick a supported document template from the OCR Service Setup window.';
TableRelation = "OCR Service Document Template";
trigger OnValidate()
begin
CalcFields("OCR Service Doc. Template Name");
end;
}
field(39; "OCR Service Doc. Template Name"; Text[50])
{
CalcFormula = lookup("OCR Service Document Template".Name where(Code = field("OCR Service Doc. Template Code")));
Caption = 'OCR Service Doc. Template Name';
ToolTip = 'Specifies the name of the document template that you want the OCR service provider to use when they convert the incoming-document file to an electronic document. Chose the field to pick a supported document template from the OCR Service Setup window.';
Editable = false;
FieldClass = FlowField;
}
field(40; "OCR Process Finished"; Boolean)
{
Caption = 'OCR Process Finished';
}
field(41; "Created Doc. Error Msg. Type"; Option)
{
Caption = 'Created Doc. Error Msg. Type';
InitValue = Error;
OptionCaption = ' ,Error,Warning';
OptionMembers = " ",Error,Warning;
}
field(42; "Vendor Id"; Guid)
{
Caption = 'Vendor Id';
TableRelation = Vendor.SystemId;
}
field(50; "Currency Code"; Code[10])
{
Caption = 'Currency Code';
ToolTip = 'Specifies the currency code, if the document contains that code. The field may be filled automatically.';
trigger OnLookup()
var
Currency: Record Currency;
begin
if PAGE.RunModal(PAGE::Currencies, Currency) = ACTION::LookupOK then
"Currency Code" := Currency.Code;
end;
trigger OnValidate()
var
GeneralLedgerSetup: Record "General Ledger Setup";
Currency: Record Currency;
begin
GeneralLedgerSetup.Get();
if (not Currency.Get("Currency Code")) and ("Currency Code" <> '') and ("Currency Code" <> GeneralLedgerSetup."LCY Code") then
Error(InvalidCurrencyCodeErr);
end;
}
field(51; "Amount Excl. VAT"; Decimal)
{
AutoFormatExpression = Rec."Currency Code";
AutoFormatType = 1;
Caption = 'Amount Excl. VAT';
ToolTip = 'Specifies the amount excluding VAT for the whole document. The field may be filled automatically.';
}
field(52; "Amount Incl. VAT"; Decimal)
{
AutoFormatExpression = Rec."Currency Code";
AutoFormatType = 1;
Caption = 'Amount Incl. VAT';
ToolTip = 'Specifies the amount including VAT for the whole document. The field may be filled automatically.';
}
field(53; "VAT Amount"; Decimal)
{
AutoFormatExpression = Rec."Currency Code";
AutoFormatType = 1;
Caption = 'VAT Amount';
ToolTip = 'Specifies the amount of VAT that is included in the total amount.';
}
field(54; "Due Date"; Date)
{
Caption = 'Due Date';
ToolTip = 'Specifies the date when the vendor document must be paid. The field may be filled automatically.';
}
field(55; "Vendor Invoice No."; Code[35])
{
Caption = 'Vendor Invoice No.';
ToolTip = 'Specifies the document number of the original document you received from the vendor. You can require the document number for posting, or let it be optional. By default, it''s required, so that this document references the original. Making document numbers optional removes a step from the posting process. For example, if you attach the original invoice as a PDF, you might not need to enter the document number. To specify whether document numbers are required, in the Purchases & Payables Setup window, select or clear the Ext. Doc. No. Mandatory field.';
}
field(56; "Order No."; Code[20])
{
Caption = 'Order No.';
ToolTip = 'Specifies the order number, if the document contains that number. The field may be filled automatically.';
}
field(57; "Vendor Phone No."; Text[30])
{
Caption = 'Vendor Phone No.';
ToolTip = 'Specifies the phone number of the vendor on the incoming document.';
}
field(58; "Related Record ID"; RecordID)
{
Caption = 'Related Record ID';
DataClassification = CustomerContent;
}
field(160; "Job Queue Status"; Enum "Inc. Doc. Job Queue Status")
{
Caption = 'Job Queue Status';
ToolTip = 'Specifies the status of the job queue entry that is processing the incoming document.';
Editable = false;
trigger OnLookup()
var
JobQueueEntry: Record "Job Queue Entry";
begin
if Rec."Job Queue Status" = Rec."Job Queue Status"::" " then
exit;
JobQueueEntry.ShowStatusMsg(Rec."Job Queue Entry ID");
end;
}
field(161; "Job Queue Entry ID"; Guid)
{
Caption = 'Job Queue Entry ID';
Editable = false;
}
field(162; Processed; Boolean)
{
Caption = 'Processed';
ToolTip = 'Specifies if the incoming document has been processed.';
}
}
keys
{
key(Key1; "Entry No.")
{
Clustered = true;
}
key(Key2; Status)
{
}
key(Key3; "Document No.", "Posting Date")
{
}
key(Key4; "OCR Status")
{
}
key(Key5; "Vendor No.")
{
}
key(Key6; Processed)
{
}
}
fieldgroups
{
fieldgroup(Brick; "Created Date-Time", Description, "Amount Incl. VAT", Status, "Currency Code")
{
}
}
trigger OnDelete()
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
ActivityLog: Record "Activity Log";
begin
TestField(Posted, false);
DeleteApprovalEntries();
ClearRelatedRecords();
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
if not IncomingDocumentAttachment.IsEmpty() then
IncomingDocumentAttachment.DeleteAll();
ActivityLog.SetRange("Record ID", Rec.RecordId);
if not ActivityLog.IsEmpty() then
ActivityLog.DeleteAll();
ClearErrorMessages();
end;
trigger OnInsert()
var
OCRServiceSetup: Record "OCR Service Setup";
begin
if OCRServiceSetup.Get() then;
"Created Date-Time" := RoundDateTime(CurrentDateTime, 60000);
"Created By User ID" := UserSecurityId();
if "OCR Service Doc. Template Code" = '' then
"OCR Service Doc. Template Code" := OCRServiceSetup."Default OCR Doc. Template";
end;
trigger OnModify()
begin
"Last Date-Time Modified" := RoundDateTime(CurrentDateTime, 60000);
"Last Modified By User ID" := UserSecurityId();
end;
var
IncomingDocumentsSetup: Record "Incoming Documents Setup";
TempErrorMessage: Record "Error Message" temporary;
DocumentType: Option Invoice,"Credit Memo";
UrlTooLongErr: Label 'Only URLs with a maximum of %1 characters are allowed.', Comment = '%1 = length of the URL field (e.g. 1024).';
NoDocumentMsg: Label 'There is no incoming document for this combination of posting date and document number.';
AlreadyUsedInJnlErr: Label 'The incoming document has already been assigned to journal batch %1, line number. %2.', Comment = '%1 = journal batch name, %2=line number.';
AlreadyUsedInDocHdrErr: Label 'The incoming document has already been assigned to %1 %2 (%3).', Comment = '%1=document type, %2=document number, %3=table name, e.g. Sales Header.';
DocPostedErr: Label 'The document related to this incoming document has been posted.';
DocApprovedErr: Label 'This incoming document requires releasing.';
#pragma warning disable AA0470
DetachQst: Label 'Do you want to remove the reference from this incoming document to posted document %1, posting date %2?';
#pragma warning restore AA0470
NotSupportedPurchErr: Label 'Purchase documents of type %1 are not supported.', Comment = '%1 will be Sales/Purchase Header. %2 will be invoice, Credit Memo.';
NotSupportedSalesErr: Label 'Sales documents of type %1 are not supported.', Comment = '%1 will be Sales/Purchase Header. %2 will be invoice, Credit Memo.';
EntityNotFoundErr: Label 'Cannot create the document. Make sure the data exchange definition is correct.';
DocAlreadyCreatedErr: Label 'The document has already been created.';
DocNotCreatedMsg: Label 'The document was not created due to errors in the conversion process.';
DocCreatedMsg: Label '%1 %2 has been created.', Comment = '%1 can be Purchase Invoice, %2 is an ID (e.g. 1001)';
DocCreatedWarningsMsg: Label '%1 %2 has been created with warnings.', Comment = '%1 can be Purchase Invoice, %2 is an ID (e.g. 1001)';
RemovePostedRecordManuallyMsg: Label 'The reference to the posted record has been removed.\\Remember to correct the posted record if needed.';
DeleteRecordQst: Label 'The reference to the record has been removed.\\Do you want to delete the record?';
DocWhenApprovalIsCompleteErr: Label 'The document can only be created when the approval process is complete.';
InvalidCurrencyCodeErr: Label 'You must enter a valid currency code.';
ReplaceMainAttachmentQst: Label 'Are you sure you want to replace the attached file?';
PurchaseTxt: Label 'Purchase';
SalesTxt: Label 'Sales';
PurchaseInvoiceTxt: Label 'Purchase Invoice';
PurchaseCreditMemoTxt: Label 'Purchase Credit Memo';
SalesInvoiceTxt: Label 'Sales Invoice';
SalesCreditMemoTxt: Label 'Sales Credit Memo';
JournalTxt: Label 'Journal';
DoYouWantToRemoveReferenceQst: Label 'Do you want to remove the reference?';
DataExchangeTypeEmptyErr: Label 'You must select a value in the Data Exchange Type field on the incoming document.';
NoDocAttachErr: Label 'No document is attached.\\Attach a document, and then try again.';
GeneralLedgerEntriesTxt: Label 'General Ledger Entries';
CannotReplaceMainAttachmentErr: Label 'Cannot replace the main attachment because the document has already been sent to OCR.';
procedure GetURL(): Text
begin
exit(URL);
end;
procedure SetURL(NewURL: Text)
begin
TestField(Status, Status::New);
TestField(Posted, false);
if StrLen(NewURL) > MaxStrLen(URL) then
Error(UrlTooLongErr, MaxStrLen(URL));
URL := NewURL;
end;
local procedure DeleteApprovalEntries()
var
ApprovalsMgmt: Codeunit "Approvals Mgmt.";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDeleteApprovalEntries(Rec, IsHandled);
if IsHandled then
exit;
ApprovalsMgmt.DeleteApprovalEntries(Rec.RecordId);
end;
[Scope('OnPrem')]
procedure Release()
var
ReleaseIncomingDocument: Codeunit "Release Incoming Document";
begin
ReleaseIncomingDocument.PerformManualRelease(Rec);
end;
procedure Reject()
var
ReleaseIncomingDocument: Codeunit "Release Incoming Document";
begin
ReleaseIncomingDocument.PerformManualReject(Rec);
end;
procedure CheckNotCreated()
begin
if Status = Status::Created then
Error(DocAlreadyCreatedErr);
end;
procedure CreateDocumentWithDataExchange()
var
RelatedRecord: Variant;
begin
if GetRecord(RelatedRecord) then
Error(DocAlreadyCreatedErr);
CreateWithDataExchange("Document Type"::" ")
end;
procedure TryCreateDocumentWithDataExchange()
begin
CreateDocumentWithDataExchange();
end;
procedure CreateReleasedDocumentWithDataExchange()
var
PurchaseHeader: Record "Purchase Header";
ReleasePurchaseDocument: Codeunit "Release Purchase Document";
RecordRef: RecordRef;
Variant: Variant;
begin
CreateWithDataExchange("Document Type"::" ");
GetRecord(Variant);
RecordRef.GetTable(Variant);
if RecordRef.Number <> Database::"Purchase Header" then
exit;
RecordRef.SetTable(PurchaseHeader);
ReleasePurchaseDocument.PerformManualRelease(PurchaseHeader);
end;
local procedure CreateWithDataExchange(DocumentType: Enum "Incoming Related Document Type")
var
ErrorMessage: Record "Error Message";
ApprovalsMgmt: Codeunit "Approvals Mgmt.";
ReleaseIncomingDocument: Codeunit "Release Incoming Document";
OldStatus: Enum "Incoming Document Status";
begin
Find();
if ApprovalsMgmt.IsIncomingDocApprovalsWorkflowEnabled(Rec) and (Status = Status::New) then
Error(DocWhenApprovalIsCompleteErr);
OnCheckIncomingDocCreateDocRestrictions();
if "Data Exchange Type" = '' then
Error(DataExchangeTypeEmptyErr);
"Document Type" := DocumentType;
Modify();
ClearErrorMessages();
TestReadyForProcessing();
CheckNotCreated();
if Status in [Status::New, Status::Failed] then begin
OldStatus := Status;
CODEUNIT.Run(CODEUNIT::"Release Incoming Document", Rec);
TestField(Status, Status::Released);
Status := OldStatus;
Modify();
end;
Commit();
if not CODEUNIT.Run(CODEUNIT::"Incoming Doc. with Data. Exch.", Rec) then begin
ErrorMessage.CopyFromTemp(TempErrorMessage);
SetProcessFailed('');
exit;
end;
ErrorMessage.SetContext(Rec.RecordId);
if ErrorMessage.HasErrors(false) then begin
SetProcessFailed('');
exit;
end;
// identify the created doc
if not UpdateDocumentFields() then begin
SetProcessFailed('');
exit;
end;
ReleaseIncomingDocument.Create(Rec);
ShowResultMessage(ErrorMessage);
end;
local procedure ShowResultMessage(var ErrorMessage: Record "Error Message")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeShowResultMessage(Rec, ErrorMessage, IsHandled);
if IsHandled then
exit;
if ErrorMessage.ErrorMessageCount(ErrorMessage."Message Type"::Warning) > 0 then
Message(DocCreatedWarningsMsg, Format("Document Type"), "Document No.")
else
Message(DocCreatedMsg, Format("Document Type"), "Document No.");
end;
procedure CreateManually()
var
RelatedRecord: Variant;
DocumentTypeOption, DocumentTypeEnum : Integer;
IsHandled: Boolean;
CreatedDocumentType: Dictionary of [Integer, Integer];
CreatedDocumentStrMenu: Text;
begin
IsHandled := false;
OnBeforeCreateManually(Rec, IsHandled);
if IsHandled then
exit;
if GetRecord(RelatedRecord) then
Error(DocAlreadyCreatedErr);
CreatedDocumentType.Add(1, "Document Type"::Journal.AsInteger());
CreatedDocumentType.Add(2, "Document Type"::"Sales Invoice".AsInteger());
CreatedDocumentType.Add(3, "Document Type"::"Sales Credit Memo".AsInteger());
CreatedDocumentType.Add(4, "Document Type"::"Purchase Invoice".AsInteger());
CreatedDocumentType.Add(5, "Document Type"::"Purchase Credit Memo".AsInteger());
CreatedDocumentStrMenu := StrSubstNo('%1,%2,%3,%4,%5', JournalTxt, SalesInvoiceTxt, SalesCreditMemoTxt, PurchaseInvoiceTxt, PurchaseCreditMemoTxt);
OnAfterSetCreatedDocumentType(CreatedDocumentType, CreatedDocumentStrMenu);
DocumentTypeOption := StrMenu(CreatedDocumentStrMenu, 1);
if DocumentTypeOption < 1 then
exit;
DocumentTypeEnum := CreatedDocumentType.Get(DocumentTypeOption);
case DocumentTypeEnum of
"Document Type"::"Purchase Invoice".AsInteger():
CreatePurchInvoice();
"Document Type"::"Purchase Credit Memo".AsInteger():
CreatePurchCreditMemo();
"Document Type"::"Sales Invoice".AsInteger():
CreateSalesInvoice();
"Document Type"::"Sales Credit Memo".AsInteger():
CreateSalesCreditMemo();
"Document Type"::Journal.AsInteger():
CreateGenJnlLine();
else
OnAfterCreateDocumentType(Rec, DocumentTypeEnum);
end;
OnAfterCreateManually(Rec);
end;
procedure CreateGenJnlLine()
var
GenJnlLine: Record "Gen. Journal Line";
LastGenJnlLine: Record "Gen. Journal Line";
LineNo: Integer;
JournalTemplate: Code[10];
JournalBatch: Code[10];
IsHandled: Boolean;
begin
if "Document Type" <> "Document Type"::Journal then
TestIfAlreadyExists();
TestReadyForProcessing();
OnBeforeGetJournalTemplateAndBatch(JournalTemplate, JournalBatch, IsHandled);
if not IsHandled then begin
IncomingDocumentsSetup.TestField("General Journal Template Name");
IncomingDocumentsSetup.TestField("General Journal Batch Name");
JournalTemplate := IncomingDocumentsSetup."General Journal Template Name";
JournalBatch := IncomingDocumentsSetup."General Journal Batch Name";
end;
GenJnlLine.SetRange("Journal Template Name", JournalTemplate);
GenJnlLine.SetRange("Journal Batch Name", JournalBatch);
GenJnlLine.SetRange("Incoming Document Entry No.", "Entry No.");
if not GenJnlLine.IsEmpty() then
exit; // instead; go to the document
GenJnlLine.SetRange("Incoming Document Entry No.");
"Document Type" := "Document Type"::Journal;
if GenJnlLine.FindLast() then;
LastGenJnlLine := GenJnlLine;
LineNo := GenJnlLine."Line No." + 10000;
GenJnlLine.Init();
GenJnlLine."Journal Template Name" := JournalTemplate;
GenJnlLine."Journal Batch Name" := JournalBatch;
GenJnlLine."Line No." := LineNo;
GenJnlLine.SetUpNewLine(LastGenJnlLine, 0, true);
GenJnlLine."Incoming Document Entry No." := "Entry No.";
GenJnlLine.Description := CopyStr(Description, 1, MaxStrLen(GenJnlLine.Description));
OnCreateGenJnlLineOnBeforeGenJnlLineInsert(GenJnlLine, LastGenJnlLine);
if GenJnlLine.Insert(true) then
OnAfterCreateGenJnlLineFromIncomingDocSuccess(Rec)
else
OnAfterCreateGenJnlLineFromIncomingDocFail(Rec);
if GenJnlLine.HasLinks then
GenJnlLine.DeleteLinks();
if GetURL() <> '' then
GenJnlLine.AddLink(GetURL(), Description);
IsHandled := false;
OnCreateGenJnlLineOnBeforeShowRecord(Rec, IsHandled);
if not IsHandled then
ShowRecord();
end;
procedure CreatePurchInvoice()
begin
if "Document Type" <> "Document Type"::"Purchase Invoice" then
TestIfAlreadyExists();
"Document Type" := "Document Type"::"Purchase Invoice";
CreatePurchDoc(DocumentType::Invoice);
end;
procedure CreatePurchCreditMemo()
begin
if "Document Type" <> "Document Type"::"Purchase Credit Memo" then
TestIfAlreadyExists();
"Document Type" := "Document Type"::"Purchase Credit Memo";
CreatePurchDoc(DocumentType::"Credit Memo");
end;
procedure CreateSalesInvoice()
begin
if "Document Type" <> "Document Type"::"Sales Invoice" then
TestIfAlreadyExists();
"Document Type" := "Document Type"::"Sales Invoice";
CreateSalesDoc(DocumentType::Invoice);
end;
procedure CreateSalesCreditMemo()
begin
if "Document Type" <> "Document Type"::"Sales Credit Memo" then
TestIfAlreadyExists();
"Document Type" := "Document Type"::"Sales Credit Memo";
CreateSalesDoc(DocumentType::"Credit Memo");
end;
[Scope('OnPrem')]
procedure CreateGeneralJournalLineWithDataExchange()
var
ErrorMessage: Record "Error Message";
RelatedRecord: Variant;
begin
if GetRecord(RelatedRecord) then
Error(DocAlreadyCreatedErr);
CreateWithDataExchange("Document Type"::Journal);
ErrorMessage.SetContext(Rec.RecordId);
if not ErrorMessage.HasErrors(false) then
OnAfterCreateGenJnlLineFromIncomingDocSuccess(Rec)
else
OnAfterCreateGenJnlLineFromIncomingDocFail(Rec);
end;
[Scope('OnPrem')]
procedure TryCreateGeneralJournalLineWithDataExchange()
begin
CreateGeneralJournalLineWithDataExchange();
end;
procedure RemoveReferenceToWorkingDocument(EntryNo: Integer)
begin
if EntryNo = 0 then
exit;
if not Get(EntryNo) then
exit;
TestField(Posted, false);
Clear("Related Record ID");
"Document Type" := "Document Type"::" ";
"Document No." := '';
// To clear the filters and prevent the page from putting values back
SetRange("Document Type");
SetRange("Document No.");
if Released then
Status := Status::Released
else
Status := Status::New;
ClearErrorMessages();
"Created Doc. Error Msg. Type" := "Created Doc. Error Msg. Type"::Error;
OnRemoveReferenceToWorkingDocumentOnBeforeModify(Rec);
Modify();
end;
procedure RemoveIncomingDocumentEntryNoFromUnpostedDocument()
var
SalesHeader: Record "Sales Header";
DataTypeManagement: Codeunit "Data Type Management";
RelatedRecordRecordRef: RecordRef;
RelatedRecordFieldRef: FieldRef;
RelatedRecordVariant: Variant;
begin
if not GetUnpostedRecord(RelatedRecordVariant) then
exit;
RelatedRecordRecordRef.GetTable(RelatedRecordVariant);
if DataTypeManagement.FindFieldByName(
RelatedRecordRecordRef, RelatedRecordFieldRef, SalesHeader.FieldName("Incoming Document Entry No."))
then begin
RelatedRecordFieldRef.Value := 0;
RelatedRecordRecordRef.Modify(true);
end;
OnAfterRemoveIncomingDocumentEntryNoFromUnpostedDocument(Rec, RelatedRecordVariant);
end;
procedure CreateIncomingDocument(NewDescription: Text; NewURL: Text): Integer
begin
Reset();
Clear(Rec);
Init();
Description := CopyStr(NewDescription, 1, MaxStrLen(Description));
SetURL(NewURL);
Insert(true);
exit("Entry No.");
end;
procedure CreateIncomingDocument(PictureInStream: InStream; FileName: Text)
var
IncomingDocument: Record "Incoming Document";
IncomingDocumentAttachment: Record "Incoming Document Attachment";
FileManagement: Codeunit "File Management";
begin
IncomingDocument.CopyFilters(Rec);
CreateIncomingDocument(FileManagement.GetFileNameWithoutExtension(FileName), '');
AddAttachmentFromStream(IncomingDocumentAttachment, FileName, FileManagement.GetExtension(FileName), PictureInStream);
CopyFilters(IncomingDocument);
end;
procedure TestIfAlreadyExists()
var
GenJnlLine: Record "Gen. Journal Line";
SalesHeader: Record "Sales Header";
PurchaseHeader: Record "Purchase Header";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTestIfAlreadyExists(Rec, IsHandled);
if IsHandled then
exit;
case "Document Type" of
"Document Type"::Journal:
begin
GenJnlLine.SetRange("Incoming Document Entry No.", "Entry No.");
if GenJnlLine.FindFirst() then
Error(AlreadyUsedInJnlErr, GenJnlLine."Journal Batch Name", GenJnlLine."Line No.");
end;
"Document Type"::"Sales Invoice", "Document Type"::"Sales Credit Memo":
begin
SalesHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if SalesHeader.FindFirst() then
Error(AlreadyUsedInDocHdrErr, SalesHeader."Document Type", SalesHeader."No.", SalesHeader.TableCaption());
end;
"Document Type"::"Purchase Invoice", "Document Type"::"Purchase Credit Memo":
begin
PurchaseHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if PurchaseHeader.FindFirst() then
Error(AlreadyUsedInDocHdrErr, PurchaseHeader."Document Type", PurchaseHeader."No.", PurchaseHeader.TableCaption());
end;
else
OnTestIfAlreadyExists("Document Type", "Entry No.");
end;
end;
procedure TestReadyForProcessing()
begin
TestReadyForProcessingForcePosted(false);
end;
local procedure TestReadyForProcessingForcePosted(ForcePosted: Boolean)
begin
if not ForcePosted and Posted then
Error(DocPostedErr);
IncomingDocumentsSetup.Fetch();
if IncomingDocumentsSetup."Require Approval To Create" and (not Released) then
Error(DocApprovedErr);
end;
procedure PostedDocExists(DocumentNo: Code[20]; PostingDate: Date): Boolean
begin
SetRange(Posted, true);
SetRange("Document No.", DocumentNo);
SetRange("Posting Date", PostingDate);
exit(not IsEmpty);
end;
procedure GetRelatedDocType(PostingDate: Date; DocNo: Code[20]; var IsPosted: Boolean): Enum "Incoming Related Document Type"
var
SalesInvoiceHeader: Record "Sales Invoice Header";
SalesCrMemoHeader: Record "Sales Cr.Memo Header";
PurchInvHeader: Record "Purch. Inv. Header";
PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";
GLEntry: Record "G/L Entry";
IncomingRelatedDocumentType: Enum "Incoming Related Document Type";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetRelatedDocType(PostingDate, DocNo, IsPosted, IncomingRelatedDocumentType, IsHandled);
if IsHandled then
exit(IncomingRelatedDocumentType);
IsPosted := true;
case true of
((PostingDate = 0D) or (DocNo = '')):
exit("Document Type"::" ");
PurchInvHeader.Get(DocNo):
if PurchInvHeader."Posting Date" = PostingDate then
exit("Document Type"::"Purchase Invoice");
PurchCrMemoHdr.Get(DocNo):
if PurchCrMemoHdr."Posting Date" = PostingDate then
exit("Document Type"::"Purchase Credit Memo");
SalesInvoiceHeader.Get(DocNo):
if SalesInvoiceHeader."Posting Date" = PostingDate then
exit("Document Type"::"Sales Invoice");
SalesCrMemoHeader.Get(DocNo):
if SalesCrMemoHeader."Posting Date" = PostingDate then
exit("Document Type"::"Sales Credit Memo");
else
GLEntry.SetRange("Posting Date", PostingDate);
GLEntry.SetRange("Document No.", DocNo);
IsPosted := not GLEntry.IsEmpty();
exit("Document Type"::Journal);
end;
IsPosted := false;
exit("Document Type"::" ");
end;
procedure SetPostedDocFields(PostingDate: Date; DocNo: Code[20])
begin
SetPostedDocFieldsForcePosted(PostingDate, DocNo, false);
end;
procedure SetPostedDocFieldsForcePosted(PostingDate: Date; DocNo: Code[20]; ForcePosted: Boolean)
var
CurrIncomingDocument: Record "Incoming Document";
IncomingDocumentAttachment: Record "Incoming Document Attachment";
IncomingDocumentAttachmentCopy: Record "Incoming Document Attachment";
TempBlob: Codeunit "Temp Blob";
RelatedRecordRef: RecordRef;
RelatedRecord: Variant;
begin
TestReadyForProcessingForcePosted(ForcePosted);
if Posted then begin
CurrIncomingDocument.CreateIncomingDocument('', '');
CurrIncomingDocument.TransferFields(Rec, false);
CurrIncomingDocument.Modify();
end;
Posted := true;
Status := Status::Posted;
Processed := true;
"Posted Date-Time" := CurrentDateTime;
"Document No." := DocNo;
"Posting Date" := PostingDate;
if FindPostedRecord(RelatedRecord) then begin
RelatedRecordRef.GetTable(RelatedRecord);
"Related Record ID" := RelatedRecordRef.RecordId;
end;
ClearErrorMessages();
Modify(true);
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
if not IncomingDocumentAttachment.Findset() then
exit;
repeat
if CurrIncomingDocument."Entry No." <> 0 then begin
IncomingDocumentAttachmentCopy := IncomingDocumentAttachment;
IncomingDocumentAttachmentCopy."Incoming Document Entry No." := CurrIncomingDocument."Entry No.";
TempBlob.FromRecord(IncomingDocumentAttachment, IncomingDocumentAttachment.FieldNo(Content));
IncomingDocumentAttachmentCopy.SetContentFromBlob(TempBlob);
IncomingDocumentAttachmentCopy.Insert();
end;
IncomingDocumentAttachment."Document No." := "Document No.";
IncomingDocumentAttachment."Posting Date" := "Posting Date";
IncomingDocumentAttachment.Modify();
until IncomingDocumentAttachment.Next() = 0;
end;
procedure UndoPostedDocFields()
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
DummyRecordID: RecordID;
begin
if "Entry No." = 0 then
exit;
if not Posted then
exit;
if not Confirm(StrSubstNo(DetachQst, "Document No.", "Posting Date"), false) then
exit;
Posted := false;
Processed := false;
Status := Status::Released;
"Posted Date-Time" := 0DT;
"Related Record ID" := DummyRecordID;
"Document No." := '';
"Document Type" := "Document Type"::" ";
"Posting Date" := 0D;
// To clear the filters and prevent the page from putting values back
SetRange("Posted Date-Time");
SetRange("Document No.");
SetRange("Document Type");
SetRange("Posting Date");
Modify(true);
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
IncomingDocumentAttachment.ModifyAll("Document No.", "Document No.");
IncomingDocumentAttachment.ModifyAll("Posting Date", "Posting Date");
Message(RemovePostedRecordManuallyMsg);
end;
procedure UpdateIncomingDocumentFromPosting(IncomingDocumentNo: Integer; PostingDate: Date; DocNo: Code[20])
var
IncomingDocument: Record "Incoming Document";
IsHandled: Boolean;
begin
if IncomingDocumentNo = 0 then
exit;
if not IncomingDocument.Get(IncomingDocumentNo) then
exit;
IsHandled := false;
OnBeforeUpdateIncomingDocumentFromPosting(IncomingDocumentNo, PostingDate, DocNo, IsHandled);
if IsHandled then
exit;
IncomingDocument.SetPostedDocFieldsForcePosted(PostingDate, DocNo, true);
IncomingDocument.Modify();
end;
local procedure ClearRelatedRecords()
var
GenJnlLine: Record "Gen. Journal Line";
SalesHeader: Record "Sales Header";
PurchaseHeader: Record "Purchase Header";
SalesHeaderArchive: Record "Sales Header Archive";
PurchaseHeaderArchive: Record "Purchase Header Archive";
begin
case "Document Type" of
"Document Type"::Journal:
begin
GenJnlLine.SetRange("Incoming Document Entry No.", "Entry No.");
GenJnlLine.ModifyAll("Incoming Document Entry No.", 0, true);
end;
"Document Type"::"Sales Invoice", "Document Type"::"Sales Credit Memo":
begin
SalesHeader.SetRange("Incoming Document Entry No.", "Entry No.");
SalesHeader.ModifyAll("Incoming Document Entry No.", 0, true);
SalesHeaderArchive.SetRange("Incoming Document Entry No.", "Entry No.");
if not SalesHeaderArchive.IsEmpty() then
SalesHeaderArchive.ModifyAll("Incoming Document Entry No.", 0, true);
end;
"Document Type"::"Purchase Invoice", "Document Type"::"Purchase Credit Memo":
begin
PurchaseHeader.SetRange("Incoming Document Entry No.", "Entry No.");
PurchaseHeader.ModifyAll("Incoming Document Entry No.", 0, true);
PurchaseHeaderArchive.SetRange("Incoming Document Entry No.", "Entry No.");
if not PurchaseHeaderArchive.IsEmpty() then
PurchaseHeaderArchive.ModifyAll("Incoming Document Entry No.", 0, true);
end;
else
OnAfterClearRelatedRecords("Document Type", "Entry No.");
end;
end;
local procedure CreateSalesDoc(DocType: Option)
var
SalesHeader: Record "Sales Header";
IsHandled: Boolean;
begin
TestReadyForProcessing();
SalesHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if not SalesHeader.IsEmpty() then begin
ShowRecord();
exit;
end;
SalesHeader.Reset();
SalesHeader.Init();
case DocType of
DocumentType::Invoice:
SalesHeader."Document Type" := SalesHeader."Document Type"::Invoice;
DocumentType::"Credit Memo":
SalesHeader."Document Type" := SalesHeader."Document Type"::"Credit Memo";
end;
OnBeforeCreateSalesHeaderFromIncomingDoc(SalesHeader);
SalesHeader.Insert(true);
OnAfterCreateSalesHeaderFromIncomingDoc(SalesHeader);
if GetURL() <> '' then
SalesHeader.AddLink(GetURL(), Description);
SalesHeader."Incoming Document Entry No." := "Entry No.";
SalesHeader.Modify();
OnCreateSalesDocOnAfterModifySalesHeader(Rec, SalesHeader);
"Document No." := SalesHeader."No.";
Modify(true);
Commit();
IsHandled := false;
OnCreateSalesDocOnBeforeShowRecord(Rec, IsHandled);
if not IsHandled then
ShowRecord();
end;
local procedure CreatePurchDoc(DocType: Option)
var
PurchHeader: Record "Purchase Header";
IsHandled: Boolean;
begin
TestReadyForProcessing();
PurchHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if not PurchHeader.IsEmpty() then begin
ShowRecord();
exit;
end;
PurchHeader.Reset();
PurchHeader.Init();
case DocType of
DocumentType::Invoice:
PurchHeader."Document Type" := PurchHeader."Document Type"::Invoice;
DocumentType::"Credit Memo":
PurchHeader."Document Type" := PurchHeader."Document Type"::"Credit Memo";
end;
OnCreatePurchDocOnBeforePurchHeaderInsert(PurchHeader);
PurchHeader.Insert(true);
OnAfterCreatePurchHeaderFromIncomingDoc(PurchHeader);
if GetURL() <> '' then
PurchHeader.AddLink(GetURL(), Description);
PurchHeader."Incoming Document Entry No." := "Entry No.";
PurchHeader.Modify();
OnCreatePurchDocOnAfterModifyPurchaseHeader(Rec, PurchHeader);
"Document No." := PurchHeader."No.";
Modify(true);
Commit();
IsHandled := false;
OnCreatePurchDocOnBeforeShowRecord(Rec, IsHandled);
if not IsHandled then
ShowRecord();
end;
procedure SetGenJournalLine(var GenJnlLine: Record "Gen. Journal Line")
begin
if GenJnlLine."Incoming Document Entry No." = 0 then
exit;
Get(GenJnlLine."Incoming Document Entry No.");
TestReadyForProcessing();
TestIfAlreadyExists();
"Document Type" := "Document Type"::Journal;
Modify(true);
if not DocLinkExists(GenJnlLine) then
GenJnlLine.AddLink(GetURL(), Description);
end;
procedure SetSalesDoc(var SalesHeader: Record "Sales Header")
begin
if SalesHeader."Incoming Document Entry No." = 0 then
exit;
Get(SalesHeader."Incoming Document Entry No.");
TestReadyForProcessing();
TestIfAlreadyExists();
case SalesHeader."Document Type" of
SalesHeader."Document Type"::Invoice:
"Document Type" := "Document Type"::"Sales Invoice";
SalesHeader."Document Type"::"Credit Memo":
"Document Type" := "Document Type"::"Sales Credit Memo";
end;
Modify();
if not DocLinkExists(SalesHeader) then
SalesHeader.AddLink(GetURL(), Description);
end;
procedure SetPurchDoc(var PurchaseHeader: Record "Purchase Header")
begin
if PurchaseHeader."Incoming Document Entry No." = 0 then
exit;
Get(PurchaseHeader."Incoming Document Entry No.");
TestReadyForProcessing();
TestIfAlreadyExists();
case PurchaseHeader."Document Type" of
PurchaseHeader."Document Type"::Invoice:
"Document Type" := "Document Type"::"Purchase Invoice";
PurchaseHeader."Document Type"::"Credit Memo":
"Document Type" := "Document Type"::"Purchase Credit Memo";
end;
Modify();
if not DocLinkExists(PurchaseHeader) then
PurchaseHeader.AddLink(GetURL(), Description);
end;
procedure DocLinkExists(RecVar: Variant): Boolean
var
RecordLink: Record "Record Link";
RecRef: RecordRef;
begin
if GetURL() = '' then
exit(true);
RecRef.GetTable(RecVar);
RecordLink.SetRange("Record ID", RecRef.RecordId);
RecordLink.SetRange(URL1, URL);
RecordLink.SetRange(Description, Description);
exit(not RecordLink.IsEmpty);
end;
procedure HyperlinkToDocument(DocumentNo: Code[20]; PostingDate: Date)
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
if ForwardToExistingLink(DocumentNo, PostingDate) then
exit;
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
IncomingDocumentAttachment.SetFilter(Type, '<>%1', IncomingDocumentAttachment.Type::XML);
if IncomingDocumentAttachment.FindFirst() then
IncomingDocumentAttachment.Export('', true);
end;
procedure ForwardToExistingLink(DocumentNo: Code[20]; PostingDate: Date): Boolean
begin
SetRange("Document No.", DocumentNo);
SetRange("Posting Date", PostingDate);
if not FindFirst() then begin
Message(NoDocumentMsg);
exit(true);
end;
if GetURL() <> '' then begin
HyperLink(GetURL());
exit(true);
end;
end;
procedure ShowCard(DocumentNo: Code[20]; PostingDate: Date)
begin
SetRange("Document No.", DocumentNo);
SetRange("Posting Date", PostingDate);
if not FindFirst() then
exit;
SetRecFilter();
PAGE.Run(PAGE::"Incoming Document", Rec);
end;
procedure ShowCardFromEntryNo(EntryNo: Integer)
begin
if EntryNo = 0 then
exit;
Get(EntryNo);
SetRecFilter();
PAGE.Run(PAGE::"Incoming Document", Rec);
end;
procedure ImportAttachment(var IncomingDocument: Record "Incoming Document")
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
IncomingDocumentAttachment.NewAttachment();
IncomingDocument.Get(IncomingDocumentAttachment."Incoming Document Entry No.")
end;
[Scope('OnPrem')]
procedure AddXmlAttachmentFromXmlText(var IncomingDocumentAttachment: Record "Incoming Document Attachment"; OrgFileName: Text; XmlText: Text)
var
FileManagement: Codeunit "File Management";
OutStr: OutStream;
begin
TestField("Entry No.");
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
if not IncomingDocumentAttachment.FindLast() then
IncomingDocumentAttachment."Line No." := 10000
else
IncomingDocumentAttachment."Line No." += 10000;
IncomingDocumentAttachment."Incoming Document Entry No." := "Entry No.";
IncomingDocumentAttachment.Init();
IncomingDocumentAttachment.Name :=
CopyStr(FileManagement.GetFileNameWithoutExtension(OrgFileName), 1, MaxStrLen(IncomingDocumentAttachment.Name));
IncomingDocumentAttachment.Validate("File Extension", 'xml');
IncomingDocumentAttachment.Content.CreateOutStream(OutStr, TEXTENCODING::UTF8);
OutStr.WriteText(XmlText);
IncomingDocumentAttachment.Insert(true);
if IncomingDocumentAttachment.Type in [IncomingDocumentAttachment.Type::Image, IncomingDocumentAttachment.Type::PDF] then
IncomingDocumentAttachment.OnAttachBinaryFile();
end;
procedure AddAttachmentFromStream(var IncomingDocumentAttachment: Record "Incoming Document Attachment"; OrgFileName: Text; FileExtension: Text; var InStr: InStream)
var
FileManagement: Codeunit "File Management";
OutStr: OutStream;
begin
TestField("Entry No.");
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
if not IncomingDocumentAttachment.FindLast() then
IncomingDocumentAttachment."Line No." := 10000
else
IncomingDocumentAttachment."Line No." += 10000;
IncomingDocumentAttachment."Incoming Document Entry No." := "Entry No.";
IncomingDocumentAttachment.Init();
IncomingDocumentAttachment.Name :=
CopyStr(FileManagement.GetFileNameWithoutExtension(OrgFileName), 1, MaxStrLen(IncomingDocumentAttachment.Name));
IncomingDocumentAttachment.Validate(
"File Extension", CopyStr(FileExtension, 1, MaxStrLen(IncomingDocumentAttachment."File Extension")));
IncomingDocumentAttachment.Content.CreateOutStream(OutStr);
CopyStream(OutStr, InStr);
IncomingDocumentAttachment.Insert(true);
end;
[Scope('OnPrem')]
procedure AddAttachmentFromServerFile(FileName: Text; FilePath: Text)
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
FileManagement: Codeunit "File Management";
File: File;
InStr: InStream;
begin
if (FileName = '') or (FilePath = '') then
exit;
if not File.Open(FilePath) then
exit;
File.CreateInStream(InStr);
AddAttachmentFromStream(IncomingDocumentAttachment, FileName, FileManagement.GetExtension(FileName), InStr);
File.Close();
if Erase(FilePath) then;
end;
local procedure SetProcessFailed(ErrorMsg: Text[2048])
var
ErrorMessage: Record "Error Message";
ReleaseIncomingDocument: Codeunit "Release Incoming Document";
begin
ReleaseIncomingDocument.Fail(Rec);
if ErrorMsg = '' then begin
ErrorMsg := CopyStr(GetLastErrorText, 1, MaxStrLen(ErrorMessage."Message"));
ClearLastError();
end;
if ErrorMsg <> '' then begin
ErrorMessage.SetContext(Rec.RecordId);
ErrorMessage.LogSimpleMessage(ErrorMessage."Message Type"::Error, ErrorMsg);
end;
if GuiAllowed then
Message(DocNotCreatedMsg);
end;
[TryFunction]
local procedure UpdateDocumentFields()
var
PurchaseHeader: Record "Purchase Header";
SalesHeader: Record "Sales Header";
GenJournalLine: Record "Gen. Journal Line";
DocExists: Boolean;
begin
// If purchase
PurchaseHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if PurchaseHeader.FindFirst() then begin
case PurchaseHeader."Document Type" of
PurchaseHeader."Document Type"::Invoice:
"Document Type" := "Document Type"::"Purchase Invoice";
PurchaseHeader."Document Type"::"Credit Memo":
"Document Type" := "Document Type"::"Purchase Credit Memo";
else
Error(NotSupportedPurchErr, Format(PurchaseHeader."Document Type"));
end;
"Document No." := PurchaseHeader."No.";
exit;
end;
// If sales
SalesHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if SalesHeader.FindFirst() then begin
case SalesHeader."Document Type" of
SalesHeader."Document Type"::Invoice:
"Document Type" := "Document Type"::"Sales Invoice";
SalesHeader."Document Type"::"Credit Memo":
"Document Type" := "Document Type"::"Sales Credit Memo";
else
Error(NotSupportedSalesErr, Format(SalesHeader."Document Type"));
end;
"Document No." := SalesHeader."No.";
exit;
end;
OnUpdateDocumentFieldsOnAfterUpdateDocuments(Rec, DocExists);
if DocExists then
exit;
// If general journal line
GenJournalLine.SetRange("Incoming Document Entry No.", "Entry No.");
if GenJournalLine.FindFirst() then begin
"Document No." := GenJournalLine."Document No.";
exit;
end;
DocExists := false;
OnAfterUpdateDocumentFields(Rec, DocExists);
if not DocExists then
Error(EntityNotFoundErr);
end;
local procedure ClearErrorMessages()
var
ErrorMessage: Record "Error Message";
begin
ErrorMessage.SetRange("Context Record ID", Rec.RecordId);
ErrorMessage.DeleteAll();
TempErrorMessage.SetRange("Context Record ID", Rec.RecordId);
TempErrorMessage.DeleteAll();
end;
procedure SelectIncomingDocument(EntryNo: Integer; RelatedRecordID: RecordID): Integer
var
IncomingDocumentsSetup: Record "Incoming Documents Setup";
IncomingDocument: Record "Incoming Document";
IncomingDocuments: Page "Incoming Documents";
begin
if EntryNo <> 0 then begin
IncomingDocument.Get(EntryNo);
IncomingDocuments.SetRecord(IncomingDocument);
end;
if IncomingDocumentsSetup.Get() then
if IncomingDocumentsSetup."Require Approval To Create" then
IncomingDocument.SetRange(Released, true);
IncomingDocument.SetRange(Posted, false);
IncomingDocuments.SetTableView(IncomingDocument);
IncomingDocuments.LookupMode := true;
if IncomingDocuments.RunModal() = ACTION::LookupOK then begin
IncomingDocuments.GetRecord(IncomingDocument);
IncomingDocument.Validate("Related Record ID", RelatedRecordID);
IncomingDocument.Modify();
exit(IncomingDocument."Entry No.");
end;
exit(EntryNo);
end;
procedure SelectIncomingDocumentForPostedDocument(DocumentNo: Code[20]; PostingDate: Date; RelatedRecordID: RecordID)
var
IncomingDocument: Record "Incoming Document";
EntryNo: Integer;
IsPosted: Boolean;
begin
if (DocumentNo = '') or (PostingDate = 0D) then
exit;
EntryNo := SelectIncomingDocument(0, RelatedRecordID);
if EntryNo = 0 then
exit;
IncomingDocument.Get(EntryNo);
IncomingDocument.SetPostedDocFields(PostingDate, DocumentNo);
IncomingDocument."Document Type" := GetRelatedDocType(PostingDate, DocumentNo, IsPosted);
end;
[Scope('OnPrem')]
procedure SendToJobQueue(ShowMessages: Boolean)
var
SendIncomingDocumentToOCR: Codeunit "Send Incoming Document to OCR";
begin
SendIncomingDocumentToOCR.SetShowMessages(ShowMessages);
SendIncomingDocumentToOCR.SendToJobQueue(Rec);
end;
[Scope('OnPrem')]
procedure ResetOriginalOCRData()
var
OCRServiceMgt: Codeunit "OCR Service Mgt.";
OriginalXMLRootNode: DotNet XmlNode;
begin
OCRServiceMgt.GetOriginalOCRXMLRootNode(Rec, OriginalXMLRootNode);
OCRServiceMgt.UpdateIncomingDocWithOCRData(Rec, OriginalXMLRootNode);
end;
[Scope('OnPrem')]
procedure UploadCorrectedOCRData(): Boolean
var
OCRServiceMgt: Codeunit "OCR Service Mgt.";
begin
exit(OCRServiceMgt.UploadCorrectedOCRFile(Rec))
end;
procedure SaveErrorMessages(var TempErrorMessageRef: Record "Error Message" temporary)
var
EntryNo: Integer;
begin
if not TempErrorMessageRef.FindSet() then
exit;
Clear(TempErrorMessage);
if TempErrorMessage.FindLast() then;
EntryNo := TempErrorMessage.ID + 1;
repeat
TempErrorMessage.TransferFields(TempErrorMessageRef);
TempErrorMessage.ID := EntryNo;
TempErrorMessage.Insert();
EntryNo += 1;
until TempErrorMessageRef.Next() = 0;
end;
procedure RemoveFromJobQueue(ShowMessages: Boolean)
var
SendIncomingDocumentToOCR: Codeunit "Send Incoming Document to OCR";
begin
SendIncomingDocumentToOCR.SetShowMessages(ShowMessages);
SendIncomingDocumentToOCR.RemoveFromJobQueue(Rec);
end;
[Scope('OnPrem')]
procedure SendToOCR(ShowMessages: Boolean)
var
IncomingDocumentCopy: Record "Incoming Document";
SendIncomingDocumentToOCR: Codeunit "Send Incoming Document to OCR";
begin
IncomingDocumentCopy.Copy(Rec);
IncomingDocumentCopy.Reset();
SendIncomingDocumentToOCR.SetShowMessages(ShowMessages);
SendIncomingDocumentToOCR.SendDocToOCR(IncomingDocumentCopy);
SendIncomingDocumentToOCR.ScheduleJobQueueReceive();
end;
procedure SetStatus(NewStatus: Option)
begin
Status := "Incoming Document Status".FromInteger(NewStatus);
Modify();
end;
[Scope('OnPrem')]
procedure RetrieveFromOCR(ShowMessages: Boolean)
var
SendIncomingDocumentToOCR: Codeunit "Send Incoming Document to OCR";
begin
SendIncomingDocumentToOCR.SetShowMessages(ShowMessages);
SendIncomingDocumentToOCR.RetrieveDocFromOCR(Rec);
end;
procedure GetGeneratedFromOCRAttachment(var IncomingDocumentAttachment: Record "Incoming Document Attachment"): Boolean
begin
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
IncomingDocumentAttachment.SetRange("Generated from OCR", true);
exit(IncomingDocumentAttachment.FindFirst());
end;
procedure GetDataExchangePath(FieldNumber: Integer): Text
var
DataExchangeType: Record "Data Exchange Type";
DataExchLineDef: Record "Data Exch. Line Def";
PurchaseHeader: Record "Purchase Header";
VendorBankAccount: Record "Vendor Bank Account";
Vendor: Record Vendor;
GLEntry: Record "G/L Entry";
DataExchangePath: Text;
begin
if not DataExchangeType.Get("Data Exchange Type") then
exit('');
DataExchLineDef.SetRange("Data Exch. Def Code", DataExchangeType."Data Exch. Def. Code");
DataExchLineDef.SetRange("Parent Code", '');
if not DataExchLineDef.FindFirst() then
exit('');
OnGetDataExchangePathOnBeforeCase(DataExchLineDef, FieldNumber, DataExchangePath);
if DataExchangePath <> '' then
exit(DataExchangePath);
case FieldNumber of
FieldNo("Vendor Name"):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Buy-from Vendor Name")));
FieldNo("Vendor Id"):
exit(DataExchLineDef.GetPath(Database::Vendor, Vendor.FieldNo(SystemId)));
FieldNo("Vendor No."):
exit(DataExchLineDef.GetPath(Database::Vendor, Vendor.FieldNo("No.")));
FieldNo("Vendor VAT Registration No."):
exit(DataExchLineDef.GetPath(Database::Vendor, Vendor.FieldNo("VAT Registration No.")));
FieldNo("Vendor IBAN"):
exit(DataExchLineDef.GetPath(Database::"Vendor Bank Account", VendorBankAccount.FieldNo(IBAN)));
FieldNo("Vendor Bank Branch No."):
exit(DataExchLineDef.GetPath(Database::"Vendor Bank Account", VendorBankAccount.FieldNo("Bank Branch No.")));
FieldNo("Vendor Bank Account No."):
exit(DataExchLineDef.GetPath(Database::"Vendor Bank Account", VendorBankAccount.FieldNo("Bank Account No.")));
FieldNo("Vendor Phone No."):
exit(DataExchLineDef.GetPath(Database::Vendor, Vendor.FieldNo("Phone No.")));
FieldNo("Vendor Invoice No."):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Vendor Invoice No.")));
FieldNo("Document Date"):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Document Date")));
FieldNo("Due Date"):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Due Date")));
FieldNo("Currency Code"):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Currency Code")));
FieldNo("Amount Excl. VAT"):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo(Amount)));
FieldNo("Amount Incl. VAT"):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Amount Including VAT")));
FieldNo("Order No."):
exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Vendor Order No.")));
FieldNo("VAT Amount"):
exit(DataExchLineDef.GetPath(Database::"G/L Entry", GLEntry.FieldNo("VAT Amount")));
else begin
OnGetDataExchangePath(DataExchLineDef, FieldNumber, DataExchangePath);
if DataExchangePath <> '' then
exit(DataExchangePath);
end;
end;
exit('');
end;
procedure ShowRecord()
var
PageManagement: Codeunit "Page Management";
DataTypeManagement: Codeunit "Data Type Management";
RecRef: RecordRef;
RelatedRecord: Variant;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeShowRecord(Rec, IsHandled);
if IsHandled then
exit;
if GetRecord(RelatedRecord) then begin
DataTypeManagement.GetRecordRef(RelatedRecord, RecRef);
PageManagement.PageRun(RecRef);
end;
end;
procedure GetRecord(var RelatedRecord: Variant): Boolean
begin
if Posted then
exit(GetPostedRecord(RelatedRecord));
exit(GetUnpostedRecord(RelatedRecord));
end;
local procedure GetPostedRecord(var RelatedRecord: Variant): Boolean
var
RelatedRecordRef: RecordRef;
begin
if GetRelatedRecord(RelatedRecordRef) then begin
RelatedRecord := RelatedRecordRef;
exit(true);
end;
exit(FindPostedRecord(RelatedRecord));
end;
local procedure FindPostedRecord(var RelatedRecord: Variant): Boolean
var
SalesInvoiceHeader: Record "Sales Invoice Header";
SalesCrMemoHeader: Record "Sales Cr.Memo Header";
PurchInvHeader: Record "Purch. Inv. Header";
PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";
GLEntry: Record "G/L Entry";
RecordFound: Boolean;
begin
case "Document Type" of
"Document Type"::Journal:
begin
GLEntry.SetCurrentKey("Document No.", "Posting Date");
GLEntry.SetRange("Document No.", "Document No.");
GLEntry.SetRange("Posting Date", "Posting Date");
if GLEntry.FindFirst() then begin
RelatedRecord := GLEntry;
exit(true);
end;
end;
"Document Type"::"Sales Invoice":
if SalesInvoiceHeader.Get("Document No.") then begin
RelatedRecord := SalesInvoiceHeader;
exit(true);
end;
"Document Type"::"Sales Credit Memo":
if SalesCrMemoHeader.Get("Document No.") then begin
RelatedRecord := SalesCrMemoHeader;
exit(true);
end;
"Document Type"::"Purchase Invoice":
if PurchInvHeader.Get("Document No.") then begin
RelatedRecord := PurchInvHeader;
exit(true);
end;
"Document Type"::"Purchase Credit Memo":
if PurchCrMemoHdr.Get("Document No.") then begin
RelatedRecord := PurchCrMemoHdr;
exit(true);
end;
end;
RecordFound := false;
OnAfterFindPostedRecord(RelatedRecord, RecordFound, Rec);
exit(RecordFound);
end;
local procedure GetUnpostedRecord(var RelatedRecord: Variant): Boolean
var
RelatedRecordRef: RecordRef;
begin
if GetRelatedRecord(RelatedRecordRef) then begin
RelatedRecord := RelatedRecordRef;
exit(true);
end;
exit(FindUnpostedRecord(RelatedRecord));
end;
local procedure FindUnpostedRecord(var RelatedRecord: Variant): Boolean
var
SalesHeader: Record "Sales Header";
PurchaseHeader: Record "Purchase Header";
GenJournalLine: Record "Gen. Journal Line";
RecordFound: Boolean;
begin
case "Document Type" of
"Document Type"::Journal:
begin
GenJournalLine.SetRange("Incoming Document Entry No.", "Entry No.");
if GenJournalLine.FindFirst() then begin
GenJournalLine.SetRange("Journal Batch Name", GenJournalLine."Journal Batch Name");
GenJournalLine.SetRange("Journal Template Name", GenJournalLine."Journal Template Name");
OnFindUnpostedRecordOnAfterFilterGenJournalLine(Rec, GenJournalLine);
RelatedRecord := GenJournalLine;
exit(true)
end;
end;
"Document Type"::"Sales Invoice",
"Document Type"::"Sales Credit Memo":
begin
SalesHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if SalesHeader.FindFirst() then begin
RelatedRecord := SalesHeader;
exit(true);
end;
end;
"Document Type"::"Purchase Invoice",
"Document Type"::"Purchase Credit Memo":
begin
PurchaseHeader.SetRange("Incoming Document Entry No.", "Entry No.");
if PurchaseHeader.FindFirst() then begin
RelatedRecord := PurchaseHeader;
exit(true);
end;
end;
end;
RecordFound := false;
OnAfterFindUnpostedRecord(RelatedRecord, RecordFound, Rec);
exit(RecordFound);
end;
local procedure GetRelatedRecord(var RelatedRecordRef: RecordRef): Boolean
var
RelatedRecordID: RecordID;
begin
RelatedRecordID := "Related Record ID";
if RelatedRecordID.TableNo = 0 then
exit(false);
RelatedRecordRef := RelatedRecordID.GetRecord();
exit(RelatedRecordRef.Get(RelatedRecordID));
end;
procedure RemoveLinkToRelatedRecord()
var
DummyRecordID: RecordID;
begin
"Related Record ID" := DummyRecordID;
"Document No." := '';
"Document Type" := "Document Type"::" ";
Modify(true);
end;
procedure RemoveReferencedRecords()
var
RecRef: RecordRef;
NavRecordVariant: Variant;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeRemoveReferencedRecords(Rec, IsHandled);
if IsHandled then
exit;
if Posted then
UndoPostedDocFields()
else begin
if not Confirm(DoYouWantToRemoveReferenceQst) then
exit;
if Confirm(DeleteRecordQst) then
if GetRecord(NavRecordVariant) then begin
RecRef.GetTable(NavRecordVariant);
RecRef.Delete(true);
exit;
end;
RemoveIncomingDocumentEntryNoFromUnpostedDocument();
RemoveReferenceToWorkingDocument("Entry No.");
end;
end;
procedure CreateFromAttachment()
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
IncomingDocument: Record "Incoming Document";
begin
if IncomingDocumentAttachment.Import(true) then begin
IncomingDocument.Get(IncomingDocumentAttachment."Incoming Document Entry No.");
PAGE.Run(PAGE::"Incoming Document", IncomingDocument);
end;
end;
procedure GetMainAttachment(var IncomingDocumentAttachment: Record "Incoming Document Attachment"): Boolean
begin
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
IncomingDocumentAttachment.SetRange("Main Attachment", true);
exit(IncomingDocumentAttachment.FindFirst())
end;
procedure GetMainAttachmentFileName(): Text
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
if GetMainAttachment(IncomingDocumentAttachment) then
exit(IncomingDocumentAttachment.GetFullName());
exit('');
end;
procedure GetRecordLinkText(): Text
var
DataTypeManagement: Codeunit "Data Type Management";
RecRef: RecordRef;
VariantRecord: Variant;
begin
if GetRecord(VariantRecord) and DataTypeManagement.GetRecordRef(VariantRecord, RecRef) then
exit(GetRelatedRecordCaption(RecRef));
exit('');
end;
local procedure GetRelatedRecordCaption(var RelatedRecordRef: RecordRef): Text
var
GenJournalLine: Record "Gen. Journal Line";
RecCaption: Text;
begin
if RelatedRecordRef.IsEmpty() then
exit('');
case RelatedRecordRef.Number of
Database::"Sales Header":
RecCaption := StrSubstNo('%1 %2', SalesTxt, GetRecordCaption(RelatedRecordRef));
Database::"Sales Invoice Header":
RecCaption := StrSubstNo('%1 - %2', SalesInvoiceTxt, GetRecordCaption(RelatedRecordRef));
Database::"Sales Cr.Memo Header":
RecCaption := StrSubstNo('%1 - %2', SalesCreditMemoTxt, GetRecordCaption(RelatedRecordRef));
Database::"Purchase Header":
RecCaption := StrSubstNo('%1 %2', PurchaseTxt, GetRecordCaption(RelatedRecordRef));
Database::"Purch. Inv. Header":
RecCaption := StrSubstNo('%1 - %2', PurchaseInvoiceTxt, GetRecordCaption(RelatedRecordRef));
Database::"Purch. Cr. Memo Hdr.":
RecCaption := StrSubstNo('%1 - %2', PurchaseCreditMemoTxt, GetRecordCaption(RelatedRecordRef));
Database::"G/L Entry":
RecCaption := StrSubstNo('%1 - %2', "Document Type", GeneralLedgerEntriesTxt);
Database::"Gen. Journal Line":
if Posted then
RecCaption := StrSubstNo('%1 - %2', "Document Type", GeneralLedgerEntriesTxt)
else begin
RelatedRecordRef.SetTable(GenJournalLine);
if GenJournalLine."Document Type" <> GenJournalLine."Document Type"::" " then
RecCaption := StrSubstNo('%1 - %2', GenJournalLine."Document Type", GetRecordCaption(RelatedRecordRef))
else
RecCaption := StrSubstNo('%1 - %2', JournalTxt, GetRecordCaption(RelatedRecordRef));
end;
else
RecCaption := StrSubstNo('%1 - %2', RelatedRecordRef.Caption, GetRecordCaption(RelatedRecordRef));
end;
OnAfterGetRelatedRecordCaption(RelatedRecordRef, RecCaption);
exit(RecCaption);
end;
procedure GetRecordCaption(var RecRef: RecordRef): Text
var
FieldRef: FieldRef;
KeyRef: KeyRef;
KeyNo: Integer;
FieldNo: Integer;
RecCaption: Text;
begin
for KeyNo := 1 to RecRef.KeyCount do begin
KeyRef := RecRef.KeyIndex(KeyNo);
if KeyRef.Active then begin
for FieldNo := 1 to KeyRef.FieldCount do begin
FieldRef := KeyRef.FieldIndex(FieldNo);
if RecCaption <> '' then
RecCaption := StrSubstNo('%1 - %2', RecCaption, FieldRef.Value)
else
RecCaption := Format(FieldRef.Value);
end;
break;
end
end;
exit(RecCaption);
end;
procedure GetOCRResutlFileName(): Text
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
FileName: Text;
begin
FileName := '';
if GetGeneratedFromOCRAttachment(IncomingDocumentAttachment) then
FileName := IncomingDocumentAttachment.GetFullName();
exit(FileName);
end;
[Scope('OnPrem')]
procedure MainAttachmentDrillDown()
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
if not GetMainAttachment(IncomingDocumentAttachment) then begin
IncomingDocumentAttachment.NewAttachment();
exit;
end;
// Download
IncomingDocumentAttachment.Export('', true);
end;
[Scope('OnPrem')]
procedure ReplaceOrInsertMainAttachment()
begin
ReplaceMainAttachment('');
end;
[Scope('OnPrem')]
procedure ReplaceMainAttachment(FilePath: Text)
var
MainIncomingDocumentAttachment: Record "Incoming Document Attachment";
NewIncomingDocumentAttachment: Record "Incoming Document Attachment";
ImportAttachmentIncDoc: Codeunit "Import Attachment - Inc. Doc.";
begin
if not CanReplaceMainAttachment() then
Error(CannotReplaceMainAttachmentErr);
if not GetMainAttachment(MainIncomingDocumentAttachment) then begin
MainIncomingDocumentAttachment.NewAttachment();
exit;
end;
if not Confirm(ReplaceMainAttachmentQst) then
exit;
if FilePath = '' then
ImportAttachmentIncDoc.UploadFile(NewIncomingDocumentAttachment, FilePath);
if FilePath = '' then
exit;
MainIncomingDocumentAttachment.Delete();
Commit();
NewIncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
ImportAttachmentIncDoc.ImportAttachment(NewIncomingDocumentAttachment, FilePath);
end;
[Scope('OnPrem')]
procedure ShowMainAttachment()
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
if GetMainAttachment(IncomingDocumentAttachment) then
IncomingDocumentAttachment.Export('', true);
end;
[Scope('OnPrem')]
procedure OCRResultDrillDown()
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
if not GetGeneratedFromOCRAttachment(IncomingDocumentAttachment) then
exit;
IncomingDocumentAttachment.Export('', true);
end;
procedure GetAdditionalAttachments(var IncomingDocumentAttachment: Record "Incoming Document Attachment"): Boolean
begin
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
IncomingDocumentAttachment.SetRange("Main Attachment", false);
IncomingDocumentAttachment.SetRange("Generated from OCR", false);
exit(IncomingDocumentAttachment.FindSet());
end;
procedure DefaultAttachmentIsXML(): Boolean
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
IncomingDocumentAttachment.SetRange(Default, true);
if IncomingDocumentAttachment.FindFirst() then
exit(IncomingDocumentAttachment.Type = IncomingDocumentAttachment.Type::XML);
exit(false);
end;
procedure FindByDocumentNoAndPostingDate(MainRecordRef: RecordRef; var IncomingDocument: Record "Incoming Document"): Boolean
var
SalesInvoiceHeader: Record "Sales Invoice Header";
VATEntry: Record "VAT Entry";
DataTypeManagement: Codeunit "Data Type Management";
DocumentNoFieldRef: FieldRef;
PostingDateFieldRef: FieldRef;
begin
if not DataTypeManagement.FindFieldByName(MainRecordRef, DocumentNoFieldRef, SalesInvoiceHeader.FieldName("No.")) then
if not DataTypeManagement.FindFieldByName(MainRecordRef, DocumentNoFieldRef, VATEntry.FieldName("Document No.")) then
exit(false);
if not DataTypeManagement.FindFieldByName(MainRecordRef, PostingDateFieldRef, SalesInvoiceHeader.FieldName("Posting Date")) then
exit(false);
exit(FindByDocumentNoAndPostingDate(IncomingDocument, DocumentNoFieldRef.Value, PostingDateFieldRef.Value))
end;
procedure FindByDocumentNoAndPostingDate(MainRecordRef: RecordRef; var IncomingDocument: Record "Incoming Document"; DocumentNo: Text; PostingDateText: Text): Boolean
var
SalesHeader: Record "Sales Header";
PurchaseHeader: Record "Purchase Header";
PostingDate: Date;
begin
if (DocumentNo = '') or (PostingDateText = '') then
exit(false);
if not Evaluate(PostingDate, PostingDateText) then
exit(false);
IncomingDocument.SetRange("Document No.", DocumentNo);
IncomingDocument.SetRange("Posting Date", PostingDate);
case MainRecordRef.Number of
Database::"Sales Invoice Header":
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Sales Invoice");
IncomingDocument.SetRange(Posted, true);
end;
Database::"Purch. Inv. Header":
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Purchase Invoice");
IncomingDocument.SetRange(Posted, true);
end;
Database::"Sales Cr.Memo Header":
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Sales Credit Memo");
IncomingDocument.SetRange(Posted, true);
end;
Database::"Purch. Cr. Memo Hdr.":
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Purchase Credit Memo");
IncomingDocument.SetRange(Posted, true);
end;
Database::"Sales Header":
begin
MainRecordRef.SetTable(SalesHeader);
case SalesHeader."Document Type" of
SalesHeader."Document Type"::Invoice, SalesHeader."Document Type"::Order, SalesHeader."Document Type"::Quote:
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Sales Invoice");
IncomingDocument.SetRange(Posted, false);
end;
SalesHeader."Document Type"::"Credit Memo":
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Sales Credit Memo");
IncomingDocument.SetRange(Posted, false);
end;
end;
end;
Database::"Purchase Header":
begin
MainRecordRef.SetTable(PurchaseHeader);
case PurchaseHeader."Document Type" of
PurchaseHeader."Document Type"::Invoice, PurchaseHeader."Document Type"::Order, PurchaseHeader."Document Type"::Quote:
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Purchase Invoice");
IncomingDocument.SetRange(Posted, false);
end;
PurchaseHeader."Document Type"::"Credit Memo":
begin
IncomingDocument.SetRange("Document Type", IncomingDocument."Document Type"::"Purchase Credit Memo");
IncomingDocument.SetRange(Posted, false);
end;
end
end;
else
OnFindByDocumentNoAndPostingDateOnSetFilters(IncomingDocument, MainRecordRef);
end;
exit(IncomingDocument.FindFirst());
end;
procedure FindByDocumentNoAndPostingDate(var IncomingDocument: Record "Incoming Document"; DocumentNo: Text; PostingDateText: Text): Boolean
var
PostingDate: Date;
IsFound: Boolean;
IsHandled: Boolean;
begin
if (DocumentNo = '') or (PostingDateText = '') then
exit(false);
if not Evaluate(PostingDate, PostingDateText) then
exit(false);
IsHandled := false;
OnFindByDocumentNoAndPostingDateOnBeforeFind(IncomingDocument, DocumentNo, PostingDate, IsFound, IsHandled);
if IsHandled then
exit(IsFound);
IncomingDocument.SetRange("Document No.", DocumentNo);
IncomingDocument.SetRange("Posting Date", PostingDate);
exit(IncomingDocument.FindFirst());
end;
procedure FindFromIncomingDocumentEntryNo(MainRecordRef: RecordRef; var IncomingDocument: Record "Incoming Document") Result: Boolean
var
SalesHeader: Record "Sales Header";
DataTypeManagement: Codeunit "Data Type Management";
IncomingDocumentEntryNoFieldRef: FieldRef;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeFindFromIncomingDocumentEntryNo(MainRecordRef, IncomingDocument, Result, IsHandled);
if IsHandled then
exit;
if not DataTypeManagement.FindFieldByName(
MainRecordRef, IncomingDocumentEntryNoFieldRef, SalesHeader.FieldName("Incoming Document Entry No."))
then
exit(false);
exit(IncomingDocument.Get(Format(IncomingDocumentEntryNoFieldRef.Value)));
end;
procedure GetStatusStyleText(): Text
begin
case Status of
Status::Rejected,
Status::Failed:
exit('Unfavorable');
else
exit('Standard');
end;
end;
[IntegrationEvent(true, false)]
[Scope('OnPrem')]
procedure OnCheckIncomingDocReleaseRestrictions()
begin
end;
[IntegrationEvent(true, false)]
[Scope('OnPrem')]
procedure OnCheckIncomingDocCreateDocRestrictions()
begin
end;
[IntegrationEvent(true, false)]
[Scope('OnPrem')]
procedure OnCheckIncomingDocSetForOCRRestrictions()
begin
end;
procedure WaitingToReceiveFromOCR(): Boolean
begin
if "OCR Status" in ["OCR Status"::Sent, "OCR Status"::"Awaiting Verification"] then
exit(true);
exit(false);
end;
procedure OCRIsEnabled(): Boolean
var
OCRServiceSetup: Record "OCR Service Setup";
begin
if not OCRServiceSetup.Get() then
exit(false);
exit(OCRServiceSetup.Enabled);
end;
procedure IsADocumentAttached(): Boolean
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", "Entry No.");
if GetURL() = '' then
if IncomingDocumentAttachment.IsEmpty() then
exit(false);
exit(true);
end;
procedure TestReadyForApproval()
begin
if IsADocumentAttached() then
exit;
Error(NoDocAttachErr);
end;
procedure HasAttachment(): Boolean
var
IncomingDocumentAttachment: Record "Incoming Document Attachment";
begin
exit(GetMainAttachment(IncomingDocumentAttachment));
end;
procedure CanReplaceMainAttachment() CanReplaceMainAttachment: Boolean
var
IsHandled: Boolean;
begin
OnBeforeCanReplaceMainAttachment(CanReplaceMainAttachment, Rec, IsHandled);
if IsHandled then
exit(CanReplaceMainAttachment);
if not HasAttachment() then
exit(true);
exit(not WasSentToOCR());
end;
local procedure WasSentToOCR(): Boolean
begin
exit("OCR Status" <> "OCR Status"::" ");
end;
[IntegrationEvent(false, false)]
procedure OnAfterCreateGenJnlLineFromIncomingDocSuccess(var IncomingDocument: Record "Incoming Document")
begin
end;
[IntegrationEvent(false, false)]
procedure OnAfterCreateGenJnlLineFromIncomingDocFail(var IncomingDocument: Record "Incoming Document")
begin
end;
[IntegrationEvent(false, false)]
procedure OnAfterCreateManually(var IncomingDocument: Record "Incoming Document")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnAfterCreateSalesHeaderFromIncomingDoc(var SalesHeader: Record "Sales Header")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnAfterCreatePurchHeaderFromIncomingDoc(var PurchHeader: Record "Purchase Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterFindPostedRecord(var RelatedRecord: Variant; var RecordFound: Boolean; var IncomingDocument: Record "Incoming Document")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterFindUnpostedRecord(var RelatedRecord: Variant; var RecordFound: Boolean; var IncomingDocument: Record "Incoming Document")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterGetRelatedRecordCaption(var RelatedRecordRef: RecordRef; var RecCaption: Text)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterUpdateDocumentFields(var IncomingDocument: Record "Incoming Document"; var DocExists: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeCreateManually(var IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeCreateSalesHeaderFromIncomingDoc(var SalesHeader: Record "Sales Header")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeDeleteApprovalEntries(var IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeShowResultMessage(var IncomingDocument: Record "Incoming Document"; var ErrorMessage: Record "Error Message"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeFindFromIncomingDocumentEntryNo(MainRecordRef: RecordRef; var IncomingDocument: Record "Incoming Document"; var Result: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnCreatePurchDocOnBeforePurchHeaderInsert(var PurchHeader: Record "Purchase Header")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnCreateGenJnlLineOnBeforeGenJnlLineInsert(var GenJnlLine: Record "Gen. Journal Line"; LastGenJnlLine: Record "Gen. Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnGetDataExchangePath(DataExchLineDef: Record "Data Exch. Line Def"; FieldNumber: Integer; var DataExchangePath: Text)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeGetJournalTemplateAndBatch(var JournalTemplate: Code[10]; var JournalBatch: Code[10]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateGenJnlLineOnBeforeShowRecord(var IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateSalesDocOnBeforeShowRecord(var IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreatePurchDocOnBeforeShowRecord(var IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRemoveReferenceToWorkingDocumentOnBeforeModify(var IncomingDocument: Record "Incoming Document")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetCreatedDocumentType(var CreatedDocumentType: Dictionary of [Integer, Integer]; var CreatedDocumentStrMenu: Text)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCreateDocumentType(var IncomingDocument: Record "Incoming Document"; DocumentTypeEnum: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTestIfAlreadyExists(IncomingRelatedDocumentType: Enum "Incoming Related Document Type"; EntryNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetRelatedDocType(PostingDate: Date; DocNo: Code[20]; var IsPosted: Boolean; var IncomingRelatedDocumentType: Enum "Incoming Related Document Type"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterClearRelatedRecords(IncomingRelatedDocumentType: Enum "Incoming Related Document Type"; EntryNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnGetDataExchangePathOnBeforeCase(DataExchLineDef: Record "Data Exch. Line Def"; FieldNumber: Integer; DataExchangePath: Text)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRemoveReferencedRecords(var IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnFindByDocumentNoAndPostingDateOnBeforeFind(var IncomingDocument: Record "Incoming Document"; DocumentNo: Text; PostingDate: Date; var IsFound: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateSalesDocOnAfterModifySalesHeader(var IncomingDocument: Record "Incoming Document"; var SalesHeader: Record "Sales Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreatePurchDocOnAfterModifyPurchaseHeader(var IncomingDocument: Record "Incoming Document"; var PurchaseHeader: Record "Purchase Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateIncomingDocumentFromPosting(IncomingDocumentNo: Integer; PostingDate: Date; DocNo: Code[20]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeShowRecord(var IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnFindUnpostedRecordOnAfterFilterGenJournalLine(var IncomingDocument: Record "Incoming Document"; var GenJournalLine: Record "Gen. Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCanReplaceMainAttachment(var CanReplaceMainAttachment: Boolean; IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTestIfAlreadyExists(IncomingDocument: Record "Incoming Document"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateDocumentFieldsOnAfterUpdateDocuments(var IncomingDocument: Record "Incoming Document"; var DocExists: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnFindByDocumentNoAndPostingDateOnSetFilters(var IncomingDocument: Record "Incoming Document"; MainRecordRef: RecordRef)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterRemoveIncomingDocumentEntryNoFromUnpostedDocument(var IncomingDocument: Record "Incoming Document"; RelatedRecord: Variant)
begin
end;
}