Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Microsoft.eServices.EDocument.Format;

using Microsoft.eServices.EDocument.Processing.Import;
using Microsoft.eServices.EDocument.Processing.Interfaces;

enumextension 28006 "PINT A-NZ EDoc Read into Draft" extends "E-Doc. Read into Draft"
{
value(28005; "PINT A-NZ")
{
Caption = 'PINT A-NZ';
Implementation = IStructuredFormatReader = "E-Document PINT A-NZ Handler";
}
}

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions Apps/APAC/EDocumentFormats/PINT A-NZ/test/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,16 @@
"idRanges": [
{
"from": 148003,
"to": 148004
"to": 148007
}
],
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": true,
"includeSourceInSymbolFile": true
},
"application": "27.0.0.0"
}
"application": "27.0.0.0",
"resourceFolders": [
".resources"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
codeunit 148007 "E-Doc. Format Mock" implements "E-Document"
{
SingleInstance = true;

procedure Check(var SourceDocumentHeader: RecordRef; EDocService: Record "E-Document Service"; EDocumentProcessingPhase: enum "E-Document Processing Phase");
begin
OnCheck(SourceDocumentHeader, EDocService, EDocumentProcessingPhase);
end;

procedure Create(EDocService: Record "E-Document Service"; var EDocument: Record "E-Document"; var SourceDocumentHeader: RecordRef; var SourceDocumentLines: RecordRef; var TempBlob: codeunit "Temp Blob");
begin
OnCreate(EDocService, EDocument, SourceDocumentHeader, SourceDocumentLines, TempBlob);
end;

procedure CreateBatch(EDocService: Record "E-Document Service"; var EDocuments: Record "E-Document"; var SourceDocumentHeaders: RecordRef; var SourceDocumentsLines: RecordRef; var TempBlob: codeunit "Temp Blob");
begin
OnCreateBatch(EDocService, EDocuments, SourceDocumentHeaders, SourceDocumentsLines, TempBlob);
end;

procedure GetBasicInfoFromReceivedDocument(var EDocument: Record "E-Document"; var TempBlob: codeunit "Temp Blob");
begin
OnGetBasicInfoFromReceivedDocument(EDocument, TempBlob);
end;

procedure GetCompleteInfoFromReceivedDocument(var EDocument: Record "E-Document"; var CreatedDocumentHeader: RecordRef; var CreatedDocumentLines: RecordRef; var TempBlob: codeunit "Temp Blob");
begin
OnGetCompleteInfoFromReceivedDocument(EDocument, CreatedDocumentHeader, CreatedDocumentLines, TempBlob);
end;

[IntegrationEvent(false, false)]
local procedure OnCheck(var SourceDocumentHeader: RecordRef; EDocService: Record "E-Document Service"; EDocumentProcessingPhase: enum "E-Document Processing Phase")
begin
end;

[IntegrationEvent(false, false)]
local procedure OnCreate(EDocService: Record "E-Document Service"; var EDocument: Record "E-Document"; var SourceDocumentHeader: RecordRef; var SourceDocumentLines: RecordRef; var TempBlob: codeunit "Temp Blob");
begin
end;

[IntegrationEvent(false, false)]
local procedure OnCreateBatch(EDocService: Record "E-Document Service"; var EDocuments: Record "E-Document"; var SourceDocumentHeaders: RecordRef; var SourceDocumentsLines: RecordRef; var TempBlob: codeunit "Temp Blob");
begin
end;

[IntegrationEvent(false, false)]
local procedure OnGetBasicInfoFromReceivedDocument(var EDocument: Record "E-Document"; var TempBlob: codeunit "Temp Blob");
begin
end;

[IntegrationEvent(false, false)]
local procedure OnGetCompleteInfoFromReceivedDocument(var EDocument: Record "E-Document"; var CreatedDocumentHeader: RecordRef; var CreatedDocumentLines: RecordRef; var TempBlob: codeunit "Temp Blob");
begin
end;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enumextension 148003 "E-Doc. Format Mock" extends "E-Document Format"
{
value(6160; "Mock")
{
Implementation = "E-Document" = "E-Doc. Format Mock";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
codeunit 148005 "E-Document Structured Tests"
{
Subtype = Test;
TestType = IntegrationTest;

var
Customer: Record Customer;
Vendor: Record Vendor;
EDocumentService: Record "E-Document Service";
Assert: Codeunit Assert;
LibraryVariableStorage: Codeunit "Library - Variable Storage";
LibraryEDoc: Codeunit "Library - E-Document";
LibraryLowerPermission: Codeunit "Library - Lower Permissions";
PINTANZStructuredValidations: Codeunit "PINTANZ Structured Validations";
IsInitialized: Boolean;
EDocumentStatusNotUpdatedErr: Label 'The status of the EDocument was not updated to the expected status after the step was executed.';
TestFileTok: Label 'pint_a-nz/pint_a-nz-invoice-0.xml', Locked = true;
MockCurrencyCode: Code[10];
MockDate: Date;

#region PINT A-NZ XML
[Test]
procedure TestPINTANZInvoice_ValidDocument()
var
EDocument: Record "E-Document";
begin
// [FEATURE] [E-Document] [PINTANZ] [Import]
// [SCENARIO] Import and process a valid PINTANZ invoice document

// [GIVEN] A valid PINTANZ XML invoice document is imported
Initialize(Enum::"Service Integration"::"No Integration");
SetupPINTANZEDocumentService();
CreateInboundEDocumentFromXML(EDocument, TestFileTok);

// [WHEN] The document is processed to draft status
if ProcessEDocumentToStep(EDocument, "Import E-Document Steps"::"Read into Draft") then begin
PINTANZStructuredValidations.SetMockCurrencyCode(MockCurrencyCode);
PINTANZStructuredValidations.SetMockDate(MockDate);

// [THEN] The full E-Document content is correctly extracted
PINTANZStructuredValidations.AssertFullEDocumentContentExtracted(EDocument."Entry No");
end else
Assert.Fail(EDocumentStatusNotUpdatedErr);
end;

[Test]
[HandlerFunctions('EDocumentPurchaseHeaderPageHandler')]
procedure TestPINTANZInvoice_ValidDocument_ViewExtractedData()
var
EDocument: Record "E-Document";
EDocImport: Codeunit "E-Doc. Import";
begin
// [FEATURE] [E-Document] [PINTANZ] [View Data]
// [SCENARIO] View extracted data from a valid PINTANZ invoice document

// [GIVEN] A valid PINTANZ XML invoice document is imported
Initialize(Enum::"Service Integration"::"No Integration");
SetupPINTANZEDocumentService();
CreateInboundEDocumentFromXML(EDocument, TestFileTok);

// [WHEN] The document is processed to draft status
ProcessEDocumentToStep(EDocument, "Import E-Document Steps"::"Read into Draft");
EDocument.Get(EDocument."Entry No");

// [WHEN] View extracted data is called
EDocImport.ViewExtractedData(EDocument);

// [THEN] The extracted data page opens and can be handled properly (verified by page handler)
// EDocumentPurchaseHeaderPageHandler
end;

[Test]
procedure TestPINTANZInvoice_ValidDocument_PurchaseInvoiceCreated()
var
EDocument: Record "E-Document";
PurchaseHeader: Record "Purchase Header";
DummyItem: Record Item;
EDocumentProcessing: Codeunit "E-Document Processing";
DataTypeManagement: Codeunit "Data Type Management";
RecRef: RecordRef;
VariantRecord: Variant;
begin
// [FEATURE] [E-Document] [PINTANZ] [Purchase Invoice Creation]
// [SCENARIO] Create a purchase invoice from a valid PINTANZ invoice document

// [GIVEN] A valid PINTANZ XML invoice document is imported
Initialize(Enum::"Service Integration"::"No Integration");
SetupPINTANZEDocumentService();
CreateInboundEDocumentFromXML(EDocument, TestFileTok);

// [WHEN] The document is processed through finish draft step
ProcessEDocumentToStep(EDocument, "Import E-Document Steps"::"Finish draft");
EDocument.Get(EDocument."Entry No");

// [WHEN] The created purchase record is retrieved
EDocumentProcessing.GetRecord(EDocument, VariantRecord);
DataTypeManagement.GetRecordRef(VariantRecord, RecRef);
RecRef.SetTable(PurchaseHeader);

// [THEN] The purchase header is correctly created with PINTANZ data
PINTANZStructuredValidations.SetMockCurrencyCode(MockCurrencyCode);
PINTANZStructuredValidations.SetMockDate(MockDate);
PINTANZStructuredValidations.AssertPurchaseDocument(Vendor."No.", PurchaseHeader, DummyItem);
end;

[Test]
procedure TestPINTANZInvoice_ValidDocument_UpdateDraftAndFinalize()
var
EDocument: Record "E-Document";
PurchaseHeader: Record "Purchase Header";
Item: Record Item;
EDocImportParameters: Record "E-Doc. Import Parameters";
EDocImport: Codeunit "E-Doc. Import";
EDocumentProcessing: Codeunit "E-Document Processing";
DataTypeManagement: Codeunit "Data Type Management";
RecRef: RecordRef;
EDocPurchaseDraft: TestPage "E-Document Purchase Draft";
VariantRecord: Variant;
begin
// [FEATURE] [E-Document] [PINTANZ] [Draft Update]
// [SCENARIO] Update draft purchase document data and finalize processing

// [GIVEN] A valid PINTANZ XML invoice document is imported and processed to draft preparation
Initialize(Enum::"Service Integration"::"No Integration");
SetupPINTANZEDocumentService();
CreateInboundEDocumentFromXML(EDocument, TestFileTok);
ProcessEDocumentToStep(EDocument, "Import E-Document Steps"::"Prepare draft");

// [GIVEN] A generic item is created for manual assignment
LibraryEDoc.CreateGenericItem(Item, '');

// [WHEN] The draft document is opened and modified through UI
EDocPurchaseDraft.OpenEdit();
EDocPurchaseDraft.GoToRecord(EDocument);
EDocPurchaseDraft.Lines.First();
EDocPurchaseDraft.Lines."No.".SetValue(Item."No.");
EDocPurchaseDraft.Lines.Next();

// [WHEN] The processing is completed to finish draft step
EDocImportParameters."Step to Run" := "Import E-Document Steps"::"Finish draft";
EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParameters);
EDocument.Get(EDocument."Entry No");

// [WHEN] The final purchase record is retrieved
EDocumentProcessing.GetRecord(EDocument, VariantRecord);
DataTypeManagement.GetRecordRef(VariantRecord, RecRef);
RecRef.SetTable(PurchaseHeader);

// [THEN] The purchase header contains both imported PINTANZ data and manual updates
PINTANZStructuredValidations.SetMockCurrencyCode(MockCurrencyCode);
PINTANZStructuredValidations.SetMockDate(MockDate);
PINTANZStructuredValidations.AssertPurchaseDocument(Vendor."No.", PurchaseHeader, Item);
end;

[PageHandler]
procedure EDocumentPurchaseHeaderPageHandler(var EDocReadablePurchaseDoc: TestPage "E-Doc. Readable Purchase Doc.")
begin
EDocReadablePurchaseDoc.Close();
end;
#endregion

local procedure Initialize(Integration: Enum "Service Integration")
var
TransformationRule: Record "Transformation Rule";
EDocument: Record "E-Document";
EDocDataStorage: Record "E-Doc. Data Storage";
EDocumentsSetup: Record "E-Documents Setup";
EDocumentServiceStatus: Record "E-Document Service Status";
EDocumentPurchaseHeader: Record "E-Document Purchase Header";
EDocumentPurchaseLine: Record "E-Document Purchase Line";
DocumentAttachment: Record "Document Attachment";
Currency: Record Currency;
begin
LibraryLowerPermission.SetOutsideO365Scope();
LibraryVariableStorage.Clear();
Clear(LibraryVariableStorage);

if IsInitialized then
exit;

EDocument.DeleteAll(false);
EDocumentServiceStatus.DeleteAll(false);
EDocumentService.DeleteAll(false);
EDocDataStorage.DeleteAll(false);
EDocumentPurchaseHeader.DeleteAll(false);
EDocumentPurchaseLine.DeleteAll(false);
DocumentAttachment.DeleteAll(false);

LibraryEDoc.SetupStandardVAT();
LibraryEDoc.SetupStandardSalesScenario(Customer, EDocumentService, Enum::"E-Document Format"::"PINT A-NZ", Integration);
LibraryEDoc.SetupStandardPurchaseScenario(Vendor, EDocumentService, Enum::"E-Document Format"::"PINT A-NZ", Integration);
EDocumentService."Import Process" := "E-Document Import Process"::"Version 2.0";
EDocumentService."Read into Draft Impl." := "E-Doc. Read into Draft"::"PINT A-NZ";
EDocumentService.Modify();
EDocumentsSetup.InsertNewExperienceSetup();

// Set a currency that can be used across all localizations
MockCurrencyCode := 'XYZ';
Currency.Init();
Currency.Validate(Code, MockCurrencyCode);
if Currency.Insert(true) then;
CreateCurrencyExchangeRate();

MockDate := DMY2Date(22, 01, 2026);

TransformationRule.DeleteAll(false);
TransformationRule.CreateDefaultTransformations();

IsInitialized := true;
end;

local procedure SetupPINTANZEDocumentService()
begin
EDocumentService."Read into Draft Impl." := "E-Doc. Read into Draft"::"PINT A-NZ";
EDocumentService.Modify(false);
end;

local procedure CreateInboundEDocumentFromXML(var EDocument: Record "E-Document"; FilePath: Text)
var
EDocLogRecord: Record "E-Document Log";
EDocumentLog: Codeunit "E-Document Log";
begin
LibraryEDoc.CreateInboundEDocument(EDocument, EDocumentService);

EDocumentLog.SetBlob('Test', Enum::"E-Doc. File Format"::XML, NavApp.GetResourceAsText(FilePath));
EDocumentLog.SetFields(EDocument, EDocumentService);
EDocLogRecord := EDocumentLog.InsertLog(Enum::"E-Document Service Status"::Imported, Enum::"Import E-Doc. Proc. Status"::Readable);

EDocument."Structured Data Entry No." := EDocLogRecord."E-Doc. Data Storage Entry No.";
EDocument.Modify(false);
end;

local procedure ProcessEDocumentToStep(var EDocument: Record "E-Document"; ProcessingStep: Enum "Import E-Document Steps"): Boolean
var
EDocImportParameters: Record "E-Doc. Import Parameters";
EDocImport: Codeunit "E-Doc. Import";
EDocumentProcessing: Codeunit "E-Document Processing";
begin
EDocumentProcessing.ModifyEDocumentProcessingStatus(EDocument, "Import E-Doc. Proc. Status"::Readable);
EDocImportParameters."Step to Run" := ProcessingStep;
EDocImport.ProcessIncomingEDocument(EDocument, EDocImportParameters);
EDocument.CalcFields("Import Processing Status");

// Update the exit condition to handle different processing steps
case ProcessingStep of
"Import E-Document Steps"::"Read into Draft":
exit(EDocument."Import Processing Status" = Enum::"Import E-Doc. Proc. Status"::"Ready for draft");
"Import E-Document Steps"::"Finish draft":
exit(EDocument."Import Processing Status" = Enum::"Import E-Doc. Proc. Status"::Processed);
"Import E-Document Steps"::"Prepare draft":
exit(EDocument."Import Processing Status" = Enum::"Import E-Doc. Proc. Status"::"Draft Ready");
else
exit(EDocument."Import Processing Status" = Enum::"Import E-Doc. Proc. Status"::"Ready for draft");
end;
end;

local procedure CreateCurrencyExchangeRate()
var
CurrencyExchangeRate: Record "Currency Exchange Rate";
begin
CurrencyExchangeRate.Init();
CurrencyExchangeRate."Currency Code" := MockCurrencyCode;
CurrencyExchangeRate."Starting Date" := WorkDate();
CurrencyExchangeRate."Exchange Rate Amount" := 10;
CurrencyExchangeRate."Relational Exch. Rate Amount" := 1.23;
CurrencyExchangeRate.Insert(true);
end;
}
Loading
Loading