diff --git a/src/System Application/App/Translation/src/Translation.Codeunit.al b/src/System Application/App/Translation/src/Translation.Codeunit.al index 66f787ef16..0a84b8c104 100644 --- a/src/System Application/App/Translation/src/Translation.Codeunit.al +++ b/src/System Application/App/Translation/src/Translation.Codeunit.al @@ -195,4 +195,17 @@ codeunit 3711 Translation begin TranslationImplementation.ShowForAllRecords(TableId, FieldId); end; -} + + /// + /// Gets all available translations for a record into a temporary buffer. + /// If FieldId is 0, it retrieves translations for all fields. + /// + /// Source record variant + /// Field ID to get translations for. Use 0 to retrieve translations for all fields. + /// Output: Temporary buffer with translations + /// True if translations were found + procedure GetTranslations(RecVariant: Variant; FieldId: Integer; var TranslationBuffer: Record "Translation Buffer"): Boolean + begin + exit(TranslationImplementation.GetTranslations(RecVariant, FieldId, TranslationBuffer)); + end; +} \ No newline at end of file diff --git a/src/System Application/App/Translation/src/TranslationBuffer.Table.al b/src/System Application/App/Translation/src/TranslationBuffer.Table.al new file mode 100644 index 0000000000..21839020a3 --- /dev/null +++ b/src/System Application/App/Translation/src/TranslationBuffer.Table.al @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace System.Globalization; + +table 3713 "Translation Buffer" +{ + Access = Public; + Caption = 'Translation Buffer'; + InherentEntitlements = X; + InherentPermissions = X; + TableType = Temporary; + + fields + { + field(1; "Language ID"; Integer) + { + DataClassification = SystemMetadata; + Caption = 'Language ID'; + TableRelation = Language."Windows Language ID"; + } + field(2; "System ID"; Guid) + { + DataClassification = SystemMetadata; + Caption = 'System ID'; + Editable = false; + } + field(3; "Table ID"; Integer) + { + DataClassification = SystemMetadata; + Caption = 'Table ID'; + Editable = false; + } + field(4; "Field ID"; Integer) + { + DataClassification = SystemMetadata; + Caption = 'Field ID'; + Editable = false; + } + field(5; Value; Text[2048]) + { + DataClassification = CustomerContent; + Caption = 'Value'; + } + } + + keys + { + key(Key1; "Language ID", "System ID", "Field ID") + { + Clustered = true; + } + key(Key2; "Table ID", "Field ID") + { + } + } +} \ No newline at end of file diff --git a/src/System Application/App/Translation/src/TranslationImplementation.Codeunit.al b/src/System Application/App/Translation/src/TranslationImplementation.Codeunit.al index 9f665c89d8..d97e6b1e57 100644 --- a/src/System Application/App/Translation/src/TranslationImplementation.Codeunit.al +++ b/src/System Application/App/Translation/src/TranslationImplementation.Codeunit.al @@ -183,6 +183,29 @@ codeunit 3712 "Translation Implementation" Error(MaxLenghtErr, Translation.Value, StrLen(Translation.Value), Field.Len); end; + procedure GetTranslations(RecVariant: Variant; FieldId: Integer; var TranslationBuffer: Record "Translation Buffer"): Boolean + var + Translation: Record Translation; + FromRecordRef: RecordRef; + begin + TranslationBuffer.Reset(); + TranslationBuffer.DeleteAll(); + + GetRecordRefFromVariant(RecVariant, FromRecordRef); + Translation.SetRange("System ID", GetSystemIdFromRecordRef(FromRecordRef)); + Translation.SetRange("Table ID", FromRecordRef.Number()); + if FieldId <> 0 then + Translation.SetRange("Field ID", FieldId); + if Translation.FindSet() then + repeat + TranslationBuffer.Init(); + TranslationBuffer.TransferFields(Translation); + TranslationBuffer.Insert(); + until Translation.Next() = 0; + + exit(TranslationBuffer.FindFirst()); + end; + local procedure GetRecordIdCaptionFromVariant(RecVariant: Variant): Text var RecordId: RecordId; @@ -225,4 +248,4 @@ codeunit 3712 "Translation Implementation" Error(NoRecordIdErr); end; -} +} \ No newline at end of file diff --git a/src/System Application/Test/Translation/src/TranslationTests.Codeunit.al b/src/System Application/Test/Translation/src/TranslationTests.Codeunit.al index c545562c24..1ca9c14171 100644 --- a/src/System Application/Test/Translation/src/TranslationTests.Codeunit.al +++ b/src/System Application/Test/Translation/src/TranslationTests.Codeunit.al @@ -480,6 +480,189 @@ codeunit 137121 "Translation Tests" Assert.ExpectedError(CannotTranslateTempRecErr); end; + [Test] + [Scope('OnPrem')] + procedure GetTranslationsForOneFieldFromRecord() + var + TranslationTestTable: Record "Translation Test Table"; + TranslationBuffer: Record "Translation Buffer"; + begin + // [SCENARIO] Translation must be retrieved correctly for one field + + Initialize(); + PermissionsMock.Set(TranslationEditRoleTok); + + // [GIVEN] Create a record in TableA and set a translation for the fields FieldA and FieldB + CreateRecord(TranslationTestTable); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(TextField), Text1Txt); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(TextField), GetDanishLanguageId(), Text2Txt); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(SecondTextField), Text3Txt); + + // [WHEN] Translations are retrieved for a specific field + Assert.IsTrue( + Translation.GetTranslations(TranslationTestTable, TranslationTestTable.FieldNo(TextField), TranslationBuffer), + 'GetTranslations should return true when translations exist'); + + // [THEN] Verify that only translations for the requested field are returned + Assert.AreEqual(2, TranslationBuffer.Count(), 'Should have 2 translations for the TextField'); + + // [THEN] Verify the translation values + TranslationBuffer.SetRange("Language ID", GetEnglishLanguageId()); + Assert.IsTrue(TranslationBuffer.FindFirst(), 'English translation should exist'); + Assert.AreEqual(Text1Txt, TranslationBuffer.Value, 'Incorrect English translation value'); + Assert.AreEqual(TranslationTestTable.FieldNo(TextField), TranslationBuffer."Field ID", 'Incorrect Field ID'); + Assert.AreEqual(TranslationTestTable.SystemId, TranslationBuffer."System ID", 'Incorrect System ID'); + + TranslationBuffer.SetRange("Language ID", GetDanishLanguageId()); + Assert.IsTrue(TranslationBuffer.FindFirst(), 'Danish translation should exist'); + Assert.AreEqual(Text2Txt, TranslationBuffer.Value, 'Incorrect Danish translation value'); + + // [THEN] Verify no translations for SecondTextField are included + TranslationBuffer.SetRange("Language ID"); + TranslationBuffer.SetRange("Field ID", TranslationTestTable.FieldNo(SecondTextField)); + Assert.IsTrue(TranslationBuffer.IsEmpty(), 'No translations for SecondTextField should be returned'); + end; + + [Test] + [Scope('OnPrem')] + procedure GetTranslationsForAllFieldsFromRecord() + var + TranslationTestTable: Record "Translation Test Table"; + TranslationBuffer: Record "Translation Buffer"; + begin + // [SCENARIO] Translation must be retrieved correctly for all fields when FieldId is 0 + + Initialize(); + PermissionsMock.Set(TranslationEditRoleTok); + + // [GIVEN] Create a record in TableA and set a translation for the fields FieldA and FieldB + CreateRecord(TranslationTestTable); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(TextField), Text1Txt); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(TextField), GetDanishLanguageId(), Text2Txt); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(SecondTextField), Text3Txt); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(SecondTextField), GetFrenchLanguageId(), Text4Txt); + + // [WHEN] Translations are retrieved for all fields (FieldId = 0) + Assert.IsTrue( + Translation.GetTranslations(TranslationTestTable, 0, TranslationBuffer), + 'GetTranslations should return true when translations exist'); + + // [THEN] Verify that translations for all fields are returned + Assert.AreEqual(4, TranslationBuffer.Count(), 'Should have 4 translations total (2 fields x 2 languages each)'); + + // [THEN] Verify TextField translations + TranslationBuffer.SetRange("Field ID", TranslationTestTable.FieldNo(TextField)); + Assert.AreEqual(2, TranslationBuffer.Count(), 'Should have 2 translations for TextField'); + + TranslationBuffer.SetRange("Language ID", GetEnglishLanguageId()); + Assert.IsTrue(TranslationBuffer.FindFirst(), 'English translation for TextField should exist'); + Assert.AreEqual(Text1Txt, TranslationBuffer.Value, 'Incorrect English translation for TextField'); + + TranslationBuffer.SetRange("Language ID", GetDanishLanguageId()); + Assert.IsTrue(TranslationBuffer.FindFirst(), 'Danish translation for TextField should exist'); + Assert.AreEqual(Text2Txt, TranslationBuffer.Value, 'Incorrect Danish translation for TextField'); + + // [THEN] Verify SecondTextField translations + TranslationBuffer.SetRange("Language ID"); + TranslationBuffer.SetRange("Field ID", TranslationTestTable.FieldNo(SecondTextField)); + Assert.AreEqual(2, TranslationBuffer.Count(), 'Should have 2 translations for SecondTextField'); + + TranslationBuffer.SetRange("Language ID", GetEnglishLanguageId()); + Assert.IsTrue(TranslationBuffer.FindFirst(), 'English translation for SecondTextField should exist'); + Assert.AreEqual(Text3Txt, TranslationBuffer.Value, 'Incorrect English translation for SecondTextField'); + + TranslationBuffer.SetRange("Language ID", GetFrenchLanguageId()); + Assert.IsTrue(TranslationBuffer.FindFirst(), 'French translation for SecondTextField should exist'); + Assert.AreEqual(Text4Txt, TranslationBuffer.Value, 'Incorrect French translation for SecondTextField'); + end; + + [Test] + [Scope('OnPrem')] + procedure GetTranslationsNoTranslationsExist() + var + TranslationTestTable: Record "Translation Test Table"; + TranslationBuffer: Record "Translation Buffer"; + begin + // [SCENARIO] GetTranslations returns false when no translations exist + + Initialize(); + PermissionsMock.Set(TranslationEditRoleTok); + + // [GIVEN] Create a record without any translations + CreateRecord(TranslationTestTable); + + // [WHEN] Translations are retrieved + // [THEN] GetTranslations should return false + Assert.IsFalse( + Translation.GetTranslations(TranslationTestTable, TranslationTestTable.FieldNo(TextField), TranslationBuffer), + 'GetTranslations should return false when no translations exist'); + + // [THEN] Buffer should be empty + Assert.IsTrue(TranslationBuffer.IsEmpty(), 'Translation buffer should be empty'); + end; + + [Test] + [Scope('OnPrem')] + procedure GetTranslationsWithRecordRef() + var + TranslationTestTable: Record "Translation Test Table"; + TranslationBuffer: Record "Translation Buffer"; + RecRef: RecordRef; + begin + // [SCENARIO] GetTranslations works correctly with RecordRef variant + + Initialize(); + PermissionsMock.Set(TranslationEditRoleTok); + + // [GIVEN] Create a record and set translations + CreateRecord(TranslationTestTable); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(TextField), Text1Txt); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(TextField), GetDanishLanguageId(), Text2Txt); + + // [GIVEN] Get RecordRef from the record + RecRef.GetTable(TranslationTestTable); + + // [WHEN] Translations are retrieved using RecordRef + Assert.IsTrue( + Translation.GetTranslations(RecRef, TranslationTestTable.FieldNo(TextField), TranslationBuffer), + 'GetTranslations should work with RecordRef'); + + // [THEN] Verify translations are returned correctly + Assert.AreEqual(2, TranslationBuffer.Count(), 'Should have 2 translations'); + + TranslationBuffer.SetRange("Language ID", GetEnglishLanguageId()); + Assert.IsTrue(TranslationBuffer.FindFirst(), 'English translation should exist'); + Assert.AreEqual(Text1Txt, TranslationBuffer.Value, 'Incorrect English translation value'); + end; + + [Test] + [Scope('OnPrem')] + procedure GetTranslationsBufferContainsCorrectMetadata() + var + TranslationTestTable: Record "Translation Test Table"; + TranslationBuffer: Record "Translation Buffer"; + begin + // [SCENARIO] Translation Buffer contains correct metadata fields + + Initialize(); + PermissionsMock.Set(TranslationEditRoleTok); + + // [GIVEN] Create a record and set a translation + CreateRecord(TranslationTestTable); + Translation.Set(TranslationTestTable, TranslationTestTable.FieldNo(TextField), GetDanishLanguageId(), Text2Txt); + + // [WHEN] Translations are retrieved + Translation.GetTranslations(TranslationTestTable, TranslationTestTable.FieldNo(TextField), TranslationBuffer); + + // [THEN] Verify all metadata fields are populated correctly + Assert.IsTrue(TranslationBuffer.FindFirst(), 'Translation should exist'); + Assert.AreEqual(GetDanishLanguageId(), TranslationBuffer."Language ID", 'Incorrect Language ID'); + Assert.AreEqual(TranslationTestTable.SystemId, TranslationBuffer."System ID", 'Incorrect System ID'); + Assert.AreEqual(Database::"Translation Test Table", TranslationBuffer."Table ID", 'Incorrect Table ID'); + Assert.AreEqual(TranslationTestTable.FieldNo(TextField), TranslationBuffer."Field ID", 'Incorrect Field ID'); + Assert.AreEqual(Text2Txt, TranslationBuffer.Value, 'Incorrect translation value'); + end; + local procedure Initialize() var TranslationTestTable: Record "Translation Test Table";