From 56cfcf8a660f3049d5d6c29c6724b796557e3d3f Mon Sep 17 00:00:00 2001 From: Bert Verbeek Date: Mon, 7 Oct 2024 14:25:52 +0200 Subject: [PATCH] Fix errors and warning (#180) --- businessCentral/app/.vscode/settings.json | 11 ++- .../app/permissions/Api.PermissionSet.al | 24 ++++++ .../app/permissions/Execute.PermissionSet.al | 17 +++- .../app/permissions/Setup.PermissionSet.al | 17 +++- .../app/src/BC2ADLSExport.xmlport.al | 2 + .../app/src/BC2ADLSImport.xmlport.al | 2 + businessCentral/app/src/CDMFormat.Enum.al | 2 + businessCentral/app/src/CDMUtil.Codeunit.al | 6 +- .../app/src/ClearTrackedDeletions.Codeunit.al | 4 +- .../app/src/Communication.Codeunit.al | 8 +- .../app/src/Credentials.Codeunit.al | 6 +- .../app/src/CurrentSession.Table.al | 14 +++- .../app/src/CurrentSessionAPI.Page.al | 6 ++ .../app/src/DeletedRecord.Table.al | 3 + .../app/src/EnumTranslation.Table.al | 22 +++-- .../app/src/EnumTranslationLang.Table.al | 14 +++- .../app/src/EnumTranslations.Page.al | 7 +- .../app/src/EnumTranslationsLang.Page.al | 5 +- businessCentral/app/src/Execute.Codeunit.al | 19 +++-- businessCentral/app/src/Execution.Codeunit.al | 15 ++-- .../app/src/ExternalEvents.Codeunit.al | 4 +- businessCentral/app/src/Field.Table.al | 11 ++- businessCentral/app/src/FieldAPI.Page.al | 6 ++ businessCentral/app/src/Gen2Util.Codeunit.al | 4 +- businessCentral/app/src/Http.Codeunit.al | 12 +-- businessCentral/app/src/HttpMethod.Enum.al | 2 + businessCentral/app/src/Installer.Codeunit.al | 4 +- businessCentral/app/src/Run.Page.al | 30 ++----- businessCentral/app/src/Run.Table.al | 35 ++++++-- businessCentral/app/src/RunAPI.Page.al | 7 ++ businessCentral/app/src/RunState.Enum.al | 2 + .../app/src/SessionManager.Codeunit.al | 7 +- businessCentral/app/src/Setup.Codeunit.al | 3 + businessCentral/app/src/Setup.Page.al | 84 ++++++------------- businessCentral/app/src/Setup.Table.al | 23 +++++ businessCentral/app/src/SetupAPI.Page.al | 2 + businessCentral/app/src/SetupAPIv11.Page.al | 6 ++ businessCentral/app/src/SetupFields.Page.al | 26 ++---- businessCentral/app/src/SetupTables.Page.al | 25 +++--- businessCentral/app/src/StorageType.Enum.al | 12 ++- businessCentral/app/src/Table.Table.al | 31 +++++-- businessCentral/app/src/TableAPI.Page.al | 10 ++- .../app/src/TableLastTimestamp.Table.al | 8 +- businessCentral/app/src/Upgrade.Codeunit.al | 6 +- .../src/UpgradeTagNewCompanySubs.Codeunit.al | 4 +- businessCentral/app/src/Util.Codeunit.al | 14 ++-- 46 files changed, 378 insertions(+), 204 deletions(-) create mode 100644 businessCentral/app/permissions/Api.PermissionSet.al diff --git a/businessCentral/app/.vscode/settings.json b/businessCentral/app/.vscode/settings.json index 517665a..1d48db3 100644 --- a/businessCentral/app/.vscode/settings.json +++ b/businessCentral/app/.vscode/settings.json @@ -4,11 +4,18 @@ "${CodeCop}", "${UICop}", "${PerTenantExtensionCop}", - "${analyzerfolder}BusinessCentral.LinterCop.dll" + "${analyzerFolder}BusinessCentral.LinterCop.dll" ], "al.ruleSetPath": "./.vscode/custom.ruleset.json", "CRS.FileNamePattern": "..al", "CRS.FileNamePatternExtensions": "..al", "CRS.FileNamePatternPageCustomizations": "..al", - "CRS.RemovePrefixFromFilename": true + "CRS.RemovePrefixFromFilename": true, + "linterCop.repositories": [ + { + "url": "https://github.com/StefanMaron/BusinessCentral.LinterCop", + "shortName": "BcLntr", + "fileName": "BusinessCentral.LinterCop.dll" + } + ] } \ No newline at end of file diff --git a/businessCentral/app/permissions/Api.PermissionSet.al b/businessCentral/app/permissions/Api.PermissionSet.al new file mode 100644 index 0000000..ed95c2d --- /dev/null +++ b/businessCentral/app/permissions/Api.PermissionSet.al @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. See LICENSE in the project root for license information. +permissionset 82563 "ADLSE - API" +{ + /// + /// The permission set to be used when using the API. + /// + Access = Public; + Assignable = true; + Caption = 'ADLS - Api', MaxLength = 30; + + Permissions = tabledata "ADLSE Table" = RMI, + tabledata "ADLSE Setup" = R, + tabledata "ADLSE Current Session" = R, + tabledata "ADLSE Run" = R, + tabledata "ADLSE Field" = RI, + page "ADLSE Table API" = X, + page "ADLSE Setup API v11" = X, + page "ADLSE CurrentSession API" = X, + page "ADLSE Run API" = X, + page "ADLSE Field API" = X, + codeunit "ADLSE External Events Helper" = X, + codeunit "ADLSE External Events" = X; +} \ No newline at end of file diff --git a/businessCentral/app/permissions/Execute.PermissionSet.al b/businessCentral/app/permissions/Execute.PermissionSet.al index 2a760a1..973a0ee 100644 --- a/businessCentral/app/permissions/Execute.PermissionSet.al +++ b/businessCentral/app/permissions/Execute.PermissionSet.al @@ -7,7 +7,7 @@ permissionset 82561 "ADLSE - Execute" /// Access = Public; Assignable = true; - Caption = 'Azure Data Lake Storage - Execute'; + Caption = 'ADLS - Execute', MaxLength = 30; Permissions = tabledata "ADLSE Setup" = RM, tabledata "ADLSE Table" = RM, @@ -17,5 +17,18 @@ permissionset 82561 "ADLSE - Execute" tabledata "ADLSE Table Last Timestamp" = RIMD, tabledata "ADLSE Run" = RIMD, tabledata "ADLSE Enum Translation" = RIMD, - tabledata "ADLSE Enum Translation Lang" = RIMD; + tabledata "ADLSE Enum Translation Lang" = RIMD, + codeunit "ADLSE UpgradeTagNewCompanySubs" = X, + codeunit "ADLSE Upgrade" = X, + codeunit "ADLSE Util" = X, + codeunit ADLSE = X, + codeunit "ADLSE CDM Util" = X, + codeunit "ADLSE Communication" = X, + codeunit "ADLSE Session Manager" = X, + codeunit "ADLSE Http" = X, + codeunit "ADLSE Gen 2 Util" = X, + codeunit "ADLSE Execute" = X, + codeunit "ADLSE Execution" = X, + report "ADLSE Seek Data" = X, + xmlport "BC2ADLS Export" = X; } \ No newline at end of file diff --git a/businessCentral/app/permissions/Setup.PermissionSet.al b/businessCentral/app/permissions/Setup.PermissionSet.al index a7d64f4..a0848bf 100644 --- a/businessCentral/app/permissions/Setup.PermissionSet.al +++ b/businessCentral/app/permissions/Setup.PermissionSet.al @@ -7,7 +7,7 @@ permissionset 82560 "ADLSE - Setup" /// Access = Public; Assignable = true; - Caption = 'Azure Data Lake Storage - Setup'; + Caption = 'ADLS - Setup', MaxLength = 30; Permissions = tabledata "ADLSE Setup" = RIMD, tabledata "ADLSE Table" = RIMD, @@ -15,5 +15,18 @@ permissionset 82560 "ADLSE - Setup" tabledata "ADLSE Deleted Record" = RD, tabledata "ADLSE Current Session" = R, tabledata "ADLSE Table Last Timestamp" = RID, - tabledata "ADLSE Run" = RD; + tabledata "ADLSE Run" = RD, + tabledata "ADLSE Enum Translation" = RIMD, + tabledata "ADLSE Enum Translation Lang" = RIMD, + codeunit "ADLSE Clear Tracked Deletions" = X, + codeunit "ADLSE Credentials" = X, + codeunit "ADLSE Setup" = X, + codeunit "ADLSE Installer" = X, + page "ADLSE Setup Tables" = X, + page "ADLSE Setup Fields" = X, + page "ADLSE Setup" = X, + page "ADLSE Run" = X, + page "ADLSE Enum Translations" = X, + page "ADLSE Enum Translations Lang" = X, + xmlport "BC2ADLS Import" = X; } \ No newline at end of file diff --git a/businessCentral/app/src/BC2ADLSExport.xmlport.al b/businessCentral/app/src/BC2ADLSExport.xmlport.al index f0af0bb..f1d458b 100644 --- a/businessCentral/app/src/BC2ADLSExport.xmlport.al +++ b/businessCentral/app/src/BC2ADLSExport.xmlport.al @@ -3,6 +3,8 @@ xmlport 82561 "BC2ADLS Export" Caption = 'BC2ADLS Export'; UseRequestPage = false; Direction = Export; + Permissions = tabledata "ADLSE Field" = r, + tabledata "ADLSE Table" = r; schema { diff --git a/businessCentral/app/src/BC2ADLSImport.xmlport.al b/businessCentral/app/src/BC2ADLSImport.xmlport.al index 9207dd3..6092fb3 100644 --- a/businessCentral/app/src/BC2ADLSImport.xmlport.al +++ b/businessCentral/app/src/BC2ADLSImport.xmlport.al @@ -3,6 +3,8 @@ xmlport 82560 "BC2ADLS Import" Caption = 'BC2ADLS Import'; UseRequestPage = false; Direction = Import; + Permissions = tabledata "ADLSE Field" = rmi, + tabledata "ADLSE Table" = rmid; schema { diff --git a/businessCentral/app/src/CDMFormat.Enum.al b/businessCentral/app/src/CDMFormat.Enum.al index 3457da8..0dd7c5e 100644 --- a/businessCentral/app/src/CDMFormat.Enum.al +++ b/businessCentral/app/src/CDMFormat.Enum.al @@ -9,10 +9,12 @@ enum 82562 "ADLSE CDM Format" Access = Internal; Extensible = false; +#pragma warning disable LC0045 value(0; Csv) { Caption = 'CSV'; } +#pragma warning restore LC0045 value(1; Parquet) { diff --git a/businessCentral/app/src/CDMUtil.Codeunit.al b/businessCentral/app/src/CDMUtil.Codeunit.al index edf80a8..eeadbce 100644 --- a/businessCentral/app/src/CDMUtil.Codeunit.al +++ b/businessCentral/app/src/CDMUtil.Codeunit.al @@ -12,7 +12,7 @@ codeunit 82566 "ADLSE CDM Util" // Refer Common Data Model https://docs.microsof FieldDataTypeCannotBeChangedErr: Label 'The data type for the field %1 in the entity %2 cannot be changed.', Comment = '%1: field name, %2: entity name'; RepresentsTableTxt: Label 'Represents the table %1', Comment = '%1: table caption'; ManifestNameTxt: Label '%1-manifest', Comment = '%1: name of manifest'; - EntityPathTok: Label '%1.cdm.json/%1', Comment = '%1: Entity'; + EntityPathTok: Label '%1.cdm.json/%1', Comment = '%1: Entity', Locked = true; UnequalAttributeCountErr: Label 'Unequal number of attributes'; MismatchedValueInAttributeErr: Label 'The attribute value for %1 at index %2 is different. First: %3, Second: %4', Comment = '%1 = field, %2 = index, %3 = value of the first, %4 = value of the second'; @@ -111,7 +111,7 @@ codeunit 82566 "ADLSE CDM Util" // Refer Common Data Model https://docs.microsof Token.Add(NameValue); end; - local procedure CreateAttributes(TableID: Integer; FieldIdList: List of [Integer]) Result: JsonArray; + local procedure CreateAttributes(TableID: Integer; FieldIdList: List of [Integer]) Result: JsonArray var ADLSESetup: Record "ADLSE Setup"; ADLSEUtil: Codeunit "ADLSE Util"; @@ -174,7 +174,7 @@ codeunit 82566 "ADLSE CDM Util" // Refer Common Data Model https://docs.microsof FieldTable: Record Field; begin if FieldTable.Get(TableId, FieldId) then - exit(fieldTable.IsPartOfPrimaryKey); + exit(FieldTable.IsPartOfPrimaryKey); end; local procedure CreateAttributeJson(Name: Text; DataFormat: Text; DisplayName: Text; AppliedTraits: JsonArray; MaximumLength: Integer; IsPrimaryKeyFieldParameter: Boolean) Attribute: JsonObject diff --git a/businessCentral/app/src/ClearTrackedDeletions.Codeunit.al b/businessCentral/app/src/ClearTrackedDeletions.Codeunit.al index a36d3ba..9acc458 100644 --- a/businessCentral/app/src/ClearTrackedDeletions.Codeunit.al +++ b/businessCentral/app/src/ClearTrackedDeletions.Codeunit.al @@ -17,6 +17,8 @@ codeunit 82573 "ADLSE Clear Tracked Deletions" var TrackedDeletedRecordsRemovedMsg: Label 'Representations of deleted records that have been exported previously have been deleted.'; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'r')] + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Deleted Record", 'rd')] local procedure ClearTrackedDeletedRecords() var ADLSETable: Record "ADLSE Table"; @@ -29,7 +31,7 @@ codeunit 82573 "ADLSE Clear Tracked Deletions" ADLSEDeletedRecord.SetRange("Table ID", ADLSETable."Table ID"); ADLSEDeletedRecord.SetFilter("Entry No.", '<=%1', ADLSETableLastTimestamp.GetDeletedLastEntryNo(ADLSETable."Table ID")); if not ADLSEDeletedRecord.IsEmpty() then - ADLSEDeletedRecord.DeleteAll(); + ADLSEDeletedRecord.DeleteAll(false); ADLSETableLastTimestamp.SaveDeletedLastEntryNo(ADLSETable."Table ID", 0); until ADLSETable.Next() = 0; diff --git a/businessCentral/app/src/Communication.Codeunit.al b/businessCentral/app/src/Communication.Codeunit.al index 1d25282..8a3f527 100644 --- a/businessCentral/app/src/Communication.Codeunit.al +++ b/businessCentral/app/src/Communication.Codeunit.al @@ -27,13 +27,13 @@ codeunit 82562 "ADLSE Communication" CorpusJsonPathTxt: Label '/%1', Comment = '%1 = name of the blob', Locked = true; CannotAddedMoreBlocksErr: Label 'The number of blocks that can be added to the blob has reached its maximum limit.'; SingleRecordTooLargeErr: Label 'A single record payload exceeded the max payload size. Please adjust the payload size or reduce the fields to be exported for the record.'; - DeltasFileCsvTok: Label '/deltas/%1/%2.csv', Comment = '%1: Entity, %2: File identifier guid'; + DeltasFileCsvTok: Label '/deltas/%1/%2.csv', Comment = '%1: Entity, %2: File identifier guid', Locked = true; ExportOfSchemaNotPerformendTxt: Label 'Please export the schema first before trying to export the data.'; EntitySchemaChangedErr: Label 'The schema of the table %1 has changed. %2', Comment = '%1 = Entity name, %2 = NotAllowedOnSimultaneousExportTxt'; CdmSchemaChangedErr: Label 'There may have been a change in the tables to export. %1', Comment = '%1 = NotAllowedOnSimultaneousExportTxt'; MSFabricUrlTxt: Label 'https://onelake.dfs.fabric.microsoft.com/%1/%2.Lakehouse/Files', Locked = true, Comment = '%1: Workspace name, %2: Lakehouse Name'; MSFabricUrlGuidTxt: Label 'https://onelake.dfs.fabric.microsoft.com/%1/%2/Files', Locked = true, Comment = '%1: Workspace name, %2: Lakehouse Name'; - ResetTableExportTxt: Label '/reset/%1.txt', Locked = true, comment = '%1 = Table name'; + ResetTableExportTxt: Label '/reset/%1.txt', Locked = true, Comment = '%1 = Table name'; procedure SetupBlobStorage() var @@ -224,7 +224,7 @@ codeunit 82562 "ADLSE Communication" LastTimestampExported := LastFlushedTimeStamp; Payload.Append(RecordPayLoad); - LastRecordOnPayloadTimeStamp := RecordTimestamp; + LastRecordOnPayloadTimeStamp := RecordTimeStamp; end; [TryFunction] @@ -327,7 +327,7 @@ codeunit 82562 "ADLSE Communication" if ManifestJsonsNeedsUpdate then begin // Expected that multiple sessions that export data from different tables will be competing for writing to // manifest. Semaphore applied. - ADLSESetup.LockTable(true); + ADLSESetup.ReadIsolation := IsolationLevel::UpdLock; ADLSESetup.GetSingleton(); UpdateManifest(GetBaseUrl() + StrSubstNo(CorpusJsonPathTxt, DataCdmManifestNameTxt), 'data', ADLSESetup.DataFormat); diff --git a/businessCentral/app/src/Credentials.Codeunit.al b/businessCentral/app/src/Credentials.Codeunit.al index d892ebc..cc2d221 100644 --- a/businessCentral/app/src/Credentials.Codeunit.al +++ b/businessCentral/app/src/Credentials.Codeunit.al @@ -73,7 +73,7 @@ codeunit 82565 "ADLSE Credentials" [NonDebuggable] procedure IsClientIDSet(): Boolean begin - exit(GetClientId() <> ''); + exit(GetClientID() <> ''); end; [NonDebuggable] @@ -100,17 +100,21 @@ codeunit 82565 "ADLSE Credentials" begin if not IsolatedStorage.Contains(KeyName, IsolatedStorageDataScope()) then exit(''); +#pragma warning disable LC0043 IsolatedStorage.Get(KeyName, IsolatedStorageDataScope(), Secret); +#pragma warning restore LC0043 end; [NonDebuggable] local procedure SetSecret(KeyName: Text; Secret: Text) begin +#pragma warning disable LC0043 if EncryptionEnabled() then begin IsolatedStorage.SetEncrypted(KeyName, Secret, IsolatedStorageDataScope()); exit; end; IsolatedStorage.Set(KeyName, Secret, IsolatedStorageDataScope()); +#pragma warning restore LC0043 end; [NonDebuggable] diff --git a/businessCentral/app/src/CurrentSession.Table.al b/businessCentral/app/src/CurrentSession.Table.al index 1d06e31..45c7b29 100644 --- a/businessCentral/app/src/CurrentSession.Table.al +++ b/businessCentral/app/src/CurrentSession.Table.al @@ -1,8 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma warning disable LC0015 table 82565 "ADLSE Current Session" +#pragma warning restore { Access = Internal; + Caption = 'ADLSE Current Session'; DataClassification = SystemMetadata; DataPerCompany = false; @@ -48,6 +51,7 @@ table 82565 "ADLSE Current Session" InsertFailedErr: Label 'Could not start the export as there is already an active export running for the table %1. If this is not so, please stop all exports and try again.', Comment = '%1 = table caption'; CouldNotStopSessionErr: Label 'Could not delete the export table session %1 for table on company %2.', Comment = '%1: session id, %2: company name'; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Current Session", 'i')] procedure Start(ADLSETableID: Integer) var ADLSEUtil: Codeunit "ADLSE Util"; @@ -57,10 +61,11 @@ table 82565 "ADLSE Current Session" Rec."Session ID" := SessionId(); Rec."Session Unique ID" := GetActiveSessionIDForSession(SessionId()); Rec."Company Name" := CopyStr(CompanyName(), 1, 30); - if not Rec.Insert() then + if not Rec.Insert(true) then Error(InsertFailedErr, ADLSEUtil.GetTableCaption(ADLSETableID)); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Current Session", 'rd')] procedure Stop(ADLSETableID: Integer; EmitTelemetry: Boolean; TableCaption: Text) var ADLSEExecution: Codeunit "ADLSE Execution"; @@ -69,7 +74,7 @@ table 82565 "ADLSE Current Session" if not Rec.Get(ADLSETableID, CompanyName()) then exit; CustomDimensions.Add('Entity', TableCaption); - if not Rec.Delete() then + if not Rec.Delete(true) then ADLSEExecution.Log('ADLSE-036', StrSubstNo(CouldNotStopSessionErr, Rec."Session ID", CompanyName()), Verbosity::Error, CustomDimensions) else ADLSEExecution.Log('ADLSE-039', 'Session ended and was removed', Verbosity::Normal, CustomDimensions); @@ -81,6 +86,7 @@ table 82565 "ADLSE Current Session" Error(ExportDataInProgressErr); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Current Session", 'r')] procedure AreAnySessionsActive() AnyActive: Boolean begin Rec.SetRange("Company Name", CopyStr(CompanyName(), 1, 30)); @@ -93,12 +99,14 @@ table 82565 "ADLSE Current Session" until Rec.Next() = 0; end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Current Session", 'd')] procedure CleanupSessions() begin Rec.SetRange("Company Name", CopyStr(CompanyName(), 1, 30)); Rec.DeleteAll(false); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Current Session", 'rd')] procedure CancelAll() var ADLSEUtil: Codeunit "ADLSE Util"; @@ -109,7 +117,7 @@ table 82565 "ADLSE Current Session" Session.StopSession(Rec."Session ID", StrSubstNo(SessionTerminatedMsg, ADLSEUtil.GetTableCaption(Rec."Table ID"))); until Rec.Next() = 0; - Rec.DeleteAll(); + Rec.DeleteAll(false); end; local procedure IsSessionActive(): Boolean diff --git a/businessCentral/app/src/CurrentSessionAPI.Page.al b/businessCentral/app/src/CurrentSessionAPI.Page.al index 35b6732..ebe09e8 100644 --- a/businessCentral/app/src/CurrentSessionAPI.Page.al +++ b/businessCentral/app/src/CurrentSessionAPI.Page.al @@ -28,10 +28,16 @@ page 82571 "ADLSE CurrentSession API" { Editable = false; } +#pragma warning disable LC0016 field(systemRowVersion; Rec.SystemRowVersion) { Editable = false; } +#pragma warning restore + field(lastModifiedDateTime; Rec.SystemModifiedAt) + { + Editable = false; + } } } } diff --git a/businessCentral/app/src/DeletedRecord.Table.al b/businessCentral/app/src/DeletedRecord.Table.al index 6094ab2..97f3189 100644 --- a/businessCentral/app/src/DeletedRecord.Table.al +++ b/businessCentral/app/src/DeletedRecord.Table.al @@ -1,8 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma warning disable LC0015 table 82563 "ADLSE Deleted Record" +#pragma warning restore { Access = Internal; + Caption = 'ADLSE Deleted Record'; DataClassification = SystemMetadata; fields diff --git a/businessCentral/app/src/EnumTranslation.Table.al b/businessCentral/app/src/EnumTranslation.Table.al index a461c09..bafb847 100644 --- a/businessCentral/app/src/EnumTranslation.Table.al +++ b/businessCentral/app/src/EnumTranslation.Table.al @@ -1,13 +1,18 @@ +#pragma warning disable LC0015 table 82567 "ADLSE Enum Translation" +#pragma warning restore { DataClassification = ToBeClassified; Caption = 'ADLSE Enum Translation'; Access = Internal; + LookupPageId = "ADLSE Enum Translations"; + DrillDownPageId = "ADLSE Enum Translations"; fields { field(1; "Table Id"; Integer) { + AllowInCustomizations = Always; DataClassification = SystemMetadata; Caption = 'Table Id'; } @@ -15,9 +20,11 @@ table 82567 "ADLSE Enum Translation" { DataClassification = SystemMetadata; Caption = 'Compliant Table Name'; + ToolTip = 'Specifies the Compliant table Name of the table that is compliant with Data Lake standards.'; } field(3; "Field Id"; Integer) { + AllowInCustomizations = Always; DataClassification = SystemMetadata; Caption = 'Field Id'; } @@ -25,6 +32,7 @@ table 82567 "ADLSE Enum Translation" { DataClassification = SystemMetadata; Caption = 'Compliant Object Name'; + ToolTip = 'Specifies the compliant field name of the field that is compliant with Data Lake standards.'; } } @@ -36,6 +44,7 @@ table 82567 "ADLSE Enum Translation" } } + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Enum Translation", 'i')] local procedure InsertEnum(TableId: Integer; FieldNo: Integer; FieldName: Text[30]) var ADLSEUtil: Codeunit "ADLSE Util"; @@ -45,9 +54,12 @@ table 82567 "ADLSE Enum Translation" Rec."Compliant Table Name" := CopyStr(ADLSEUtil.GetDataLakeCompliantTableName(TableId), 1, MaxStrLen((Rec."Compliant Table Name"))); Rec."Field Id" := FieldNo; Rec."Compliant Field Name" := CopyStr(ADLSEUtil.GetDataLakeCompliantFieldName(FieldName, FieldNo), 1, MaxStrLen((Rec."Compliant Field Name"))); - Rec.Insert(); + Rec.Insert(true); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE table", 'r')] + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Enum Translation", 'd')] + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Enum Translation Lang", 'd')] procedure RefreshOptions() var ADLSETable: Record "ADLSE Table"; @@ -58,8 +70,8 @@ table 82567 "ADLSE Enum Translation" ADLSEExternalEvents: Codeunit "ADLSE External Events"; ADLSERecordRef: RecordRef; begin - ADLSEEnumTranslation.DeleteAll(); - ADLSEEnumTranslationLang.DeleteAll(); + ADLSEEnumTranslation.DeleteAll(false); + ADLSEEnumTranslationLang.DeleteAll(false); if ADLSETable.FindSet() then repeat @@ -104,8 +116,8 @@ table 82567 "ADLSE Enum Translation" Translations := ADLSESetup.Translations.Split(';'); Translations.Remove(''); for x := 1 to Translations.Count() do begin - TranslationHelper.SetGlobalLanguageByCode(Translations.Get(x)); - ADLSEEnumTranslationLang.InsertEnumLanguage(Translations.Get(x), FieldRec.TableNo, FieldRec."No.", FieldRec.FieldName, FieldRef.GetEnumValueOrdinal(i), FieldRef.GetEnumValueCaption(i)); + TranslationHelper.SetGlobalLanguageByCode(CopyStr(Translations.Get(x), 1, 10)); + ADLSEEnumTranslationLang.InsertEnumLanguage(CopyStr(Translations.Get(x), 1, 10), FieldRec.TableNo, FieldRec."No.", FieldRec.FieldName, FieldRef.GetEnumValueOrdinal(i), FieldRef.GetEnumValueCaption(i)); end; end; TranslationHelper.RestoreGlobalLanguage(); diff --git a/businessCentral/app/src/EnumTranslationLang.Table.al b/businessCentral/app/src/EnumTranslationLang.Table.al index 2113662..296cdbf 100644 --- a/businessCentral/app/src/EnumTranslationLang.Table.al +++ b/businessCentral/app/src/EnumTranslationLang.Table.al @@ -1,8 +1,12 @@ +#pragma warning disable LC0015 table 82568 "ADLSE Enum Translation Lang" +#pragma warning restore { DataClassification = ToBeClassified; Caption = 'ADLSE Enum Translation Language'; Access = Internal; + LookupPageId = "ADLSE Enum Translations Lang"; + DrillDownPageId = "ADLSE Enum Translations Lang"; fields { @@ -10,9 +14,11 @@ table 82568 "ADLSE Enum Translation Lang" { DataClassification = SystemMetadata; Caption = 'Language Code'; + ToolTip = 'Specifies the language code.'; } field(2; "Table Id"; Integer) { + AllowInCustomizations = Always; DataClassification = SystemMetadata; Caption = 'Table Id'; } @@ -20,9 +26,11 @@ table 82568 "ADLSE Enum Translation Lang" { DataClassification = SystemMetadata; Caption = 'Compliant Table Name'; + ToolTip = 'Specifies the compliant table name of the table that is compliant with Data Lake standards.'; } field(4; "Field Id"; Integer) { + AllowInCustomizations = Always; DataClassification = SystemMetadata; Caption = 'Field Id'; } @@ -30,9 +38,11 @@ table 82568 "ADLSE Enum Translation Lang" { DataClassification = SystemMetadata; Caption = 'Compliant Object Name'; + ToolTip = 'Specifies the compliant field name of the field that is compliant with Data Lake standards.'; } field(6; "Enum Value Id"; Integer) { + AllowInCustomizations = Always; DataClassification = SystemMetadata; Caption = 'Enum Index'; } @@ -40,6 +50,7 @@ table 82568 "ADLSE Enum Translation Lang" { DataClassification = SystemMetadata; Caption = 'Enum Caption'; + ToolTip = 'Specifies the caption of the enum value.'; } } @@ -51,6 +62,7 @@ table 82568 "ADLSE Enum Translation Lang" } } + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Enum Translation Lang", 'i')] procedure InsertEnumLanguage(LanguageCode: Code[10]; TableId: Integer; FieldNo: Integer; FieldName: Text[30]; EnumValueOrdinal: Integer; EnumValueName: Text) var ADLSEUtil: Codeunit "ADLSE Util"; @@ -63,6 +75,6 @@ table 82568 "ADLSE Enum Translation Lang" Rec."Compliant Field Name" := CopyStr(ADLSEUtil.GetDataLakeCompliantFieldName(FieldName, FieldNo), 1, MaxStrLen((Rec."Compliant Field Name"))); Rec."Enum Value Id" := EnumValueOrdinal; Rec."Enum Value Caption" := CopyStr(EnumValueName, 1, MaxStrLen(Rec."Enum Value Caption")); - Rec.Insert(); + Rec.Insert(true); end; } \ No newline at end of file diff --git a/businessCentral/app/src/EnumTranslations.Page.al b/businessCentral/app/src/EnumTranslations.Page.al index ded6ec7..2cb4b12 100644 --- a/businessCentral/app/src/EnumTranslations.Page.al +++ b/businessCentral/app/src/EnumTranslations.Page.al @@ -3,6 +3,7 @@ page 82569 "ADLSE Enum Translations" { PageType = List; ApplicationArea = All; + Caption = 'ADLSE Enum Translations'; UsageCategory = Lists; SourceTable = "ADLSE Enum Translation"; @@ -16,12 +17,10 @@ page 82569 "ADLSE Enum Translations" field(CompliantTableName; Rec."Compliant Table Name") { Editable = false; - ToolTip = 'The name of the table that is compliant with Data Lake standards.'; } field(CompliantFieldName; Rec."Compliant Field Name") { Editable = false; - ToolTip = 'The name of the field that is compliant with Data Lake standards.'; } } } @@ -38,7 +37,7 @@ page 82569 "ADLSE Enum Translations" ToolTip = 'Refresh the options of the enum fields.'; Image = Refresh; - trigger OnAction(); + trigger OnAction() begin Rec.RefreshOptions(); end; @@ -53,7 +52,7 @@ page 82569 "ADLSE Enum Translations" ToolTip = 'View the translations of the enum fields.'; Image = Language; - trigger OnAction(); + trigger OnAction() var ADLSEEnumTranslationLang: Record "ADLSE Enum Translation Lang"; ADLSEEnumTranslationsLang: Page "ADLSE Enum Translations Lang"; diff --git a/businessCentral/app/src/EnumTranslationsLang.Page.al b/businessCentral/app/src/EnumTranslationsLang.Page.al index 65fb240..dbf138a 100644 --- a/businessCentral/app/src/EnumTranslationsLang.Page.al +++ b/businessCentral/app/src/EnumTranslationsLang.Page.al @@ -3,6 +3,7 @@ page 82570 "ADLSE Enum Translations Lang" { PageType = List; ApplicationArea = All; + Caption = 'Enum Translations Language'; UsageCategory = Lists; SourceTable = "ADLSE Enum Translation Lang"; @@ -16,22 +17,18 @@ page 82570 "ADLSE Enum Translations Lang" field(LanguageCode; Rec."Language Code") { Editable = false; - ToolTip = 'The language code.'; } field(CompliantTableName; Rec."Compliant Table Name") { Editable = false; - ToolTip = 'The name of the table that is compliant with Data Lake standards.'; } field(CompliantFieldName; Rec."Compliant Field Name") { Editable = false; - ToolTip = 'The name of the field that is compliant with Data Lake standards.'; } field(EnumValueCaption; Rec."Enum Value Caption") { Editable = false; - ToolTip = 'The caption of the enum value.'; } } } diff --git a/businessCentral/app/src/Execute.Codeunit.al b/businessCentral/app/src/Execute.Codeunit.al index f6ee3c4..5e27458 100644 --- a/businessCentral/app/src/Execute.Codeunit.al +++ b/businessCentral/app/src/Execute.Codeunit.al @@ -138,7 +138,7 @@ codeunit 82561 "ADLSE Execute" if not SkipTimestampSorting then RecordRef.SetView(TimestampAscendingSortViewTxt); TimeStampFieldRef := RecordRef.Field(0); // 0 is the TimeStamp field - TimeStampFieldRef.SetFilter('>%1', UpdatedLastTimestamp); + TimeStampFieldRef.SetFilter('>%1', UpdatedLastTimeStamp); end; local procedure ExportTableUpdates(TableID: Integer; FieldIdList: List of [Integer]; ADLSECommunication: Codeunit "ADLSE Communication"; var UpdatedLastTimeStamp: BigInteger) @@ -156,12 +156,13 @@ codeunit 82561 "ADLSE Execute" FlushedTimeStamp: BigInteger; FieldId: Integer; SystemCreatedAt, UtcEpochZero : DateTime; + ErrorMessage: ErrorInfo; begin ADLSESetup.GetSingleton(); SetFilterForUpdates(TableID, UpdatedLastTimeStamp, ADLSESetup."Skip Timestamp Sorting On Recs", RecordRef, TimeStampFieldRef); foreach FieldId in FieldIdList do - if RecordRef.AddLoadFields(FieldID) then; + if RecordRef.AddLoadFields(FieldId) then; // ignore the return value if not RecordRef.ReadPermission() then Error(InsufficientReadPermErr); @@ -189,14 +190,14 @@ codeunit 82561 "ADLSE Execute" if UpdatedLastTimeStamp < FlushedTimeStamp then // sample the highest timestamp, to cater to the eventuality that the records do not appear sorted per timestamp UpdatedLastTimeStamp := FlushedTimeStamp; end else - Error('%1%2', GetLastErrorText(), GetLastErrorCallStack()); + ErrorMessage.Message := StrSubstNo('%1%2', GetLastErrorText(), GetLastErrorCallStack()); until RecordRef.Next() = 0; if ADLSECommunication.TryFinish(FlushedTimeStamp) then begin if UpdatedLastTimeStamp < FlushedTimeStamp then // sample the highest timestamp, to cater to the eventuality that the records do not appear sorted per timestamp UpdatedLastTimeStamp := FlushedTimeStamp end else - Error('%1%2', GetLastErrorText(), GetLastErrorCallStack()); + ErrorMessage.Message := StrSubstNo('%1%2', GetLastErrorText(), GetLastErrorCallStack()); end; if EmitTelemetry then ADLSEExecution.Log('ADLSE-009', 'Updated records exported', Verbosity::Normal); @@ -218,6 +219,7 @@ codeunit 82561 "ADLSE Execute" ADLSEDeletedRecord.SetFilter("Entry No.", '>%1', DeletedLastEntryNo); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Deleted Record", 'r')] local procedure ExportTableDeletes(TableID: Integer; ADLSECommunication: Codeunit "ADLSE Communication"; var DeletedLastEntryNo: BigInteger) var ADLSEDeletedRecord: Record "ADLSE Deleted Record"; @@ -229,6 +231,7 @@ codeunit 82561 "ADLSE Execute" TableCaption: Text; EntityCount: Text; FlushedTimeStamp: BigInteger; + ErrorMessage: ErrorInfo; begin SetFilterForDeletes(TableID, DeletedLastEntryNo, ADLSEDeletedRecord); @@ -252,18 +255,19 @@ codeunit 82561 "ADLSE Execute" if ADLSECommunication.TryCollectAndSendRecord(RecordRef, ADLSEDeletedRecord."Entry No.", FlushedTimeStamp) then DeletedLastEntryNo := FlushedTimeStamp else - Error('%1%2', GetLastErrorText(), GetLastErrorCallStack()); + ErrorMessage.Message := StrSubstNo('%1%2', GetLastErrorText(), GetLastErrorCallStack()); until ADLSEDeletedRecord.Next() = 0; if ADLSECommunication.TryFinish(FlushedTimeStamp) then DeletedLastEntryNo := FlushedTimeStamp else - Error('%1%2', GetLastErrorText(), GetLastErrorCallStack()); + ErrorMessage.Message := StrSubstNo('%1%2', GetLastErrorText(), GetLastErrorCallStack()); end; if EmitTelemetry then ADLSEExecution.Log('ADLSE-011', 'Deleted records exported', Verbosity::Normal, CustomDimensions); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Deleted Record", 'rd')] procedure FixDeletedRecordThatAreInTable(var ADLSEDeletedRecord: Record "ADLSE Deleted Record") var RecordRef: RecordRef; @@ -283,6 +287,7 @@ codeunit 82561 "ADLSE Execute" until ADLSEDeletedRecord.Next() = 0; end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Field", 'r')] procedure CreateFieldListForTable(TableID: Integer) FieldIdList: List of [Integer] var ADLSEField: Record "ADLSE Field"; @@ -313,7 +318,7 @@ codeunit 82561 "ADLSE Execute" CustomDimensions.Add('Entity', TableCaption); ADLSEExecution.Log('ADLSE-037', 'Finished the export process', Verbosity::Normal, CustomDimensions); end; - Commit(); + Commit(); //To avoid misreading // This export session is soon going to end. Start up a new one from // the stored list of pending tables to export. diff --git a/businessCentral/app/src/Execution.Codeunit.al b/businessCentral/app/src/Execution.Codeunit.al index e3d9e2f..2137991 100644 --- a/businessCentral/app/src/Execution.Codeunit.al +++ b/businessCentral/app/src/Execution.Codeunit.al @@ -17,6 +17,8 @@ codeunit 82569 "ADLSE Execution" ClearSchemaExportedOnMsg: Label 'The schema export date has been cleared.'; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'r')] + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Field", 'r')] internal procedure StartExport() var ADLSESetupRec: Record "ADLSE Setup"; @@ -78,6 +80,8 @@ codeunit 82569 "ADLSE Execution" Log('ADLSE-019', 'Stopped export sessions', Verbosity::Normal); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'r')] + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Setup", 'm')] internal procedure SchemaExport() var ADLSESetup: Record "ADLSE Setup"; @@ -114,11 +118,12 @@ codeunit 82569 "ADLSE Execution" ADLSESetup.GetSingleton(); ADLSESetup."Schema Exported On" := CurrentDateTime(); - ADLSESetup.Modify(); + ADLSESetup.Modify(true); ADLSEExternalEvents.OnExportSchema(ADLSESetup); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Setup", 'm')] internal procedure ClearSchemaExportedOn() var ADLSESetup: Record "ADLSE Setup"; @@ -126,7 +131,7 @@ codeunit 82569 "ADLSE Execution" begin ADLSESetup.GetSingleton(); ADLSESetup."Schema Exported On" := 0DT; - ADLSESetup.Modify(); + ADLSESetup.Modify(true); if GuiAllowed then Message(ClearSchemaExportedOnMsg); @@ -161,7 +166,7 @@ codeunit 82569 "ADLSE Execution" JobQueueEntry.Status := JobQueueEntry.Status::"On Hold"; JobQueueEntry.Description := JobQueueCategory.Description; JobQueueEntry."Object Type to Run" := JobQueueEntry."Object Type to Run"::Codeunit; - JobQueueEntry."Object ID to Run" := CODEUNIT::"ADLSE Execution"; + JobQueueEntry."Object ID to Run" := Codeunit::"ADLSE Execution"; JobQueueEntry."Earliest Start Date/Time" := CurrentDateTime(); // now end; @@ -179,7 +184,7 @@ codeunit 82569 "ADLSE Execution" [InherentPermissions(PermissionObjectType::Table, Database::"ADLSE Table Last Timestamp", 'X')] [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table Last Timestamp", 'R')] - [EventSubscriber(ObjectType::Codeunit, Codeunit::GlobalTriggerManagement, 'OnAfterGetDatabaseTableTriggerSetup', '', true, true)] + [EventSubscriber(ObjectType::Codeunit, Codeunit::GlobalTriggerManagement, OnAfterGetDatabaseTableTriggerSetup, '', true, true)] local procedure GetDatabaseTableTriggerSetup(TableId: Integer; var OnDatabaseInsert: Boolean; var OnDatabaseModify: Boolean; var OnDatabaseDelete: Boolean; var OnDatabaseRename: Boolean) var ADLSETableLastTimestamp: Record "ADLSE Table Last Timestamp"; @@ -195,7 +200,7 @@ codeunit 82569 "ADLSE Execution" [InherentPermissions(PermissionObjectType::Table, Database::"ADLSE Table Last Timestamp", 'X')] [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table Last Timestamp", 'R')] [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Deleted Record", 'RI')] - [EventSubscriber(ObjectType::Codeunit, Codeunit::GlobalTriggerManagement, 'OnAfterOnDatabaseDelete', '', true, true)] + [EventSubscriber(ObjectType::Codeunit, Codeunit::GlobalTriggerManagement, OnAfterOnDatabaseDelete, '', true, true)] local procedure OnAfterOnDatabaseDelete(RecRef: RecordRef) var ADLSETableLastTimestamp: Record "ADLSE Table Last Timestamp"; diff --git a/businessCentral/app/src/ExternalEvents.Codeunit.al b/businessCentral/app/src/ExternalEvents.Codeunit.al index 705c6a9..451b798 100644 --- a/businessCentral/app/src/ExternalEvents.Codeunit.al +++ b/businessCentral/app/src/ExternalEvents.Codeunit.al @@ -114,7 +114,9 @@ codeunit 82574 "ADLSE External Events" begin Url := ADLSEExternalEventsHelper.CreateLink(ADLSEFieldApiUrlTok, ADLSESetup.SystemId); WebClientUrl := CopyStr(GetUrl(ClientType::Web, CompanyName(), ObjectType::Page, Page::"ADLSE Setup", ADLSESetup), 1, MaxStrLen(WebClientUrl)); +#pragma warning disable AL0432 MyBusinessOnExportFinished(ADLSESetup.SystemId, ADLSESetup."Storage Type", Url, WebClientUrl); +#pragma warning restore AL0432 end; internal procedure OnExportFinished(ADLSESetup: Record "ADLSE Setup"; ADLSETable: Record "ADLSE Table") @@ -237,7 +239,7 @@ codeunit 82574 "ADLSE External Events" end; [EventSubscriber(ObjectType::Table, Database::"ADLSE Table", OnAfterResetSelected, '', true, true)] - local procedure OnAfterResetSelected(ADLSETable: Record "ADLSE Table"); + local procedure OnAfterResetSelected(ADLSETable: Record "ADLSE Table") begin MyBusinessEventOnAfterResetSelected(ADLSETable.SystemId, ADLSETable."Table ID"); end; diff --git a/businessCentral/app/src/Field.Table.al b/businessCentral/app/src/Field.Table.al index 716559c..60e8dbd 100644 --- a/businessCentral/app/src/Field.Table.al +++ b/businessCentral/app/src/Field.Table.al @@ -1,15 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma warning disable LC0015 table 82562 "ADLSE Field" +#pragma warning restore { Access = Internal; + Caption = 'ADLSE Field'; DataClassification = CustomerContent; DataPerCompany = false; + Permissions = tabledata "ADLSE Table" = r; fields { field(1; "Table ID"; Integer) { + AllowInCustomizations = Always; Editable = false; Caption = 'Table ID'; TableRelation = "ADLSE Table"."Table ID"; @@ -26,10 +31,12 @@ table 82562 "ADLSE Field" { Editable = false; Caption = 'Field ID'; + ToolTip = 'Specifies the ID of the field to be exported.'; } field(3; Enabled; Boolean) { Caption = 'Enabled'; + ToolTip = 'Specifies if the field will be exported.'; trigger OnValidate() var @@ -47,6 +54,7 @@ table 82562 "ADLSE Field" Editable = false; FieldClass = FlowField; CalcFormula = lookup(Field."Field Caption" where("No." = field("Field ID"), TableNo = field("Table ID"))); + ToolTip = 'Specifies the name of the field to be exported.'; } } @@ -86,6 +94,7 @@ table 82562 "ADLSE Field" var TableDoesNotExistErr: Label 'Table with ID %1 has not been set to be exported.', Comment = '%1 is the table ID'; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Field", 'ri')] procedure InsertForTable(ADLSETable: Record "ADLSE Table") var Field: Record Field; @@ -100,7 +109,7 @@ table 82562 "ADLSE Field" Rec."Table ID" := Field.TableNo; Rec."Field ID" := Field."No."; Rec.Enabled := false; - Rec.Insert(); + Rec.Insert(true); end; until Field.Next() = 0; end; diff --git a/businessCentral/app/src/FieldAPI.Page.al b/businessCentral/app/src/FieldAPI.Page.al index 8da7dc2..5e366ba 100644 --- a/businessCentral/app/src/FieldAPI.Page.al +++ b/businessCentral/app/src/FieldAPI.Page.al @@ -28,10 +28,16 @@ page 82567 "ADLSE Field API" { Editable = false; } +#pragma warning disable LC0016 field(systemRowVersion; Rec.SystemRowVersion) { Editable = false; } +#pragma warning restore + field(lastModifiedDateTime; Rec.SystemModifiedAt) + { + Editable = false; + } } } } diff --git a/businessCentral/app/src/Gen2Util.Codeunit.al b/businessCentral/app/src/Gen2Util.Codeunit.al index ab36fb0..94dab36 100644 --- a/businessCentral/app/src/Gen2Util.Codeunit.al +++ b/businessCentral/app/src/Gen2Util.Codeunit.al @@ -24,7 +24,7 @@ codeunit 82568 "ADLSE Gen 2 Util" CouldNotCreateBlobErr: Label 'Could not create blob %1. %2', Comment = '%1: blob path, %2: error text'; CouldNotReadDataInBlobErr: Label 'Could not read data on %1. %2', Comment = '%1: blob path, %2: Http respomse'; CouldNotReadResponseHeaderErr: Label 'Could not read %1 from %2.', Comment = '%1: content header value , %2: blob path'; - LatestBlockTagTok: Label '%1', Comment = '%1: block ID'; + LatestBlockTagTok: Label '%1', Comment = '%1: block ID', Locked = true; procedure ContainerExists(ContainerPath: Text; ADLSECredentials: Codeunit "ADLSE Credentials"): Boolean var @@ -89,7 +89,7 @@ codeunit 82568 "ADLSE Gen 2 Util" ContentLengthTok: Label 'Content-Length', Locked = true; begin OnBeforeGetBlobContentLength(BlobPath, ContentLength, IsHandled); - If IsHandled then + if IsHandled then exit; ADLSEHttp.SetMethod("ADLSE Http Method"::Head); diff --git a/businessCentral/app/src/Http.Codeunit.al b/businessCentral/app/src/Http.Codeunit.al index 37e3f64..9bfe964 100644 --- a/businessCentral/app/src/Http.Codeunit.al +++ b/businessCentral/app/src/Http.Codeunit.al @@ -16,9 +16,9 @@ codeunit 82563 "ADLSE Http" ContentTypeApplicationJsonTok: Label 'application/json', Locked = true; ContentTypePlainTextTok: Label 'text/plain; charset=utf-8', Locked = true; UnsupportedMethodErr: Label 'Unsupported method: %1', Comment = '%1: http method name'; - OAuthTok: Label 'https://login.microsoftonline.com/%1/oauth2/token', Comment = '%1: tenant id'; - BearerTok: Label 'Bearer %1', Comment = '%1: access token'; - AcquireTokenBodyTok: Label 'resource=%1&scope=%2&client_id=%3&client_secret=%4&grant_type=client_credentials', Comment = '%1: encoded resource url, %2: encoded scope url, %3: client ID, %4: client secret'; + OAuthTok: Label 'https://login.microsoftonline.com/%1/oauth2/token', Comment = '%1: tenant id', Locked = true; + BearerTok: Label 'Bearer %1', Comment = '%1: access token', Locked = true; + AcquireTokenBodyTok: Label 'resource=%1&scope=%2&client_id=%3&client_secret=%4&grant_type=client_credentials', Comment = '%1: encoded resource url, %2: encoded scope url, %3: client ID, %4: client secret', Locked = true; procedure SetMethod(HttpMethodValue: Enum "ADLSE Http Method") begin @@ -192,7 +192,7 @@ codeunit 82563 "ADLSE Http" var ADLSEUtil: Codeunit "ADLSE Util"; Headers: HttpHeaders; - AccessToken: Text; + AccessToken: SecretText; AuthError: Text; begin if not Credentials.IsInitialized() then begin // anonymous call @@ -201,13 +201,13 @@ codeunit 82563 "ADLSE Http" end; AccessToken := AcquireTokenOAuth2(AuthError); - if AccessToken = '' then begin + if AccessToken.IsEmpty() then begin Response := AuthError; Success := false; exit; end; Headers := HttpClient.DefaultRequestHeaders(); - Headers.Add('Authorization', StrSubstNo(BearerTok, AccessToken)); + Headers.Add('Authorization', SecretStrSubstNo(BearerTok, AccessToken)); Headers.Add('x-ms-version', AzureStorageServiceVersionTok); Headers.Add('x-ms-date', ADLSEUtil.GetCurrentDateTimeInGMTFormat()); Success := true; diff --git a/businessCentral/app/src/HttpMethod.Enum.al b/businessCentral/app/src/HttpMethod.Enum.al index 7f2cf3b..4a1e8cc 100644 --- a/businessCentral/app/src/HttpMethod.Enum.al +++ b/businessCentral/app/src/HttpMethod.Enum.al @@ -5,9 +5,11 @@ enum 82561 "ADLSE Http Method" Access = Internal; Extensible = false; +#pragma warning disable LC0016, LC0045 value(0; Get) { } value(1; Put) { } value(2; Delete) { } value(3; Patch) { } value(4; Head) { } +#pragma warning restore } \ No newline at end of file diff --git a/businessCentral/app/src/Installer.Codeunit.al b/businessCentral/app/src/Installer.Codeunit.al index bd09310..63df1ec 100644 --- a/businessCentral/app/src/Installer.Codeunit.al +++ b/businessCentral/app/src/Installer.Codeunit.al @@ -23,6 +23,7 @@ codeunit 82571 "ADLSE Installer" RetenPolAllowedTables.AddAllowedTable(Database::"ADLSE Run", ADLSERun.FieldNo(SystemModifiedAt)); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'r')] procedure ListInvalidFieldsBeingExported() InvalidFieldsMap: Dictionary of [Integer, List of [Text]] var ADLSETable: Record "ADLSE Table"; @@ -38,6 +39,7 @@ codeunit 82571 "ADLSE Installer" until ADLSETable.Next() = 0; end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'rm')] local procedure DisableTablesExportingInvalidFields() var ADLSETable: Record "ADLSE Table"; @@ -51,7 +53,7 @@ codeunit 82571 "ADLSE Installer" foreach TableID in InvalidFieldsMap.Keys() do begin ADLSETable.Get(TableID); ADLSETable.Enabled := false; - ADLSETable.Modify(); + ADLSETable.Modify(true); Clear(CustomDimensions); CustomDimensions.Add('Entity', ADLSEUtil.GetTableCaption(TableID)); diff --git a/businessCentral/app/src/Run.Page.al b/businessCentral/app/src/Run.Page.al index bcd926c..59c91c6 100644 --- a/businessCentral/app/src/Run.Page.al +++ b/businessCentral/app/src/Run.Page.al @@ -22,40 +22,22 @@ page 82563 "ADLSE Run" field("TableCaption"; NameOfTable) { - ApplicationArea = All; Caption = 'Table'; - Tooltip = 'Specifies the caption of the table whose data was exported.'; + ToolTip = 'Specifies the caption of the table whose data was exported.'; Visible = not DisplayLogsForGivenTable; } - field(State; Rec.State) - { - ApplicationArea = All; - ToolTip = 'Specifies the state of the execution of export.'; - } + field(State; Rec.State) { } - field(Started; Rec.Started) - { - ApplicationArea = All; - ToolTip = 'Specifies when the export was started.'; - } + field(Started; Rec.Started) { } - field(Ended; Rec.Ended) - { - ApplicationArea = All; - ToolTip = 'Specifies when the export was started.'; - } + field(Ended; Rec.Ended) { } field("Duration"; Rec.Duration()) { - ApplicationArea = All; Caption = 'Duration'; ToolTip = 'Specifies how long export has run.'; } - field("Error"; Rec.Error) - { - ApplicationArea = All; - ToolTip = 'Specifies the error if the execution had any.'; - } + field("Error"; Rec.Error) { } } } } @@ -68,7 +50,7 @@ page 82563 "ADLSE Run" { ApplicationArea = All; Caption = 'Clear execution log'; - Tooltip = 'Removes the history of the export executions. This should be done periodically to free up storage space.'; + ToolTip = 'Removes the history of the export executions. This should be done periodically to free up storage space.'; Image = ClearLog; Enabled = LogsFound; diff --git a/businessCentral/app/src/Run.Table.al b/businessCentral/app/src/Run.Table.al index ae602f7..671ed1a 100644 --- a/businessCentral/app/src/Run.Table.al +++ b/businessCentral/app/src/Run.Table.al @@ -1,8 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma warning disable LC0004, LC0015 table 82566 "ADLSE Run" +#pragma warning restore { Access = Internal; + Caption = 'ADLSE Run'; DataClassification = CustomerContent; DataPerCompany = false; @@ -10,17 +13,20 @@ table 82566 "ADLSE Run" { field(1; ID; Integer) { + AllowInCustomizations = Always; Editable = false; Caption = 'ID'; AutoIncrement = true; } field(2; "Table ID"; Integer) { + AllowInCustomizations = Always; Editable = false; Caption = 'Table ID'; } field(3; "Company Name"; Text[30]) { + AllowInCustomizations = Always; Editable = false; Caption = 'Company name'; } @@ -28,21 +34,25 @@ table 82566 "ADLSE Run" { Editable = false; Caption = 'State'; + ToolTip = 'Specifies the state of the execution of export.'; } field(5; "Error"; Text[2048]) { Editable = false; Caption = 'Error'; + ToolTip = 'Specifies the error if the execution had any.'; } field(6; Started; DateTime) { Editable = false; Caption = 'Started'; + ToolTip = 'Specifies when the export was started.'; } field(7; Ended; DateTime) { Editable = false; Caption = 'Ended'; + ToolTip = 'Specifies when the export was started.'; } } @@ -65,7 +75,7 @@ table 82566 "ADLSE Run" ExportStoppedDueToCancelledSessionTxt: Label 'Export stopped as session was cancelled. Please check state of the export on the data lake before enabling this.'; CouldNotUpdateExportRunStatusErr: Label 'Could not update the status of the export run for table to %1.', Comment = '%1: New status'; - procedure GetLastRunDetails(TableID: Integer; var Status: enum "ADLSE Run State"; var StartedTime: DateTime; var ErrorIfAny: Text[2048]) + procedure GetLastRunDetails(TableID: Integer; var Status: Enum "ADLSE Run State"; var StartedTime: DateTime; var ErrorIfAny: Text[2048]) begin if FindLastRun(TableID) then begin Status := Rec.State; @@ -85,6 +95,7 @@ table 82566 "ADLSE Run" exit(Round(Ended - Started, 100)); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE run", 'i')] procedure RegisterStarted(TableID: Integer) begin Rec.Init(); @@ -92,9 +103,10 @@ table 82566 "ADLSE Run" Rec."Company Name" := CopyStr(CompanyName(), 1, 30); Rec.State := "ADLSE Run State"::InProcess; Rec.Started := CurrentDateTime(); - Rec.Insert(); + Rec.Insert(true); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE run", 'm')] procedure RegisterEnded(TableID: Integer; EmitTelemetry: Boolean; TableCaption: Text) var ADLSEExecution: Codeunit "ADLSE Execution"; @@ -118,7 +130,7 @@ table 82566 "ADLSE Run" Rec.Ended := CurrentDateTime(); ADLSEExternalEvents.OnTableExportRunEnded(Rec.ID, Rec.Started, Rec.Ended, Rec."Table ID", Rec.State); - if not Rec.Modify() then + if not Rec.Modify(true) then ADLSEExecution.Log('ADLSE-035', StrSubstNo(CouldNotUpdateExportRunStatusErr, Rec.State), Verbosity::Error, CustomDimensions) else ADLSEExecution.Log('ADLSE-038', 'The export run was registered as ended.', Verbosity::Normal, CustomDimensions); @@ -138,6 +150,7 @@ table 82566 "ADLSE Run" FillErrorDetails(LastErrorMessage, EmitTelemetry, CustomDimensions); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE run", 'm')] local procedure FillErrorDetails(LastErrorMessage: Text; EmitTelemetry: Boolean; CustomDimensions: Dictionary of [Text, Text]) var ADLSEExecution: Codeunit "ADLSE Execution"; @@ -145,7 +158,7 @@ table 82566 "ADLSE Run" begin LastErrorStack := GetLastErrorCallStack(); Rec.Error := CopyStr(LastErrorMessage + LastErrorStack, 1, 2048); // 2048 is the max size of the field - Rec.Modify(); + Rec.Modify(true); if EmitTelemetry then begin CustomDimensions.Add('Error text', LastErrorMessage); @@ -155,24 +168,27 @@ table 82566 "ADLSE Run" ClearLastError(); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE run", 'm')] procedure CancelAllRuns() begin Rec.SetRange(State, "ADLSE Run State"::InProcess); - Rec.ModifyAll(Ended, CurrentDateTime); - Rec.ModifyAll(State, "ADLSE Run State"::Failed); - Rec.ModifyAll(Error, ExportStoppedDueToCancelledSessionTxt); + Rec.ModifyAll(Ended, CurrentDateTime, true); + Rec.ModifyAll(State, "ADLSE Run State"::Failed, true); + Rec.ModifyAll(Error, ExportStoppedDueToCancelledSessionTxt, true); end; - procedure OldRunsExist(): Boolean; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE run", 'r')] + procedure OldRunsExist(): Boolean begin CommmonFilterOnOldRuns(); exit(not Rec.IsEmpty()); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE run", 'd')] procedure DeleteOldRuns() begin CommmonFilterOnOldRuns(); - Rec.DeleteAll(); + Rec.DeleteAll(false); end; procedure DeleteOldRuns(TableID: Integer) @@ -181,6 +197,7 @@ table 82566 "ADLSE Run" DeleteOldRuns(); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE run", 'r')] local procedure FindLastRun(TableID: Integer) Found: Boolean begin Rec.SetCurrentKey(ID); diff --git a/businessCentral/app/src/RunAPI.Page.al b/businessCentral/app/src/RunAPI.Page.al index 5030a53..651c5a9 100644 --- a/businessCentral/app/src/RunAPI.Page.al +++ b/businessCentral/app/src/RunAPI.Page.al @@ -31,10 +31,17 @@ page 82566 "ADLSE Run API" { Editable = false; } +#pragma warning disable LC0016 field(systemRowVersion; Rec.SystemRowVersion) { Editable = false; } +#pragma warning restore + + field(lastModifiedDateTime; Rec.SystemModifiedAt) + { + Editable = false; + } } } } diff --git a/businessCentral/app/src/RunState.Enum.al b/businessCentral/app/src/RunState.Enum.al index f2420c0..e8e3470 100644 --- a/businessCentral/app/src/RunState.Enum.al +++ b/businessCentral/app/src/RunState.Enum.al @@ -5,10 +5,12 @@ enum 82560 "ADLSE Run State" Access = Internal; Extensible = false; +#pragma warning disable LC0045 value(0; None) { Caption = 'Never run'; } +#pragma warning restore LC0045 value(1; InProcess) { diff --git a/businessCentral/app/src/SessionManager.Codeunit.al b/businessCentral/app/src/SessionManager.Codeunit.al index 8be4129..80c0e32 100644 --- a/businessCentral/app/src/SessionManager.Codeunit.al +++ b/businessCentral/app/src/SessionManager.Codeunit.al @@ -24,6 +24,7 @@ codeunit 82570 "ADLSE Session Manager" StartExport(TableID, true, false, EmitTelemetry); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'r')] local procedure StartExport(TableID: Integer; ExportWasPending: Boolean; ForceExport: Boolean; EmitTelemetry: Boolean) Started: Boolean var ADLSETable: Record "ADLSE Table"; @@ -155,8 +156,10 @@ codeunit 82570 "ADLSE Session Manager" var Result: Text; begin +#pragma warning disable LC0043 IsolatedStorage.Get(PendingTablesKeyTxt, DataScope::Company, Result); exit(DeConcatenate(Result)); +#pragma warning restore LC0043 end; local procedure Concatenate(Values: List of [Integer]) Result: Text @@ -184,7 +187,9 @@ codeunit 82570 "ADLSE Session Manager" internal procedure SavePendingTables(Value: Text) begin +#pragma warning disable LC0043 if IsolatedStorage.Set(PendingTablesKeyTxt, Value, DataScope::Company) then - Commit(); // changing isolated storage triggers a write transaction + Commit(); // changing isolated storage triggers a write transaction +#pragma warning restore LC0043 end; } \ No newline at end of file diff --git a/businessCentral/app/src/Setup.Codeunit.al b/businessCentral/app/src/Setup.Codeunit.al index 3964219..2034076 100644 --- a/businessCentral/app/src/Setup.Codeunit.al +++ b/businessCentral/app/src/Setup.Codeunit.al @@ -94,6 +94,9 @@ codeunit 82560 "ADLSE Setup" ADLSECredentials.Check(); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Field", 'rd')] + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'rd')] + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Setup", 'm')] procedure FixIncorrectData() var ADLSEField: Record "ADLSE Field"; diff --git a/businessCentral/app/src/Setup.Page.al b/businessCentral/app/src/Setup.Page.al index 4968dfd..602ccaa 100644 --- a/businessCentral/app/src/Setup.Page.al +++ b/businessCentral/app/src/Setup.Page.al @@ -9,7 +9,6 @@ page 82560 "ADLSE Setup" InsertAllowed = false; DeleteAllowed = false; Caption = 'Export to Azure Data Lake Storage'; - layout { area(Content) @@ -22,8 +21,6 @@ page 82560 "ADLSE Setup" Caption = 'Account'; field(StorageType; Rec."Storage Type") { - Tooltip = 'Specifies the type of storage type to use.'; - trigger OnValidate() begin CurrPage.Update(true); @@ -32,7 +29,7 @@ page 82560 "ADLSE Setup" field("Tenant ID"; StorageTenantID) { Caption = 'Tenant ID'; - Tooltip = 'Specifies the tenant ID which holds the app registration as well as the storage account. Note that they have to be on the same tenant.'; + ToolTip = 'Specifies the tenant ID which holds the app registration as well as the storage account. Note that they have to be on the same tenant.'; trigger OnValidate() begin @@ -45,27 +42,15 @@ page 82560 "ADLSE Setup" { Caption = 'Azure Data Lake'; Editable = AzureDataLake; - field(Container; Rec.Container) - { - Tooltip = 'Specifies the name of the container where the data is going to be uploaded. Please refer to constraints on container names at https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata.'; - } - field(AccountName; Rec."Account Name") - { - Tooltip = 'Specifies the name of the storage account.'; - } + field(Container; Rec.Container) { } + field(AccountName; Rec."Account Name") { } } group(MSFabric) { Caption = 'Microsoft Fabric'; Editable = not AzureDataLake; - field(Workspace; Rec.Workspace) - { - Tooltip = 'Specifies the name of the Workspace where the data is going to be uploaded. This can be a name or a GUID.'; - } - field(Lakehouse; Rec.Lakehouse) - { - Tooltip = 'Specifies the name of the Lakehouse where the data is going to be uploaded. This can be a name or a GUID.'; - } + field(Workspace; Rec.Workspace) { } + field(Lakehouse; Rec.Lakehouse) { } } group(Access) { @@ -74,7 +59,7 @@ page 82560 "ADLSE Setup" { Caption = 'Client ID'; ExtendedDatatype = Masked; - Tooltip = 'Specifies the application client ID for the Azure App Registration that accesses the storage account.'; + ToolTip = 'Specifies the application client ID for the Azure App Registration that accesses the storage account.'; trigger OnValidate() begin @@ -85,7 +70,7 @@ page 82560 "ADLSE Setup" { Caption = 'Client secret'; ExtendedDatatype = Masked; - Tooltip = 'Specifies the client secret for the Azure App Registration that accesses the storage account.'; + ToolTip = 'Specifies the client secret for the Azure App Registration that accesses the storage account.'; trigger OnValidate() begin @@ -99,27 +84,21 @@ page 82560 "ADLSE Setup" field(MaxPayloadSize; Rec.MaxPayloadSizeMiB) { Editable = not AzureDataLake; - Tooltip = 'Specifies the maximum size of the upload for each block of data in MiBs. A large value will reduce the number of iterations to upload the data but may interfear with the performance of other processes running on this environment.'; - } - field("CDM data format"; Rec.DataFormat) - { - ToolTip = 'Specifies the format in which to store the exported data in the ''data'' CDM folder. The Parquet format is recommended for storing the data with the best fidelity.'; } + field("CDM data format"; Rec.DataFormat) { } + field("Skip Timestamp Sorting On Recs"; Rec."Skip Timestamp Sorting On Recs") { Enabled = not ExportInProgress; - ToolTip = 'Specifies that the records are not sorted as per their row version before exporting them to the lake. Enabling this may interfear with how incremental data is pushed to the lake in subsequent export runs- please refer to the documentation.'; - } - field("Emit telemetry"; Rec."Emit telemetry") - { - Tooltip = 'Specifies if operational telemetry will be emitted to this extension publisher''s telemetry pipeline. You will have to configure a telemetry account for this extension first.'; } + + field("Emit telemetry"; Rec."Emit telemetry") { } field("Translations"; Rec.Translations) { - ToolTip = 'Specifies the translations for the enums used in the selected tables.'; + trigger OnAssistEdit() var @@ -139,26 +118,16 @@ page 82560 "ADLSE Setup" Rec.Translations += Language.Code + ';'; until Language.Next() = 0; //Remove last semicolon - Rec.Translations := CopyStr(Rec.Translations, 1, StrLen(Rec.Translations) - 1); + Rec.Translations := CopyStr(CopyStr(Rec.Translations, 1, StrLen(Rec.Translations) - 1), 1, 250); CurrPage.Update(); end; end; } - field("Export Enum as Integer"; Rec."Export Enum as Integer") - { - ToolTip = 'Specifies if the enums will be exported as integers instead of strings. This is useful if you want to use the enums in Power BI.'; - } - field("Delete Table"; Rec."Delete Table") - { - ToolTip = 'Specifies if the table will be deleted if a reset of the table is done.'; - } - field("Delivered DateTime"; Rec."Delivered DateTime") - { - ToolTip = 'Specifies if the column DeliveredDateTime will be added to the CSV export file.'; - } + field("Export Enum as Integer"; Rec."Export Enum as Integer") { } + field("Delete Table"; Rec."Delete Table") { } + field("Delivered DateTime"; Rec."Delivered DateTime") { } field("Export Company Database Tables"; Rec."Export Company Database Tables") { - ToolTip = 'Specifies the company for the export of the database tables.'; Lookup = true; } } @@ -178,7 +147,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Export'; - Tooltip = 'Starts the export process by spawning different sessions for each table. The action is disabled in case there are export processes currently running, also in other companies.'; + ToolTip = 'Starts the export process by spawning different sessions for each table. The action is disabled in case there are export processes currently running, also in other companies.'; Image = Start; Enabled = not ExportInProgress; @@ -195,7 +164,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Stop export'; - Tooltip = 'Tries to stop all sessions that are exporting data, including those that are running in other companies.'; + ToolTip = 'Tries to stop all sessions that are exporting data, including those that are running in other companies.'; Image = Stop; trigger OnAction() @@ -210,7 +179,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Schema export'; - Tooltip = 'This will export the schema of the tables selected in the setup to the lake. This is a one-time operation and should be done before the first export of data.'; + ToolTip = 'This will export the schema of the tables selected in the setup to the lake. This is a one-time operation and should be done before the first export of data.'; Image = Start; trigger OnAction() @@ -225,7 +194,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Clear schema export date'; - Tooltip = 'This will clear the schema exported on field. If this is cleared you can change the schema and export it again.'; + ToolTip = 'This will clear the schema exported on field. If this is cleared you can change the schema and export it again.'; Image = ClearLog; trigger OnAction() @@ -241,7 +210,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Schedule export'; - Tooltip = 'Schedules the export process as a job queue entry.'; + ToolTip = 'Schedules the export process as a job queue entry.'; Image = Timesheet; trigger OnAction() @@ -256,7 +225,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Clear tracked deleted records'; - Tooltip = 'Removes the entries in the deleted record list that have already been exported. This should be done periodically to free up storage space. The codeunit ADLSE Clear Tracked Deletions may be invoked using a job queue entry for the same end.'; + ToolTip = 'Removes the entries in the deleted record list that have already been exported. The codeunit ADLSE Clear Tracked Deletions may be invoked using a job queue entry for the same end.'; Image = ClearLog; Enabled = TrackedDeletedRecordsExist; @@ -271,7 +240,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Clear execution log'; - Tooltip = 'Removes the history of the export executions. This should be done periodically to free up storage space.'; + ToolTip = 'Removes the history of the export executions. This should be done periodically to free up storage space.'; Image = History; Enabled = OldLogsExist; @@ -288,7 +257,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Fix incorrect data'; - Tooltip = 'Fixes incorrect tables and fields in the setup. This should be done if you have deleted some tables and fields and you cannot disable them.'; + ToolTip = 'Fixes incorrect tables and fields in the setup. This should be done if you have deleted some tables and fields and you cannot disable them.'; Image = Error; trigger OnAction() @@ -305,7 +274,7 @@ page 82560 "ADLSE Setup" { ApplicationArea = All; Caption = 'Enum translations'; - Tooltip = 'Show the translations for the enums used in the selected tables.'; + ToolTip = 'Show the translations for the enums used in the selected tables.'; Image = Translations; RunObject = page "ADLSE Enum Translations"; } @@ -374,12 +343,13 @@ page 82560 "ADLSE Setup" FailureNotificationID: Guid; ExportFailureNotificationMsg: Label 'Data from one or more tables failed to export on the last run. Please check the tables below to see the error(s).'; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'r')] local procedure UpdateNotificationIfAnyTableExportFailed() var ADLSETable: Record "ADLSE Table"; ADLSERun: Record "ADLSE Run"; FailureNotification: Notification; - Status: enum "ADLSE Run State"; + Status: Enum "ADLSE Run State"; LastStarted: DateTime; ErrorIfAny: Text[2048]; begin diff --git a/businessCentral/app/src/Setup.Table.al b/businessCentral/app/src/Setup.Table.al index 9221040..f70f657 100644 --- a/businessCentral/app/src/Setup.Table.al +++ b/businessCentral/app/src/Setup.Table.al @@ -1,8 +1,11 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma warning disable LC0015 table 82560 "ADLSE Setup" +#pragma warning restore { Access = Internal; + Caption = 'ADLSE Setup'; DataClassification = CustomerContent; DataPerCompany = false; DataCaptionFields = Container; @@ -11,6 +14,7 @@ table 82560 "ADLSE Setup" { field(1; "Primary Key"; Integer) { + AllowInCustomizations = Always; Caption = 'Primary Key'; Editable = false; } @@ -18,6 +22,7 @@ table 82560 "ADLSE Setup" field(5; "Account Name"; Text[24]) { Caption = 'Account Name'; + ToolTip = 'Specifies the name of the storage account.'; trigger OnValidate() begin @@ -32,6 +37,7 @@ table 82560 "ADLSE Setup" field(2; Container; Text[63]) { Caption = 'Container'; + ToolTip = 'Specifies the name of the container where the data is going to be uploaded. Please refer to constraints on container names at https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata.'; trigger OnValidate() begin @@ -47,6 +53,7 @@ table 82560 "ADLSE Setup" field(3; MaxPayloadSizeMiB; Integer) { Caption = 'Max payload size (MiBs)'; + ToolTip = 'Specifies the maximum size of the upload for each block of data in MiBs. A large value will reduce the number of iterations to upload the data but may interfear with the performance of other processes running on this environment.'; InitValue = 4; // Refer max limit for put block calls (https://docs.microsoft.com/en-us/rest/api/storageservices/put-block#remarks) MaxValue = 4000; @@ -56,6 +63,7 @@ table 82560 "ADLSE Setup" field(4; DataFormat; Enum "ADLSE CDM Format") { Caption = 'CDM data format'; + ToolTip = 'Specifies the format in which to store the exported data in the ''data'' CDM folder. The Parquet format is recommended for storing the data with the best fidelity.'; InitValue = Parquet; } @@ -72,6 +80,7 @@ table 82560 "ADLSE Setup" { Caption = 'Emit telemetry'; InitValue = true; + ToolTip = 'Specifies if operational telemetry will be emitted to this extension publisher''s telemetry pipeline. You will have to configure a telemetry account for this extension first.'; } field(15; "Multi- Company Export"; Boolean) @@ -97,16 +106,19 @@ table 82560 "ADLSE Setup" { Caption = 'Skip row version sorting'; InitValue = false; + ToolTip = 'Specifies that the records are not sorted as per their row version before exporting them to the lake. Enabling this may interfear with how incremental data is pushed to the lake in subsequent export runs- please refer to the documentation.'; } field(25; "Storage Type"; Enum "ADLSE Storage Type") { Caption = 'Storage type'; + ToolTip = 'Specifies the type of storage type to use.'; } field(30; Workspace; Text[100]) { Caption = 'Workspace'; + ToolTip = 'Specifies the name of the Workspace where the data is going to be uploaded. This can be a name or a GUID.'; trigger OnValidate() var ValidGuid: Guid; @@ -121,6 +133,7 @@ table 82560 "ADLSE Setup" field(31; Lakehouse; Text[100]) { Caption = 'Lakehouse'; + ToolTip = 'Specifies the name of the Lakehouse where the data is going to be uploaded. This can be a name or a GUID.'; trigger OnValidate() var ValidGuid: Guid; @@ -134,15 +147,18 @@ table 82560 "ADLSE Setup" } field(35; "Schema Exported On"; DateTime) { + AllowInCustomizations = Always; Caption = 'Schema exported on'; } field(40; "Translations"; Text[250]) { Caption = 'Translations'; + ToolTip = 'Specifies the translations for the enums used in the selected tables.'; } field(45; "Export Enum as Integer"; Boolean) { Caption = 'Export Enum as Integer'; + ToolTip = 'Specifies if the enums will be exported as integers instead of strings. This is useful if you want to use the enums in Power BI.'; trigger OnValidate() begin if Rec."Schema Exported On" <> 0DT then @@ -152,9 +168,11 @@ table 82560 "ADLSE Setup" field(50; "Delete Table"; Boolean) { Caption = 'Delete table'; + ToolTip = 'Specifies if the table will be deleted if a reset of the table is done.'; } field(55; "Maximum Retries"; Integer) { + AllowInCustomizations = Always; Caption = 'Maximum retries'; InitValue = 0; @@ -172,12 +190,16 @@ table 82560 "ADLSE Setup" field(60; "Delivered DateTime"; Boolean) { Caption = 'Add delivered DateTime'; + ToolTip = 'Specifies if the column DeliveredDateTime will be added to the CSV export file.'; } //Add field for lookup to table companies field(65; "Export Company Database Tables"; Text[30]) { Caption = 'Export Company Database Tables'; + ToolTip = 'Specifies the company for the export of the database tables.'; TableRelation = Company.Name; + + } } @@ -228,6 +250,7 @@ table 82560 "ADLSE Setup" Insert(); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Setup", 'r')] procedure Exists(): Boolean begin exit(Rec.Get(GetPrimaryKeyValue())); diff --git a/businessCentral/app/src/SetupAPI.Page.al b/businessCentral/app/src/SetupAPI.Page.al index e07d886..02fd7ed 100644 --- a/businessCentral/app/src/SetupAPI.Page.al +++ b/businessCentral/app/src/SetupAPI.Page.al @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma warning disable LC0015 page 82564 "ADLSE Setup API" +#pragma warning restore { PageType = API; APIPublisher = 'bc2adlsTeamMicrosoft'; diff --git a/businessCentral/app/src/SetupAPIv11.Page.al b/businessCentral/app/src/SetupAPIv11.Page.al index 067a540..2eca1ba 100644 --- a/businessCentral/app/src/SetupAPIv11.Page.al +++ b/businessCentral/app/src/SetupAPIv11.Page.al @@ -34,10 +34,16 @@ page 82568 "ADLSE Setup API v11" { Editable = false; } +#pragma warning disable LC0016 field(systemRowVersion; Rec.SystemRowVersion) { Editable = false; } +#pragma warning restore + field(lastModifiedDateTime; Rec.SystemModifiedAt) + { + Editable = false; + } } } } diff --git a/businessCentral/app/src/SetupFields.Page.al b/businessCentral/app/src/SetupFields.Page.al index 51a852a..ec76f78 100644 --- a/businessCentral/app/src/SetupFields.Page.al +++ b/businessCentral/app/src/SetupFields.Page.al @@ -17,59 +17,45 @@ page 82562 "ADLSE Setup Fields" { repeater(GroupName) { - field("FieldCaption"; Rec.FieldCaption) - { - ApplicationArea = All; - Tooltip = 'Specifies the name of the field to be exported'; - } + field("FieldCaption"; Rec.FieldCaption) { } field("Field ID"; Rec."Field ID") { - ApplicationArea = All; Caption = 'Number'; - Tooltip = 'Specifies the ID of the field to be exported'; Visible = false; } - field(Enabled; Rec.Enabled) - { - ApplicationArea = All; - Tooltip = 'Specifies if the field will be exported'; - } + field(Enabled; Rec.Enabled) { } field(ADLSFieldName; ADLSFieldName) { - ApplicationArea = All; Caption = 'Attribute name'; - Tooltip = 'Specifies the name of the field for this entity in the data lake.'; + ToolTip = 'Specifies the name of the field for this entity in the data lake.'; Editable = false; } field("Field Class"; FieldClassName) { - ApplicationArea = All; Caption = 'Class'; OptionCaption = 'Normal,FlowField,FlowFilter'; - Tooltip = 'Specifies the field class'; + ToolTip = 'Specifies the field class.'; Editable = false; Visible = false; } field("Field Type"; FieldTypeName) { - ApplicationArea = All; Caption = 'Type'; - Tooltip = 'Specifies the field type'; + ToolTip = 'Specifies the field type.'; Editable = false; Visible = false; } field("Obsolete State"; FieldObsoleteState) { - ApplicationArea = All; Caption = 'Obsolete State'; OptionCaption = 'No,Pending,Removed'; - Tooltip = 'Specifies the Obsolete State of the field'; + ToolTip = 'Specifies the Obsolete State of the field.'; Editable = false; Visible = false; } diff --git a/businessCentral/app/src/SetupTables.Page.al b/businessCentral/app/src/SetupTables.Page.al index 872603f..9e672ac 100644 --- a/businessCentral/app/src/SetupTables.Page.al +++ b/businessCentral/app/src/SetupTables.Page.al @@ -11,7 +11,7 @@ page 82561 "ADLSE Setup Tables" layout { - area(content) + area(Content) { repeater(Control1) { @@ -22,21 +22,20 @@ page 82561 "ADLSE Setup Tables" ApplicationArea = All; Editable = false; Caption = 'Table'; - Tooltip = 'Specifies the caption of the table whose data is to exported.'; + ToolTip = 'Specifies the caption of the table whose data is to exported.'; } field(Enabled; Rec.Enabled) { ApplicationArea = All; Editable = true; Caption = 'Enabled'; - Tooltip = 'Specifies the state of the table. Set this checkmark to export this table, otherwise not.'; } field(FieldsChosen; NumberFieldsChosenValue) { ApplicationArea = All; Editable = false; Caption = '# Fields selected'; - Tooltip = 'Shows if any field has been chosen to be exported. Click on Choose Fields action to add fields to export.'; + ToolTip = 'Specifies if any field has been chosen to be exported. Click on Choose Fields action to add fields to export.'; trigger OnDrillDown() begin @@ -48,21 +47,21 @@ page 82561 "ADLSE Setup Tables" ApplicationArea = All; Editable = false; Caption = 'Entity name'; - Tooltip = 'The name of the entity corresponding to this table on the data lake. The value at the end indicates the table number in Dynamics 365 Business Central.'; + ToolTip = 'Specifies the name of the entity corresponding to this table on the data lake. The value at the end indicates the table number in Dynamics 365 Business Central.'; } field(Status; LastRunState) { ApplicationArea = All; Caption = 'Last exported state'; Editable = false; - Tooltip = 'Specifies the status of the last export from this table in this company.'; + ToolTip = 'Specifies the status of the last export from this table in this company.'; } field(LastRanAt; LastStarted) { ApplicationArea = All; Caption = 'Last started at'; Editable = false; - Tooltip = 'Specifies the time of the last export from this table in this company.'; + ToolTip = 'Specifies the time of the last export from this table in this company.'; } field(LastError; LastRunError) { @@ -74,14 +73,14 @@ page 82561 "ADLSE Setup Tables" field(LastTimestamp; UpdatedLastTimestamp) { ApplicationArea = All; - Tooltip = 'The timestamp of the record in this table that was exported last.'; + ToolTip = 'Specifies the timestamp of the record in this table that was exported last.'; Caption = 'Last timestamp'; Visible = false; } field(LastTimestampDeleted; DeletedRecordLastEntryNo) { ApplicationArea = All; - Tooltip = 'The timestamp of the deleted records in this table that was exported last.'; + ToolTip = 'Specifies the timestamp of the deleted records in this table that was exported last.'; Caption = 'Last timestamp deleted'; Visible = false; } @@ -97,7 +96,7 @@ page 82561 "ADLSE Setup Tables" { ApplicationArea = All; Caption = 'Add'; - Tooltip = 'Add a table to be exported'; + ToolTip = 'Add a table to be exported.'; Image = New; Enabled = NoExportInProgress; @@ -114,7 +113,7 @@ page 82561 "ADLSE Setup Tables" { ApplicationArea = All; Caption = 'Delete'; - Tooltip = 'Removes a table that had been added to the list meant for export'; + ToolTip = 'Removes a table that had been added to the list meant for export.'; Image = Delete; Enabled = NoExportInProgress; @@ -129,7 +128,7 @@ page 82561 "ADLSE Setup Tables" { ApplicationArea = All; Caption = 'Choose fields'; - ToolTip = 'Select the fields of this table to be exported'; + ToolTip = 'Select the fields of this table to be exported.'; Image = SelectEntries; Enabled = NoExportInProgress; @@ -233,7 +232,7 @@ page 82561 "ADLSE Setup Tables" UpdatedLastTimestamp := 0; DeletedRecordLastEntryNo := 0; ADLSEntityName := ''; - Rec.Modify(); + Rec.Modify(true); end; ADLSERun.GetLastRunDetails(Rec."Table ID", LastRunState, LastStarted, LastRunError); diff --git a/businessCentral/app/src/StorageType.Enum.al b/businessCentral/app/src/StorageType.Enum.al index d52bbee..c6066b7 100644 --- a/businessCentral/app/src/StorageType.Enum.al +++ b/businessCentral/app/src/StorageType.Enum.al @@ -3,6 +3,14 @@ enum 82563 "ADLSE Storage Type" Access = Internal; Extensible = false; - value(0; "Azure Data Lake") { } - value(1; "Microsoft Fabric") { } +#pragma warning disable LC0045 + value(0; "Azure Data Lake") + { + Caption = 'Azure Data Lake'; + } +#pragma warning restore LC0045 + value(1; "Microsoft Fabric") + { + Caption = 'Microsoft Fabric'; + } } \ No newline at end of file diff --git a/businessCentral/app/src/Table.Table.al b/businessCentral/app/src/Table.Table.al index c5c9d98..cc5625a 100644 --- a/businessCentral/app/src/Table.Table.al +++ b/businessCentral/app/src/Table.Table.al @@ -1,15 +1,22 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma warning disable LC0015 table 82561 "ADLSE Table" +#pragma warning restore { Access = Internal; + Caption = 'ADLSE Table'; DataClassification = CustomerContent; DataPerCompany = false; + Permissions = tabledata "ADLSE Field" = rd, + tabledata "ADLSE Table Last Timestamp" = d, + tabledata "ADLSE Deleted Record" = d; fields { field(1; "Table ID"; Integer) { + AllowInCustomizations = Always; Editable = false; Caption = 'Table ID'; } @@ -24,6 +31,7 @@ table 82561 "ADLSE Table" { Editable = false; Caption = 'Enabled'; + ToolTip = 'Specifies the state of the table. Set this checkmark to export this table, otherwise not.'; trigger OnValidate() var @@ -78,13 +86,13 @@ table 82561 "ADLSE Table" ADLSESetup.SchemaExported(); ADLSETableField.SetRange("Table ID", Rec."Table ID"); - ADLSETableField.DeleteAll(); + ADLSETableField.DeleteAll(false); ADLSEDeletedRecord.SetRange("Table ID", Rec."Table ID"); - ADLSEDeletedRecord.DeleteAll(); + ADLSEDeletedRecord.DeleteAll(false); ADLSETableLastTimestamp.SetRange("Table ID", Rec."Table ID"); - ADLSETableLastTimestamp.DeleteAll(); + ADLSETableLastTimestamp.DeleteAll(false); ADLSEExternalEvents.OnDeleteTable(Rec); end; @@ -114,6 +122,7 @@ table 82561 "ADLSE Table" exit(ADLSEField.Count()); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'i')] procedure Add(TableID: Integer) var ADLSEExternalEvents: Codeunit "ADLSE External Events"; @@ -160,10 +169,10 @@ table 82561 "ADLSE Table" Error(TableExportingDataErr, ADLSEUtil.GetTableCaption(Rec."Table ID")); end; - local procedure GetLastRunState(): enum "ADLSE Run State" + local procedure GetLastRunState(): Enum "ADLSE Run State" var ADLSERun: Record "ADLSE Run"; - LastState: enum "ADLSE Run State"; + LastState: Enum "ADLSE Run State"; LastStarted: DateTime; LastErrorText: Text[2048]; begin @@ -171,6 +180,7 @@ table 82561 "ADLSE Table" exit(LastState); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table", 'rm')] procedure ResetSelected() var ADLSEDeletedRecord: Record "ADLSE Deleted Record"; @@ -183,14 +193,14 @@ table 82561 "ADLSE Table" repeat if not Rec.Enabled then begin Rec.Enabled := true; - Rec.Modify(); + Rec.Modify(true); end; ADLSETableLastTimestamp.SaveUpdatedLastTimestamp(Rec."Table ID", 0); ADLSETableLastTimestamp.SaveDeletedLastEntryNo(Rec."Table ID", 0); ADLSEDeletedRecord.SetRange("Table ID", Rec."Table ID"); - ADLSEDeletedRecord.DeleteAll(); + ADLSEDeletedRecord.DeleteAll(false); ADLSESetup.GetSingleton(); if (ADLSESetup."Delete Table") then @@ -206,6 +216,7 @@ table 82561 "ADLSE Table" Message(TablesResetTxt, Counter, '.'); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Field", 'r')] local procedure CheckExportingOnlyValidFields() var ADLSEField: Record "ADLSE Field"; @@ -221,6 +232,7 @@ table 82561 "ADLSE Table" until ADLSEField.Next() = 0; end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Field", 'r')] procedure ListInvalidFieldsBeingExported() FieldList: List of [Text] var ADLSEField: Record "ADLSE Field"; @@ -247,6 +259,7 @@ table 82561 "ADLSE Table" end; end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Field", 'rm')] procedure AddAllFields() var ADLSEFields: Record "ADLSE Field"; @@ -257,13 +270,13 @@ table 82561 "ADLSE Table" repeat if (ADLSEFields.CanFieldBeEnabled()) then begin ADLSEFields.Enabled := true; - ADLSEFields.Modify(); + ADLSEFields.Modify(true); end; until ADLSEFields.Next() = 0; end; [IntegrationEvent(false, false)] - local procedure OnAfterResetSelected(ADLSETable: record "ADLSE Table") + local procedure OnAfterResetSelected(ADLSETable: Record "ADLSE Table") begin end; diff --git a/businessCentral/app/src/TableAPI.Page.al b/businessCentral/app/src/TableAPI.Page.al index af0e88a..456a78c 100644 --- a/businessCentral/app/src/TableAPI.Page.al +++ b/businessCentral/app/src/TableAPI.Page.al @@ -30,16 +30,22 @@ page 82565 "ADLSE Table API" { Editable = false; } +#pragma warning disable LC0016 field(systemRowVersion; Rec.SystemRowVersion) { Editable = false; } +#pragma warning restore + field(lastModifiedDateTime; Rec.SystemModifiedAt) + { + Editable = false; + } } part(adlseField; "ADLSE Field API") { EntityName = 'adlseField'; EntitySetName = 'adlseFields'; - SubPageLink = "Table ID" = Field("Table ID"); + SubPageLink = "Table ID" = field("Table ID"); } } } @@ -85,7 +91,7 @@ page 82565 "ADLSE Table API" [ServiceEnabled] procedure AddAllFields(var ActionContext: WebServiceActionContext) begin - rec.AddAllFields(); + Rec.AddAllFields(); SetActionResponse(ActionContext, Rec.SystemId); end; diff --git a/businessCentral/app/src/TableLastTimestamp.Table.al b/businessCentral/app/src/TableLastTimestamp.Table.al index c46e295..4756992 100644 --- a/businessCentral/app/src/TableLastTimestamp.Table.al +++ b/businessCentral/app/src/TableLastTimestamp.Table.al @@ -8,6 +8,7 @@ table 82564 "ADLSE Table Last Timestamp" /// Access = Internal; + Caption = 'ADLSE Table Last Timestamp'; DataClassification = CustomerContent; DataPerCompany = false; @@ -49,6 +50,7 @@ table 82564 "ADLSE Table Last Timestamp" SaveUpsertLastTimestampFailedErr: Label 'Could not save the last time stamp for the upserts on table %1.', Comment = '%1: table caption'; SaveDeletionLastTimestampFailedErr: Label 'Could not save the last time stamp for the deletions on table %1.', Comment = '%1: table caption'; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table Last Timestamp", 'r')] procedure ExistsUpdatedLastTimestamp(TableID: Integer): Boolean begin exit(Rec.Get(GetCompanyNameToLookFor(TableID), TableID)); @@ -60,6 +62,7 @@ table 82564 "ADLSE Table Last Timestamp" exit(Rec."Updated Last Timestamp"); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table Last Timestamp", 'r')] procedure GetDeletedLastEntryNo(TableID: Integer): BigInteger begin if Rec.Get(GetCompanyNameToLookFor(TableID), TableID) then @@ -112,6 +115,7 @@ table 82564 "ADLSE Table Last Timestamp" exit(RecordLastTimestamp(TableID, Timestamp, false)); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Table Last Timestamp", 'rmi')] local procedure RecordLastTimestamp(TableID: Integer; Timestamp: BigInteger; Upsert: Boolean): Boolean var Company: Text; @@ -119,13 +123,13 @@ table 82564 "ADLSE Table Last Timestamp" Company := GetCompanyNameToLookFor(TableID); if Rec.Get(Company, TableID) then begin ChangeLastTimestamp(Timestamp, Upsert); - exit(Rec.Modify()); + exit(Rec.Modify(true)); end else begin Rec.Init(); Rec."Company Name" := CopyStr(Company, 1, 30); Rec."Table ID" := TableID; ChangeLastTimestamp(Timestamp, Upsert); - exit(Rec.Insert()); + exit(Rec.Insert(true)); end; end; diff --git a/businessCentral/app/src/Upgrade.Codeunit.al b/businessCentral/app/src/Upgrade.Codeunit.al index dee4875..d9e6deb 100644 --- a/businessCentral/app/src/Upgrade.Codeunit.al +++ b/businessCentral/app/src/Upgrade.Codeunit.al @@ -61,6 +61,7 @@ codeunit 82572 "ADLSE Upgrade" Result += StrSubstNo(TableFieldsTok, ADLSEUtil.GetTableCaption(TableID), ADLSEUtil.Concatenate(TableIDFieldNameList.Get(TableID))); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Setup", 'm')] local procedure DoContainerFieldFromIsolatedStorageToSetupField() var ADLSESetup: Record "ADLSE Setup"; @@ -69,7 +70,9 @@ codeunit 82572 "ADLSE Upgrade" begin if not IsolatedStorage.Contains(StorageAccountKeyNameTok, DataScope::Module) then exit; +#pragma warning disable LC0043 IsolatedStorage.Get(StorageAccountKeyNameTok, DataScope::Module, AccountName); +#pragma warning restore LC0043 if not ADLSESetup.Exists() then exit; @@ -93,6 +96,7 @@ codeunit 82572 "ADLSE Upgrade" UpgradeTag.SetUpgradeTag(GetSeperateSchemaAndDataUpgradeTag()); end; + [InherentPermissions(PermissionObjectType::TableData, Database::"ADLSE Setup", 'm')] local procedure DoGetSeperateSchemaAndData() var ADLSESetup: Record "ADLSE Setup"; @@ -103,7 +107,7 @@ codeunit 82572 "ADLSE Upgrade" if ADLSESetup."Multi- Company Export" then begin ADLSESetup."Schema Exported On" := CurrentDateTime(); - ADLSESetup.Modify(); + ADLSESetup.Modify(true); end; end; diff --git a/businessCentral/app/src/UpgradeTagNewCompanySubs.Codeunit.al b/businessCentral/app/src/UpgradeTagNewCompanySubs.Codeunit.al index 77640db..155eb5f 100644 --- a/businessCentral/app/src/UpgradeTagNewCompanySubs.Codeunit.al +++ b/businessCentral/app/src/UpgradeTagNewCompanySubs.Codeunit.al @@ -5,8 +5,8 @@ codeunit 82575 "ADLSE UpgradeTagNewCompanySubs" Access = Internal; [InherentPermissions(PermissionObjectType::Codeunit, Codeunit::"ADLSE Upgrade", 'X')] - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", 'OnGetPerCompanyUpgradeTags', '', false, false)] - local procedure OnGetPerCompanyTags(var PerCompanyUpgradeTags: List of [Code[250]]); + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", OnGetPerCompanyUpgradeTags, '', false, false)] + local procedure OnGetPerCompanyTags(var PerCompanyUpgradeTags: List of [Code[250]]) var ADLSEUpgrade: Codeunit "ADLSE Upgrade"; begin diff --git a/businessCentral/app/src/Util.Codeunit.al b/businessCentral/app/src/Util.Codeunit.al index cc41e36..e3d1dd3 100644 --- a/businessCentral/app/src/Util.Codeunit.al +++ b/businessCentral/app/src/Util.Codeunit.al @@ -9,13 +9,13 @@ codeunit 82564 "ADLSE Util" AlphabetsUpperTxt: Label 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; NumeralsTxt: Label '1234567890'; FieldTypeNotSupportedErr: Label 'The field %1 of type %2 is not supported.', Comment = '%1 = field name, %2 = field type'; - ConcatNameIdTok: Label '%1-%2', Comment = '%1: Name, %2: ID'; - DateTimeExpandedFormatTok: Label '%1, %2 %3 %4 %5:%6:%7 GMT', Comment = '%1: weekday, %2: day, %3: month, %4: year, %5: hour, %6: minute, %7: second'; - QuotedTextTok: Label '"%1"', Comment = '%1: text to be double- quoted'; - CommaPrefixedTok: Label ',%1', Comment = '%1: text to be prefixed'; - CommaSuffixedTok: Label '%1, ', Comment = '%1: text to be suffixed'; - WholeSecondsTok: Label ':%1Z', Comment = '%1: seconds'; - FractionSecondsTok: Label ':%1.%2Z', Comment = '%1: seconds, %2: milliseconds'; + ConcatNameIdTok: Label '%1-%2', Comment = '%1: Name, %2: ID', Locked = true; + DateTimeExpandedFormatTok: Label '%1, %2 %3 %4 %5:%6:%7 GMT', Comment = '%1: weekday, %2: day, %3: month, %4: year, %5: hour, %6: minute, %7: second', Locked = true; + QuotedTextTok: Label '"%1"', Comment = '%1: text to be double- quoted', Locked = true; + CommaPrefixedTok: Label ',%1', Comment = '%1: text to be prefixed', Locked = true; + CommaSuffixedTok: Label '%1, ', Comment = '%1: text to be suffixed', Locked = true; + WholeSecondsTok: Label ':%1Z', Comment = '%1: seconds', Locked = true; + FractionSecondsTok: Label ':%1.%2Z', Comment = '%1: seconds, %2: milliseconds', Locked = true; procedure ToText(GuidValue: Guid): Text begin