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

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0ba11c1
Syncing with version 25.0.21703.0 (#26811)
JesperSchulz Jul 9, 2024
096df31
[Shopify] Shopify return location on refunds (#26728)
tinestaric Jul 16, 2024
eb8dd44
[Shopify] Connector - Different shipping charges types (#26708)
aidasberesinevicius Jul 29, 2024
fd23b55
[Shopify] Add items as product variants (#26712)
tinestaric Aug 1, 2024
a1c5986
Update Yavrio in ConnectivityAppDefinitions.Codeunit.al (#26886)
jonathanwentworth Aug 6, 2024
47455bf
Syncing with version 25.0.22639.0 (#26958)
aholstrup1 Aug 7, 2024
785f277
Syncing with version 25.0.22684.0 (#26959)
aholstrup1 Aug 7, 2024
4f72cc9
[Fix] URL maximum length in E-Document Integration (#26730)
pluethi Aug 14, 2024
544e6de
Update InstallSECore.codeunit.al (#26883)
hannib84 Aug 14, 2024
e9be9d9
Update CODEOWNERS with EDocument reviewers (#27067)
aholstrup1 Aug 15, 2024
1690178
GP Updates - July 2024 (#26821)
jaymckinney-enavate Aug 16, 2024
33ead2e
[Shopify][BC Idea]: Enhancing Shopify Connector for Accurate Price Sy…
VijayErpEff Aug 19, 2024
650ec01
[Shopify] Add Translations Export to Products and Variants (#26216)
tinestaric Aug 19, 2024
87b9cba
[Shopify] Add Metafields to Products and Variants (#26185)
tinestaric Aug 20, 2024
2a768e4
Syncing with version 25.0.23141.0 (#27112)
aholstrup1 Aug 22, 2024
7c3fe3e
[Shopify] Connector - Export Posted Sales Invoices to Shopify as Orde…
GediminasGaubys Aug 23, 2024
94f2e55
GP - Update migrations with 1099 data to use the new IRS Forms app. (…
jaymckinney-enavate Aug 26, 2024
d4bfcfc
Tietoevry EDoc-connector
Roglar01 Sep 10, 2024
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions Apps/W1/EDocumentsTietoevryConnector/app/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"id": "d852a468-263e-49e5-bfda-f09e33342b89",
"name": "E-Documents Connector with External Endpoints",
"publisher": "Microsoft",
"brief": "This app extends Microsoft standard E-documents framework, offering connectors to 3rd party access-points providers.",
"description": "This app extends Microsoft standard E-documents framework, offering connectors to 3rd party access-points providers.",
"version": "25.0.0.0",
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2009120",
"help": " https://learn.microsoft.com/en-us/dynamics365/business-central/finance-edocuments-overview",
"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": "25.0.0.0"
}
],
"screenshots": [

],
"platform": "25.0.0.0",
"idRanges": [
{
"from": 6360,
"to": 6369
}
],
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": true,
"includeSourceInSymbolFile": true
},
"application": "25.0.0.0",
"target": "OnPrem"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// ------------------------------------------------------------------------------------------------
// 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;

permissionset 96361 "TE EDocConn. - Edit"
{
Access = Public;
Assignable = true;
IncludedPermissionSets = "TE EDocConn. - Read";

Permissions = tabledata "Tietoevry Connection Setup" = IM;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// ------------------------------------------------------------------------------------------------
// 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;

permissionset 96362 "TE EDocConn. - Read"
{
Access = Public;
Assignable = true;
IncludedPermissionSets = "TE EDoc. Conn. Objects";

Permissions = tabledata "Tietoevry Connection Setup" = R;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// ------------------------------------------------------------------------------------------------
// 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;

permissionset 96363 "TE EDoc. Conn. Objects"
{
Access = Public;
Assignable = false;

Permissions = table "Tietoevry Connection Setup" = X,
page "Tietoevry Conn. Setup Card" = X,
codeunit "Tietoevry API Requests" = X,
codeunit "Tietoevry Auth." = X,
codeunit "Tietoevry Connection" = X,
codeunit "Tietoevry Integration Impl." = X,
codeunit "Tietoevry Processing" = X;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// ------------------------------------------------------------------------------------------------
// 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;

using System.Security.AccessControl;

permissionsetextension 96361 "D365 Basic - EDocument Connector" extends "D365 BASIC"
{
IncludedPermissionSets = "TE EDocConn. - Edit";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Inventory.Intrastat;

using System.Security.AccessControl;
using Microsoft.EServices.EDocumentConnector;

permissionsetextension 96362 "D365 Read - EDocument Connector" extends "D365 READ"
{
IncludedPermissionSets = "TE EDocConn. - Edit";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
namespace TietoevryConnector.TietoevryConnector;

using Microsoft.Sales.Peppol;
using Microsoft.Sales.Document;
using Microsoft.Foundation.Company;
using Microsoft.Sales.Customer;
using Microsoft.EServices.EDocumentConnector;
using Microsoft.eServices.EDocument;
using System.Utilities;

codeunit 96360 "Tietoevry 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 "Tietoevry Connection Setup";
begin
if not ExternalConnectionSetup.Get() then
Error(MissingSetupErr);
IsHandled := true;
if CompanyInformation."VAT Registration No." = '' then
Error(MissingCompInfVATRegNoErr, CompanyInformation.TableCaption());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't those two event subscribers for the PEPPOL Validation be bind manually only for this connector?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You tell me, your Pagero-implementation is not bind manually.. code is based on your Pagero connector..

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you propose the e-document framework should handle this?

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)
begin
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 Customer."Service Participant Id" = '' then
Error(MissingCustInfoErr, Customer.FieldCaption("Service Participant Id"), 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
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 begin
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;
end;

var
TietoevryConnection: Codeunit "Tietoevry Connection";
TietoevryProcessing: Codeunit "Tietoevry Processing";
EDocumentLogHelper: Codeunit "E-Document Log Helper";
EDocumentErrorHelper: Codeunit "E-Document Error Helper";

MissingSetupErr: Label 'You must set up service integration in the E-Document service card.';
#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;

using Microsoft.EServices.EDocument;
using System.Utilities;
using System.Text;
using Microsoft.Purchases.Posting;
using Microsoft.Purchases.Document;
codeunit 96361 "Tietoevry 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 "Tietoevry 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.';
}
Loading
Loading