From 302e4bff32fd0585e12eade2b8cec79a746a74f6 Mon Sep 17 00:00:00 2001 From: Matti Andreas Nielsen Date: Thu, 18 Apr 2024 11:24:21 +0200 Subject: [PATCH] Add GetCollectionType to Edit-In Excel API (#550) #### Summary The issue We have received this issue: https://github.com/microsoft/ALAppExtensions/issues/21940 where the programmer wants to move all of the filters from one field to another. The only thing missing for this capability is that we should be able to dynamically detect if the filter is a AND or OR expression, this is not possible in the current implementation. Expected behavior We should expose the "Edit in Excel Filter Collection Type" property on the filter through the API, such that clients of the API can dynamically detect what collection type the filter has. #### Work Item(s) Fixes [AB#498510](https://dynamicssmb2.visualstudio.com/Dynamics%20SMB/_workitems/edit/498510/) --------- Co-authored-by: Matti Nielsen --- .../EditInExcelFieldFilter.Interface.al | 8 +++ .../EditInExcelFieldFilterv2.Interface.al | 47 ++++++++++++++ .../Filters/EditInExcelFilters.Codeunit.al | 63 +++++++++++++++++++ .../EditInExcelFiltersImpl.Codeunit.al | 10 +-- .../EditInExcelFldFilterImpl.Codeunit.al | 36 +++++++++-- .../src/EditInExcelFiltersTest.Codeunit.al | 38 +++++++++++ .../src/EditInExcelTest.Codeunit.al | 2 +- 7 files changed, 194 insertions(+), 10 deletions(-) create mode 100644 src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilterv2.Interface.al diff --git a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilter.Interface.al b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilter.Interface.al index b9ee590af2..fcbfb9dbde 100644 --- a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilter.Interface.al +++ b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilter.Interface.al @@ -1,3 +1,4 @@ +#if not CLEAN25 // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -12,12 +13,18 @@ interface "Edit in Excel Field Filter" { Access = Public; + ObsoleteState = Pending; + ObsoleteTag = '25.0'; + ObsoleteReason = 'Replaced by "Edit in Excel Field Filter v2" with support for getting the collection type of the filter.'; + /// /// Add a filter value /// /// The filter type, such as Equal, Greater than. /// The value which the field should be Equal to, Greater than etc. +#pragma warning disable AL0432 procedure AddFilterValue(EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text): Interface "Edit in Excel Field Filter" +#pragma warning restore AL0432 /// /// Get a specific filter @@ -39,3 +46,4 @@ interface "Edit in Excel Field Filter" /// The number of filters procedure Count(): Integer } +#endif \ No newline at end of file diff --git a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilterv2.Interface.al b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilterv2.Interface.al new file mode 100644 index 0000000000..412b12cb0e --- /dev/null +++ b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFieldFilterv2.Interface.al @@ -0,0 +1,47 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace System.Integration.Excel; + +/// +/// This codeunit provides an interface to create a filter for a specific field for Edit in Excel. +/// +interface "Edit in Excel Field Filter v2" +{ + Access = Public; + + /// + /// Add a filter value + /// + /// The filter type, such as Equal, Greater than. + /// The value which the field should be Equal to, Greater than etc. + procedure AddFilterValueV2(EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text): Interface "Edit in Excel Field Filter v2" + + /// + /// Get a specific filter + /// + /// The index of the filter. + /// The filter type, such as Equal, Greater than. + /// The value which the field should be Equal to, Greater than etc. + procedure Get(Index: Integer; var EditinExcelFilterType: Enum "Edit in Excel Filter Type"; var FilterValue: Text) + + /// + /// Get the filter collection type + /// + /// The collection type of the filter + procedure GetCollectionType(): Enum "Edit in Excel Filter Collection Type" + + /// + /// Remove a specific filter + /// + /// The index of the filter. + procedure Remove(Index: Integer) + + /// + /// Counts the number of filters + /// + /// The number of filters + procedure Count(): Integer +} diff --git a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFilters.Codeunit.al b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFilters.Codeunit.al index 9c729fde32..693aca0ba6 100644 --- a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFilters.Codeunit.al +++ b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFilters.Codeunit.al @@ -19,27 +19,60 @@ codeunit 1490 "Edit in Excel Filters" var EditinExcelFiltersImpl: Codeunit "Edit in Excel Filters Impl."; + +#if not CLEAN25 /// /// Add the specified field using 'and' collection type. /// /// The OData name of the field referenced. /// The Edm type of the OData field as specified in the $metadata document. + [Obsolete('Use AddFieldV2 instead.', '25.0')] +#pragma warning disable AL0432 procedure AddField(ODataFieldName: Text; EditInExcelEdmType: Enum "Edit in Excel Edm Type"): Interface "Edit in Excel Field Filter" +#pragma warning restore AL0432 begin exit(EditinExcelFiltersImpl.AddField(ODataFieldName, "Edit in Excel Filter Collection Type"::"and", EditInExcelEdmType)); end; +#endif + /// + /// Add the specified field using 'and' collection type. + /// + /// The OData name of the field referenced. + /// The Edm type of the OData field as specified in the $metadata document. + procedure AddFieldV2(ODataFieldName: Text; EditInExcelEdmType: Enum "Edit in Excel Edm Type"): Interface "Edit in Excel Field Filter v2" + begin + exit(EditinExcelFiltersImpl.AddField(ODataFieldName, "Edit in Excel Filter Collection Type"::"and", EditInExcelEdmType)); + end; + +#if not CLEAN25 /// /// Add the specified field with a specified collection type. /// /// The OData name of the field referenced. /// Specifies whether filters for this field have 'and' or 'or', such as Field1 = a|b|c (or operator) or Field1 = <a&>b>amp;>c (and operator). Both operators for the same field is currently not supported. /// The Edm type of the OData field as specified in the $metadata document. + [Obsolete('Use AddFieldV2 instead.', '25.0')] +#pragma warning disable AL0432 procedure AddField(ODataFieldName: Text; EditInExcelFilterOperatorType: Enum "Edit in Excel Filter Collection Type"; EditInExcelEdmType: Enum "Edit in Excel Edm Type"): Interface "Edit in Excel Field Filter" +#pragma warning restore AL0432 begin exit(EditinExcelFiltersImpl.AddField(ODataFieldName, EditInExcelFilterOperatorType, EditInExcelEdmType)); end; +#endif + /// + /// Add the specified field with a specified collection type. + /// + /// The OData name of the field referenced. + /// Specifies whether filters for this field have 'and' or 'or', such as Field1 = a|b|c (or operator) or Field1 = <a&>b>amp;>c (and operator). Both operators for the same field is currently not supported. + /// The Edm type of the OData field as specified in the $metadata document. + procedure AddFieldV2(ODataFieldName: Text; EditInExcelFilterOperatorType: Enum "Edit in Excel Filter Collection Type"; EditInExcelEdmType: Enum "Edit in Excel Edm Type"): Interface "Edit in Excel Field Filter V2" + begin + exit(EditinExcelFiltersImpl.AddField(ODataFieldName, EditInExcelFilterOperatorType, EditInExcelEdmType)); + end; + +#if not CLEAN25 /// /// Add the specified field with an initial value using 'and' collection type. /// This is mainly intended for fields that only filter on a single value. @@ -48,17 +81,47 @@ codeunit 1490 "Edit in Excel Filters" /// The filter type, such as Equal, Greater than etc. /// The value which the field should be Equal to, Greater than etc. /// The Edm type of the OData field as specified in the $metadata document. + [Obsolete('Use AddFieldV2 instead.', '25.0')] procedure AddField(ODataFieldName: Text; EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text; EditInExcelEdmType: Enum "Edit in Excel Edm Type") begin EditinExcelFiltersImpl.AddField(ODataFieldName, EditInExcelFilterType, FilterValue, EditInExcelEdmType); end; +#endif + /// + /// Add the specified field with an initial value using 'and' collection type. + /// This is mainly intended for fields that only filter on a single value. + /// + /// The OData name of the field referenced. + /// The filter type, such as Equal, Greater than etc. + /// The value which the field should be Equal to, Greater than etc. + /// The Edm type of the OData field as specified in the $metadata document. + procedure AddFieldV2(ODataFieldName: Text; EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text; EditInExcelEdmType: Enum "Edit in Excel Edm Type") + begin + EditinExcelFiltersImpl.AddField(ODataFieldName, EditInExcelFilterType, FilterValue, EditInExcelEdmType); + end; + +#if not CLEAN25 /// /// Get the field filters for the specified field. /// /// The OData name of the field referenced. /// + [Obsolete('Use GetV2 instead.', '25.0')] +#pragma warning disable AL0432 procedure Get(ODataFieldName: Text): Interface "Edit in Excel Field Filter" +#pragma warning restore AL0432 + begin + exit(EditinExcelFiltersImpl.Get(ODataFieldName)); + end; +#endif + + /// + /// Get the field filters for the specified field. + /// + /// The OData name of the field referenced. + /// + procedure GetV2(ODataFieldName: Text): Interface "Edit in Excel Field Filter V2" begin exit(EditinExcelFiltersImpl.Get(ODataFieldName)); end; diff --git a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFiltersImpl.Codeunit.al b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFiltersImpl.Codeunit.al index ac3227e5b9..0751ca2313 100644 --- a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFiltersImpl.Codeunit.al +++ b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFiltersImpl.Codeunit.al @@ -33,19 +33,19 @@ codeunit 1491 "Edit in Excel Filters Impl." FilterContainsMultipleOperatorsTxt: Label 'The page filter contains multiple operators, the latter was removed.', Locked = true; FieldPayloadEdmTypeTok: Label 'fieldPayload.%1.edmType', Locked = true; - procedure AddField(ODataFieldName: Text; EditinExcelFilterCollectionType: Enum "Edit in Excel Filter Collection Type"; EditInExcelEdmType: Enum "Edit in Excel Edm Type"): Interface "Edit in Excel Field Filter" + procedure AddField(ODataFieldName: Text; EditinExcelFilterCollectionType: Enum "Edit in Excel Filter Collection Type"; EditInExcelEdmType: Enum "Edit in Excel Edm Type"): Codeunit "Edit in Excel Fld Filter Impl." begin TryAdd(ODataFieldName, EditinExcelFilterCollectionType, Format(EditInExcelEdmType)); exit(Get(ODataFieldName)); end; - procedure AddField(ODataFieldName: Text; EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text; EditInExcelEdmType: Enum "Edit in Excel Edm Type") EditinExcelFieldFilter: Interface "Edit in Excel Field Filter" + procedure AddField(ODataFieldName: Text; EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text; EditInExcelEdmType: Enum "Edit in Excel Edm Type") EditinExcelFieldFilter: Codeunit "Edit in Excel Fld Filter Impl." begin EditinExcelFieldFilter := AddField(ODataFieldName, "Edit in Excel Filter Collection Type"::"and", EditInExcelEdmType); - Get(ODataFieldName).AddFilterValue(EditInExcelFilterType, FilterValue); + Get(ODataFieldName).AddFilterValueV2(EditInExcelFilterType, FilterValue); end; - procedure Get(ODataFieldName: Text): Interface "Edit in Excel Field Filter" + procedure Get(ODataFieldName: Text): Codeunit "Edit in Excel Fld Filter Impl." var EditinExcelFldFilterImpl: Codeunit "Edit in Excel Fld Filter Impl."; FilterCollectionNode: DotNet FilterCollectionNode; @@ -137,7 +137,7 @@ codeunit 1491 "Edit in Excel Filters Impl." Session.LogMessage('0000I3X', FilterContainsMultipleOperatorsTxt, Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', EditInExcelTelemetryCategoryTxt); exit; // OData does not support filtering on a field with both 'and' and 'or' hence if we see both, ignore the second type end; - Get(ODataFieldName).AddFilterValue(EditinExcelFilterType, FilterValue); + Get(ODataFieldName).AddFilterValueV2(EditinExcelFilterType, FilterValue); end; end; end; diff --git a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFldFilterImpl.Codeunit.al b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFldFilterImpl.Codeunit.al index fd4ce688f2..69bee914e2 100644 --- a/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFldFilterImpl.Codeunit.al +++ b/src/System Application/App/Edit in Excel/src/Filters/EditInExcelFldFilterImpl.Codeunit.al @@ -10,19 +10,26 @@ using System; /// /// This codeunit provides an interface to running Edit in Excel for a specific page. /// -codeunit 1492 "Edit in Excel Fld Filter Impl." implements "Edit in Excel Field Filter" + +#if not CLEAN25 +#pragma warning disable AL0432 +codeunit 1492 "Edit in Excel Fld Filter Impl." implements "Edit in Excel Field Filter", "Edit in Excel Field Filter v2" +#pragma warning restore AL0432 +#else +codeunit 1492 "Edit in Excel Fld Filter Impl." implements "Edit in Excel Field Filter v2" +#endif { Access = Internal; InherentEntitlements = X; InherentPermissions = X; var - EditInExcelFieldFilter: Interface "Edit in Excel Field Filter"; + EditInExcelFieldFilter: Codeunit "Edit in Excel Fld Filter Impl."; FilterCollectionNode: DotNet FilterCollectionNode; ODataFieldName: Text; EdmType: Text; - internal procedure Initialize(NewODataFieldName: Text; NewEdmType: Text; NewFilterCollectionNode: DotNet FilterCollectionNode; NewEditInExcelFieldFilter: Interface "Edit in Excel Field Filter") + internal procedure Initialize(NewODataFieldName: Text; NewEdmType: Text; NewFilterCollectionNode: DotNet FilterCollectionNode; NewEditInExcelFieldFilter: Codeunit "Edit in Excel Fld Filter Impl.") begin FilterCollectionNode := NewFilterCollectionNode; EditInExcelFieldFilter := NewEditInExcelFieldFilter; @@ -30,7 +37,18 @@ codeunit 1492 "Edit in Excel Fld Filter Impl." implements "Edit in Excel Field F EdmType := NewEdmType; end; +#if not CLEAN25 +#pragma warning disable AL0432 + [Obsolete('Use AddFilterValueV2 instead, returns interface "Edit in Excel Field Filter" instead which supports getting filter collection type', '25.0')] procedure AddFilterValue(EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text): Interface "Edit in Excel Field Filter" +#pragma warning restore AL0432 + begin + AddFieldFilterValue(EditInExcelFilterType, FilterValue); + exit(EditInExcelFieldFilter); // Reference back to self to allow builder pattern + end; +#endif + + procedure AddFilterValueV2(EditInExcelFilterType: Enum "Edit in Excel Filter Type"; FilterValue: Text): Interface "Edit in Excel Field Filter V2" begin AddFieldFilterValue(EditInExcelFilterType, FilterValue); exit(EditInExcelFieldFilter); // Reference back to self to allow builder pattern @@ -52,6 +70,16 @@ codeunit 1492 "Edit in Excel Fld Filter Impl." implements "Edit in Excel Field F FilterCollectionNode.Collection.RemoveAt(Index); end; + procedure GetCollectionType(): Enum "Edit in Excel Filter Collection Type" + var + TempString: DotNet String; + begin + TempString := FilterCollectionNode.Operator(); + if TempString = 'or' then + exit("Edit in Excel Filter Collection Type"::"or"); + exit("Edit in Excel Filter Collection Type"::"and") + end; + procedure Count(): Integer begin exit(FilterCollectionNode.Collection.Count()); @@ -75,4 +103,4 @@ codeunit 1492 "Edit in Excel Fld Filter Impl." implements "Edit in Excel Field F FilterCollectionNode.Collection.Add(FilterBinaryNode); end; -} +} \ No newline at end of file diff --git a/src/System Application/Test/Edit in Excel/src/EditInExcelFiltersTest.Codeunit.al b/src/System Application/Test/Edit in Excel/src/EditInExcelFiltersTest.Codeunit.al index 4fcd8a7ddd..405bef8c48 100644 --- a/src/System Application/Test/Edit in Excel/src/EditInExcelFiltersTest.Codeunit.al +++ b/src/System Application/Test/Edit in Excel/src/EditInExcelFiltersTest.Codeunit.al @@ -17,6 +17,44 @@ codeunit 132526 "Edit in Excel Filters Test" var LibraryAssert: Codeunit "Library Assert"; + [Test] + procedure TestEditInExcelFieldFilterGetCollectionTypeReturnsCorrectAndOperator() + var + EditinExcelFilters: Codeunit "Edit in Excel Filters"; + EditInExcelFilter: Interface "Edit in Excel Field Filter v2"; + FieldName: Text; + EditInExcelFilterCollectionType: Enum "Edit in Excel Filter Collection Type"; + begin + FieldName := 'No_'; + + EditinExcelFilters.AddFieldV2(FieldName, "Edit in Excel Filter Collection Type"::"and", Enum::"Edit in Excel Edm Type"::"Edm.String"); + EditinExcelFilters.GetV2(FieldName).AddFilterValueV2(Enum::"Edit in Excel Filter Type"::Equal, '10000'); + EditinExcelFilters.GetV2(FieldName).AddFilterValueV2(Enum::"Edit in Excel Filter Type"::Equal, '10001'); + + EditInExcelFilter := EditinExcelFilters.GetV2(FieldName); + EditInExcelFilterCollectionType := EditInExcelFilter.GetCollectionType(); + LibraryAssert.AreEqual("Edit in Excel Filter Collection Type"::"and", EditInExcelFilterCollectionType, 'Field filter created with an AND operator should have a collection type of AND.') + end; + + [Test] + procedure TestEditInExcelFieldFilterGetCollectionTypeReturnsCorrectOrOperator() + var + EditinExcelFilters: Codeunit "Edit in Excel Filters"; + EditInExcelFilter: Interface "Edit in Excel Field Filter v2"; + FieldName: Text; + EditInExcelFilterCollectionType: Enum "Edit in Excel Filter Collection Type"; + begin + FieldName := 'No_'; + + EditinExcelFilters.AddFieldV2(FieldName, "Edit in Excel Filter Collection Type"::"or", Enum::"Edit in Excel Edm Type"::"Edm.String"); + EditinExcelFilters.GetV2(FieldName).AddFilterValueV2(Enum::"Edit in Excel Filter Type"::Equal, '10000'); + EditinExcelFilters.GetV2(FieldName).AddFilterValueV2(Enum::"Edit in Excel Filter Type"::Equal, '10001'); + + EditInExcelFilter := EditinExcelFilters.GetV2(FieldName); + EditInExcelFilterCollectionType := EditInExcelFilter.GetCollectionType(); + LibraryAssert.AreEqual("Edit in Excel Filter Collection Type"::"or", EditInExcelFilterCollectionType, 'Field filter created with an OR operator should have a collection type of OR.') + end; + [Test] procedure TestEditInExcelStructuredFiltersDateTime() var diff --git a/src/System Application/Test/Edit in Excel/src/EditInExcelTest.Codeunit.al b/src/System Application/Test/Edit in Excel/src/EditInExcelTest.Codeunit.al index d5502b0899..73018fceb8 100644 --- a/src/System Application/Test/Edit in Excel/src/EditInExcelTest.Codeunit.al +++ b/src/System Application/Test/Edit in Excel/src/EditInExcelTest.Codeunit.al @@ -36,7 +36,7 @@ codeunit 132525 "Edit in Excel Test" TenantWebService.SetRange("Object ID", Page::"Edit in Excel List"); TenantWebService.DeleteAll(); - EditinExcelFilters.AddField('Id', Enum::"Edit in Excel Filter Type"::Equal, 'test', Enum::"Edit in Excel Edm Type"::"Edm.String"); + EditinExcelFilters.AddFieldV2('Id', Enum::"Edit in Excel Filter Type"::Equal, 'test', Enum::"Edit in Excel Edm Type"::"Edm.String"); EditInExcel.EditPageInExcel(CopyStr(EditInExcelList.Caption, 1, 240), Page::"Edit in Excel List", EditinExcelFilters);