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

#27057 EDocument Connector for Tietoevry #27233 #27626

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions Apps/W1/EDocumentConnectors/Tietoevry/app/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"id": "3b3c094c-ae7f-43f2-9246-22111b688d2e",
"name": "E-Document Connector - Tietoevry",
"publisher": "Microsoft",
"brief": "E-Document Connector - Tietoevry",
"description": "E-Document Connector - Tietoevry",
"version": "26.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": "https://go.microsoft.com/fwlink/?linkid=2204541",
"url": "https://go.microsoft.com/fwlink/?LinkId=724011",
"logo": "ExtensionLogo.png",
"contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603",
"dependencies": [
{
"id": "e1d97edc-c239-46b4-8d84-6368bdf67c8b",
"name": "E-Document Core",
"publisher": "Microsoft",
"version": "26.0.0.0"
},
{
"id": "d852a468-263e-49e5-bfda-f09e33342b89",
"name": "E-Documents Connector with External Endpoints",
"publisher": "Microsoft",
"version": "26.0.0.0"
}
],
"internalsVisibleTo": [
{
"id": "985549ff-145a-4b5c-acd1-db6d425f6cbc",
"name": "E-Document Connector - Tietoevry Tests",
"publisher": "Microsoft"
}
],
"screenshots": [

],
"platform": "26.0.0.0",
"idRanges": [
{
"from": 6380,
"to": 6389
}
],
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": true,
"includeSourceInSymbolFile": true
},
"application": "26.0.0.0",
"target": "OnPrem",
"features": [
"TranslationFile"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// ------------------------------------------------------------------------------------------------
// 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.EDocumentConnector.Tietoevry;

using Microsoft.Sales.Peppol;
using Microsoft.Sales.Document;
using Microsoft.Foundation.Company;
using Microsoft.Sales.Customer;
using Microsoft.eServices.EDocument;
using System.Utilities;
using Microsoft.eServices.EDocument.Service.Participant;

codeunit 6380 "Connection Events"
{
SingleInstance = true;
EventSubscriberInstance = StaticAutomatic;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"PEPPOL Validation", OnCheckSalesDocumentOnBeforeCheckCompanyVATRegNo, '', false, false)]
local procedure "PEPPOL Validation_OnCheckSalesDocumentOnBeforeCheckCompanyVATRegNo"(SalesHeader: Record "Sales Header"; CompanyInformation: Record "Company Information"; var IsHandled: Boolean)
var
ExternalConnectionSetup: Record "Connection Setup";
begin
if not ExternalConnectionSetup.Get() then
exit;

IsHandled := true;
if CompanyInformation."VAT Registration No." = '' then
Error(MissingCompInfVATRegNoErr, CompanyInformation.TableCaption());
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"PEPPOL Validation", OnCheckSalesDocumentOnBeforeCheckCustomerVATRegNo, '', false, false)]
local procedure "PEPPOL Validation_OnCheckSalesDocumentOnBeforeCheckCustomerVATRegNo"(SalesHeader: Record "Sales Header"; Customer: Record Customer; var IsHandled: Boolean)
var
ServiceParticipant: Record "Service Participant";
EDocumentService: Record "E-Document Service";
EDocExtConnectionSetup: Record "Connection Setup";
begin
if not EDocExtConnectionSetup.Get() then
exit;
EDocumentService.SetRange("Service Integration", EDocumentService."Service Integration"::Tietoevry);
if not EDocumentService.FindFirst() then
exit;

IsHandled := true;
if (SalesHeader."Document Type" in [SalesHeader."Document Type"::Invoice, SalesHeader."Document Type"::Order, SalesHeader."Document Type"::"Credit Memo"]) and
Customer.Get(SalesHeader."Bill-to Customer No.")
then
if Customer."VAT Registration No." = '' then
Error(MissingCustInfoErr, Customer.FieldCaption("VAT Registration No."), Customer."No.");

if not ServiceParticipant.Get(EDocumentService.Code, ServiceParticipant."Participant Type"::Customer, SalesHeader."Bill-to Customer No.") then
ServiceParticipant.Init();

if ServiceParticipant."Participant Identifier" = '' then
Error(MissingCustInfoErr, ServiceParticipant.FieldCaption("Participant Identifier"), Customer."No.");
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"E-Doc. Import", 'OnAfterInsertImportedEdocument', '', false, false)]
local procedure OnAfterInsertEdocument(var EDocument: Record "E-Document"; EDocumentService: Record "E-Document Service"; var TempBlob: Codeunit "Temp Blob"; EDocCount: Integer; HttpRequest: HttpRequestMessage; HttpResponse: HttpResponseMessage)
var
LocalHttpRequest: HttpRequestMessage;
LocalHttpResponse: HttpResponseMessage;
DocumentOutStream: OutStream;
ContentData, MessageId : Text;
begin
if EDocumentService."Service Integration" <> EDocumentService."Service Integration"::Tietoevry then
exit;

HttpResponse.Content.ReadAs(ContentData);
if not TietoevryProcessing.ParseReceivedDocument(ContentData, EDocument."Index In Batch", MessageId) then begin
EDocumentErrorHelper.LogSimpleErrorMessage(EDocument, DocumentIdNotFoundErr);
exit;
end;

TietoevryConnection.HandleGetTargetDocumentRequest(MessageId, LocalHttpRequest, LocalHttpResponse, false);
EDocumentLogHelper.InsertIntegrationLog(EDocument, EDocumentService, LocalHttpRequest, LocalHttpResponse);

LocalHttpResponse.Content.ReadAs(ContentData);
if ContentData = '' then
EDocumentErrorHelper.LogSimpleErrorMessage(EDocument, StrSubstNo(CouldNotRetrieveDocumentErr, MessageId));

Clear(TempBlob);
TempBlob.CreateOutStream(DocumentOutStream, TextEncoding::UTF8);
DocumentOutStream.WriteText(ContentData);

TietoevryProcessing.AcknowledgeEDocument(EDocument, EDocumentService, MessageId);

EDocument."Message Id" := CopyStr(MessageId, 1, MaxStrLen(EDocument."Message Id"));

EDocumentLogHelper.InsertLog(EDocument, EDocumentService, TempBlob, "E-Document Service Status"::Imported);
end;

[EventSubscriber(ObjectType::Table, Database::"E-Document Service", 'OnAfterValidateEvent', 'Document Format', false, false)]
local procedure OnAfterValidateDocumentFormat(var Rec: Record "E-Document Service"; var xRec: Record "E-Document Service"; CurrFieldNo: Integer)
var
EDocServiceSupportedType: Record "E-Doc. Service Supported Type";
begin
if Rec."Document Format" <> Rec."Document Format"::"TE PEPPOL BIS 3.0" then
exit;

EDocServiceSupportedType.SetRange("E-Document Service Code", Rec.Code);
if EDocServiceSupportedType.IsEmpty() then begin
EDocServiceSupportedType.Init();
EDocServiceSupportedType."E-Document Service Code" := Rec.Code;
EDocServiceSupportedType."Source Document Type" := EDocServiceSupportedType."Source Document Type"::"Sales Invoice";
EDocServiceSupportedType.Insert();

EDocServiceSupportedType."Source Document Type" := EDocServiceSupportedType."Source Document Type"::"Sales Credit Memo";
EDocServiceSupportedType.Insert();

EDocServiceSupportedType."Source Document Type" := EDocServiceSupportedType."Source Document Type"::"Service Invoice";
EDocServiceSupportedType.Insert();

EDocServiceSupportedType."Source Document Type" := EDocServiceSupportedType."Source Document Type"::"Service Credit Memo";
EDocServiceSupportedType.Insert();
end;
end;

[EventSubscriber(ObjectType::Table, Database::"Service Participant", 'OnAfterValidateEvent', 'Participant Identifier', false, false)]
local procedure OnAfterValidateServiceParticipant(var Rec: Record "Service Participant"; var xRec: Record "Service Participant"; CurrFieldNo: Integer)
var
EDocumentService: Record "E-Document Service";
begin
if not EDocumentService.Get(Rec.Service) then
exit;
if EDocumentService."Service Integration" <> EDocumentService."Service Integration"::Tietoevry then
exit;
if Rec."Participant Identifier" <> '' then
if not TietoevryProcessing.IsValidSchemeId(Rec."Participant Identifier") then
Rec.FieldError(Rec."Participant Identifier");
end;

var
TietoevryConnection: Codeunit "Connection";
TietoevryProcessing: Codeunit "Processing";
EDocumentLogHelper: Codeunit "E-Document Log Helper";
EDocumentErrorHelper: Codeunit "E-Document Error Helper";
#pragma warning disable AA0470
MissingCompInfVATRegNoErr: Label 'You must specify VAT Registration No. in %1.', Comment = '%1=Company Information';
#pragma warning restore AA0470
#pragma warning disable AA0470
MissingCustInfoErr: Label 'You must specify %1 for Customer %2.', Comment = '%1=Fieldcaption %2=Customer No.';
#pragma warning restore AA0470
CouldNotRetrieveDocumentErr: Label 'Could not retrieve document with id: %1 from the service', Comment = '%1 - Document ID';
DocumentIdNotFoundErr: Label 'Document ID not found in response';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// ------------------------------------------------------------------------------------------------
// 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.EDocumentConnector.Tietoevry;

using Microsoft.EServices.EDocument;
using System.Utilities;
using Microsoft.Purchases.Posting;
using Microsoft.Purchases.Document;

codeunit 6381 "Connection"
{
Access = Internal;
Permissions = tabledata "E-Document" = m;

procedure HandleSendDocumentRequest(var TempBlob: Codeunit "Temp Blob"; var EDocument: Record "E-Document"; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage; Retry: Boolean): Boolean
begin
if not TietoevryAPIRequests.SendDocumentRequest(TempBlob, EDocument, HttpRequest, HttpResponse) then
if Retry then
TietoevryAPIRequests.SendDocumentRequest(TempBlob, EDocument, HttpRequest, HttpResponse);

exit(CheckIfSuccessfulRequest(EDocument, HttpResponse));
end;

procedure CheckDocumentStatus(var EDocument: Record "E-Document"; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage; Retry: Boolean): Boolean
begin
if not TietoevryAPIRequests.GetDocumentStatusRequest(EDocument, HttpRequest, HttpResponse) then
if Retry then
TietoevryAPIRequests.GetDocumentStatusRequest(EDocument, HttpRequest, HttpResponse);

exit(CheckIfSuccessfulRequest(EDocument, HttpResponse));
end;

procedure GetReceivedDocuments(var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage; Retry: Boolean): Boolean
var
InputTxt: Text;
begin
if not TietoevryAPIRequests.GetReceivedDocumentsRequest(HttpRequest, HttpResponse) then
if Retry then
TietoevryAPIRequests.GetReceivedDocumentsRequest(HttpRequest, HttpResponse);

if not HttpResponse.IsSuccessStatusCode then
exit(false);

InputTxt := ParseAsJsonArray(HttpResponse.Content);
if InputTxt <> '' then
exit(true);
end;

procedure HandleGetTargetDocumentRequest(DocumentId: Text; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage; Retry: Boolean): Boolean
begin
if not TietoevryAPIRequests.GetTargetDocumentRequest(DocumentId, HttpRequest, HttpResponse) then
if Retry then
TietoevryAPIRequests.GetTargetDocumentRequest(DocumentId, HttpRequest, HttpResponse);

if HttpResponse.IsSuccessStatusCode then
exit(true);
end;

procedure HandleSendFetchDocumentRequest(DocumentId: Text; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage; Retry: Boolean): Boolean
begin
if not TietoevryAPIRequests.SendAcknowledgeDocumentRequest(DocumentId, HttpRequest, HttpResponse) then
if Retry then
TietoevryAPIRequests.SendAcknowledgeDocumentRequest(DocumentId, HttpRequest, HttpResponse);

if HttpResponse.IsSuccessStatusCode then
exit(true);
end;

procedure ParseAsJsonArray(HttpContentResponse: HttpContent): Text
var
ResponseJArray: JsonArray;
ResponseJson: Text;
Result: Text;
IsJsonResponse: Boolean;
begin
HttpContentResponse.ReadAs(Result);
IsJsonResponse := ResponseJArray.ReadFrom(Result);
if IsJsonResponse then
ResponseJArray.WriteTo(ResponseJson)
else
exit('');

exit(Result);
end;

local procedure CheckIfSuccessfulRequest(EDocument: Record "E-Document"; HttpResponse: HttpResponseMessage): Boolean
var
EDocumentErrorHelper: Codeunit "E-Document Error Helper";
begin
if HttpResponse.IsSuccessStatusCode then
exit(true);

if HttpResponse.IsBlockedByEnvironment then
EDocumentErrorHelper.LogSimpleErrorMessage(EDocument, EnvironmentBlocksErr)
else
EDocumentErrorHelper.LogSimpleErrorMessage(EDocument, StrSubstNo(UnsuccessfulResponseErr, HttpResponse.HttpStatusCode, HttpResponse.ReasonPhrase));
end;


[EventSubscriber(ObjectType::Codeunit, Codeunit::"Purch.-Post", 'OnAfterCheckAndUpdate', '', false, false)]
local procedure CheckOnPosting(var PurchaseHeader: Record "Purchase Header"; CommitIsSuppressed: Boolean; PreviewMode: Boolean)
var
EDocument: Record "E-Document";
EDocumentService: Record "E-Document Service";
EDocumentServiceStatus: Record "E-Document Service Status";
begin
EDocument.SetRange("Document Record ID", PurchaseHeader.RecordId);
if not EDocument.FindFirst() then
exit;

EDocumentService.SetRange("Service Integration", EDocumentService."Service Integration"::Tietoevry);
if EDocumentService.FindFirst() then;
EDocumentServiceStatus.SetRange("E-Document Entry No", EDocument."Entry No");
EDocumentServiceStatus.SetRange("E-Document Service Code", EDocumentService.Code);
if EDocumentServiceStatus.FindSet() then
repeat
EDocumentServiceStatus.TestField(EDocumentServiceStatus.Status, EDocumentServiceStatus.Status::Approved);
until EDocumentServiceStatus.Next() = 0;
end;

var
TietoevryAPIRequests: Codeunit "API Requests";
UnsuccessfulResponseErr: Label 'There was an error sending the request. Response code: %1 and error message: %2', Comment = '%1 - http response status code, e.g. 400, %2- error message';
EnvironmentBlocksErr: Label 'The request to send documents has been blocked. To resolve the problem, enable outgoing HTTP requests for the E-Document apps on the Extension Management page.';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// ------------------------------------------------------------------------------------------------
// 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.EDocumentConnector.Tietoevry;

using System.Utilities;
using Microsoft.EServices.EDocument;

codeunit 6382 "Integration Impl." implements "E-Document Integration"
{
Access = Internal;

procedure Send(var EDocument: Record "E-Document"; var TempBlob: Codeunit "Temp Blob"; var IsAsync: Boolean; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage)
var
begin
TietoevryProcessing.SendEDocument(EDocument, TempBlob, IsAsync, HttpRequest, HttpResponse);
end;

procedure SendBatch(var EDocuments: Record "E-Document"; var TempBlob: Codeunit "Temp Blob"; var IsAsync: Boolean; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage)
begin
IsAsync := false;
Error('Batch sending is not supported in this version');
end;

procedure GetResponse(var EDocument: Record "E-Document"; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage): Boolean
begin
exit(TietoevryProcessing.GetDocumentResponse(EDocument, HttpRequest, HttpResponse));
end;

procedure GetApproval(var EDocument: Record "E-Document"; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage): Boolean
begin
Error('Get Approval is not supported in this version');
end;

procedure Cancel(var EDocument: Record "E-Document"; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage): Boolean
begin
exit(TietoevryProcessing.CancelEDocument(EDocument, HttpRequest, HttpResponse));
end;

procedure ReceiveDocument(var TempBlob: Codeunit "Temp Blob"; var HttpRequest: HttpRequestMessage; var HttpResponse: HttpResponseMessage)
begin
TietoevryProcessing.ReceiveDocument(TempBlob, HttpRequest, HttpResponse);
end;

procedure GetDocumentCountInBatch(var TempBlob: Codeunit "Temp Blob"): Integer
begin
exit(TietoevryProcessing.GetDocumentCountInBatch(TempBlob));
end;

procedure GetIntegrationSetup(var SetupPage: Integer; var SetupTable: Integer)
begin
SetupPage := page::"Connection Setup Card";
SetupTable := Database::"Connection Setup";
end;

var
TietoevryProcessing: Codeunit "Processing";
}
Loading
Loading