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 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2395fb4
app checkin
Roglar01 Oct 29, 2024
e08a53c
Updated for tests
Roglar01 Oct 29, 2024
2ff1977
Tietoevry tests based on Avalara tests
Roglar01 Oct 29, 2024
974aa28
Merge branch 'microsoft:main' into main
Roglar01 Nov 13, 2024
211ab74
Updated app id
Roglar01 Nov 20, 2024
509dc9c
Merge branch 'microsoft:main' into main
Roglar01 Nov 20, 2024
53a81f6
Updated for new namespace
Roglar01 Nov 20, 2024
e214a39
Updated to new E-Doc Core
Roglar01 Nov 26, 2024
5d265de
correction after review
Roglar01 Nov 26, 2024
218a37b
Acknowledge Received
Roglar01 Nov 27, 2024
1112145
Merge branch 'microsoft:main' into main
Roglar01 Nov 28, 2024
e337674
"Uptake latest master of E-Doc Core. Remove dependency on E-Documents…
Dec 1, 2024
202399a
Merge branch 'microsoft:main' into main
Roglar01 Dec 2, 2024
f89a9f5
Syncing with version 26.0.27457.0
Roglar01 Dec 2, 2024
555c2e9
Syncing with version 26.0.27457.0
Roglar01 Dec 2, 2024
e58b5f1
uptake
Roglar01 Dec 2, 2024
1828d9c
Removed dependency to "Document Id"-field
Roglar01 Dec 2, 2024
ab0ea6f
update
Roglar01 Dec 2, 2024
95a42ed
resolved issues
Roglar01 Dec 2, 2024
4620cf6
workflow
Roglar01 Dec 2, 2024
25c524d
moved tooltips to table
Roglar01 Dec 2, 2024
9588622
Fixes
Dec 2, 2024
c55f8f4
Merge branch 'microsoft:main' into main
Roglar01 Dec 2, 2024
71a7b2d
Fix tests
Dec 2, 2024
f9a1f30
Merge branch 'main' of https://github.com/Roglar01/ALAppExtensions in…
Dec 2, 2024
9ae3e59
Merge branch 'microsoft:main' into main
Roglar01 Dec 5, 2024
8d7db5b
Merge branch 'microsoft:main' into main
Roglar01 Dec 11, 2024
456c1e5
Removed unused directives
Roglar01 Dec 11, 2024
135f4e5
Merge branch 'microsoft:main' into main
mjohans8 Dec 23, 2024
ac9597f
Fixed DocumentDownload
mjohans8 Dec 23, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemeids": "0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0147 0151 0170 0183 0184 0188 0190 0191 0192 0193 0194 0195 0196 0198 0199 0200 0201 0202 0203 0204 0205 0208 0209 0210 0211 0212 0213 0215 0216 0217 0218 0219 0220 0221 0225 0230 9901 9910 9913 9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9957 9959 AN AQ AS AU EM" }
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions Apps/W1/EDocumentConnectors/Tietoevry/app/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"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"
}
],
"internalsVisibleTo": [
{
"id": "985549ff-145a-4b5c-acd1-db6d425f6cbc",
"name": "E-Document Connector - Tietoevry Tests",
"publisher": "Microsoft"
}
],
"screenshots": [

],
"platform": "26.0.0.0",
"idRanges": [
{
"from": 6390,
"to": 6399
}
],
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": true,
"includeSourceInSymbolFile": true
},
"application": "26.0.0.0",
"target": "OnPrem",
"features": [
"TranslationFile"
],
"resourceFolders": [
".resources"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// ------------------------------------------------------------------------------------------------
// 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.Security.Authentication;
codeunit 6394 "Authenticator"
{
Access = Internal;
Permissions = tabledata "OAuth 2.0 Setup" = im,
tabledata "Connection Setup" = rim;

procedure CreateConnectionSetupRecord()
var
ConnectionSetup: Record "Connection Setup";
begin
if not ConnectionSetup.Get() then begin
Roglar01 marked this conversation as resolved.
Show resolved Hide resolved
ConnectionSetup."Authentication URL" := this.AuthURLTxt;
ConnectionSetup."API URL" := this.APIURLTxt;
ConnectionSetup."Sandbox Authentication URL" := this.SandboxAuthURLTxt;
ConnectionSetup."Sandbox API URL" := this.SandboxAPIURLTxt;
ConnectionSetup."Send Mode" := ConnectionSetup."Send Mode"::Test; //Sandbox
ConnectionSetup.Insert();
end;
end;

procedure SetClientId(var ClientIdKey: Guid; ClientID: SecretText)
begin
this.SetIsolatedStorageValue(ClientIdKey, ClientID, DataScope::Company);
end;

procedure SetClientSecret(var ClienSecretKey: Guid; ClientSecret: SecretText)
begin
this.SetIsolatedStorageValue(ClienSecretKey, ClientSecret, DataScope::Company);
end;

procedure GetAccessToken() Token: SecretText
var
ConnectionSetup: Record "Connection Setup";
Requests: Codeunit Requests;
ExpiresIn: Integer;
ClientId, ClientSecret, TokenTxt, Response : SecretText;
TokenKey: Guid;
begin
ConnectionSetup.Get();

// Reuse token if it lives longer than 1 min in future
if (ConnectionSetup."Token Expiry" > CurrentDateTime() + 60 * 1000) and (not IsNullGuid(ConnectionSetup."Token - Key")) then
if this.GetTokenValue(ConnectionSetup."Token - Key", Token, DataScope::Company) then
exit;

if not this.GetTokenValue(ConnectionSetup."Client ID - Key", ClientId, DataScope::Company) then
Error(this.TietoevryClientIdErr, ConnectionSetup.TableCaption);

if not this.GetTokenValue(ConnectionSetup."Client Secret - Key", ClientSecret, DataScope::Company) then
Error(this.TietoevryClientSecretErr, ConnectionSetup.TableCaption);

Requests.Init();
Requests.CreateAuthenticateRequest(ClientId, ClientSecret);
this.ExecuteResponse(Requests, Response);
if not this.ParseResponse(Response, TokenTxt, ExpiresIn) then
Error(this.TietoevryParseTokenErr);

// Save token for reuse
this.SetIsolatedStorageValue(TokenKey, TokenTxt, DataScope::Company);
// Read again as we want fresh record to modify
ConnectionSetup.Get();
ConnectionSetup."Token - Key" := TokenKey;
ConnectionSetup."Token Expiry" := CurrentDateTime() + ExpiresIn * 1000;
ConnectionSetup.Modify();
Commit();
exit(TokenTxt);
end;

[NonDebuggable]
local procedure ExecuteResponse(var Request: Codeunit Requests; var Response: SecretText)
var
HttpExecutor: Codeunit "Http Executor";
begin
Response := HttpExecutor.ExecuteHttpRequest(Request);
end;

[NonDebuggable]
[TryFunction]
local procedure ParseResponse(Response: SecretText; var Token: SecretText; var ExpiresIn: Integer)
var
ResponseJson: JsonObject;
TokenJson, ExpiryJson : JsonToken;
begin
ResponseJson.ReadFrom(Response.Unwrap());
ResponseJson.Get('access_token', TokenJson);
Token := TokenJson.AsValue().AsText();
ResponseJson.Get('expires_in', ExpiryJson);
ExpiresIn := ExpiryJson.AsValue().AsInteger();
end;

procedure IsClientCredsSet(var ClientId: Text; var ClientSecret: Text): Boolean
var
ConnectionSetup: Record "Connection Setup";
begin
ConnectionSetup.Get();

if this.HasToken(ConnectionSetup."Client ID - Key", DataScope::Company) then
ClientId := '*';
if this.HasToken(ConnectionSetup."Client Secret - Key", DataScope::Company) then
ClientSecret := '*';
end;

procedure SetIsolatedStorageValue(var ValueKey: Guid; Value: SecretText; TokenDataScope: DataScope)
begin
if IsNullGuid(ValueKey) then
ValueKey := CreateGuid();

IsolatedStorage.Set(ValueKey, Value, TokenDataScope);
end;

local procedure GetTokenValue(TokenKey: Text; var TokenValueAsSecret: SecretText; TokenDataScope: DataScope): Boolean
begin
if not this.HasToken(TokenKey, TokenDataScope) then
exit(false);

exit(IsolatedStorage.Get(TokenKey, TokenDataScope, TokenValueAsSecret));
end;

local procedure HasToken(TokenKey: Text; TokenDataScope: DataScope): Boolean
begin
exit(IsolatedStorage.Contains(TokenKey, TokenDataScope));
end;

var
AuthURLTxt: Label 'https://auth.infotorg.no/auth/realms/fms-realm/protocol/openid-connect', Locked = true;
APIURLTxt: Label 'https://accesspoint-api.dataplatfor.ms', Locked = true;
SandboxAuthURLTxt: Label 'https://auth-qa.infotorg.no/auth/realms/fms-realm/protocol/openid-connect', Locked = true;
SandboxAPIURLTxt: Label 'https://accesspoint-api.qa.dataplatfor.ms', Locked = true;
TietoevryClientIdErr: Label 'Tietoevry Client Id is not set in %1', Comment = '%1 - Client id';
TietoevryClientSecretErr: Label 'Tietoevry Client Secret is not set in %1', Comment = '%1 - Client secret';
TietoevryParseTokenErr: Label 'Failed to parse response for Tietoevry Access token request';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// ------------------------------------------------------------------------------------------------
// 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;

table 6392 "Connection Setup"
{
fields
{
field(1; Id; Code[10])
{
DataClassification = CustomerContent;
}
field(2; "Client Id - Key"; Guid)
{
Caption = 'Client Id';
DataClassification = EndUserIdentifiableInformation;
}
field(3; "Client Secret - Key"; Guid)
{
Caption = 'Client Secret';
DataClassification = EndUserIdentifiableInformation;
}
field(4; "Authentication URL"; Text[250])
{
Caption = 'Authentication URL';
DataClassification = CustomerContent;
Editable = false;
}
field(5; "API URL"; Text[250])
{
Caption = 'API URL';
DataClassification = CustomerContent;
Editable = false;
}
field(6; "Sandbox Authentication URL"; Text[250])
{
Caption = 'Sandbox Authentication URL';
DataClassification = CustomerContent;
Editable = false;
}
field(7; "Sandbox API URL"; Text[250])
{
Caption = 'Sandbox Authentication URL';
DataClassification = CustomerContent;
Editable = false;
}
field(8; "Token - Key"; Guid)
{
Caption = 'Token';
DataClassification = CustomerContent;
}
field(9; "Token Expiry"; DateTime)
{
Caption = 'Token Expiry';
DataClassification = CustomerContent;
}
field(10; "Company Id"; Text[250])
{
Caption = 'Company ID';
DataClassification = CustomerContent;

trigger OnValidate()
var
TietoevryProcessing: Codeunit Processing;
begin
if not TietoevryProcessing.IsValidSchemeId(Rec."Company Id") then
Rec.FieldError(Rec."Company Id");
Roglar01 marked this conversation as resolved.
Show resolved Hide resolved
end;
}
field(13; "Send Mode"; Enum "Send Mode")
{
Caption = 'Send Mode';
DataClassification = EndUserIdentifiableInformation;
}
}

keys
{
key(Key1; Id)
{
Clustered = true;
}
}

}
Loading
Loading