From 5164630f6778a75120a304767c70c60a69e1dcfd Mon Sep 17 00:00:00 2001 From: Luc Genetier Date: Mon, 27 Jan 2025 14:58:02 +0100 Subject: [PATCH] [WIP/POC] Add navigation properties --- .../Internal/Wrappers/ISwaggerSchema.cs | 6 + .../Internal/Wrappers/SwaggerJsonSchema.cs | 6 + .../Internal/Wrappers/SwaggerSchema.cs | 13 +- .../OpenApiExtensions.cs | 15 +- .../Public/CdpDelegationInfo.cs | 17 +- .../Public/CdpTableValue.cs | 45 +- .../Public/ConnectorType.cs | 56 +- .../Public/NavigationProperty.cs | 20 + .../Capabilities/ServiceCapabilities.cs | 6 +- .../Tabular/CdpTableResolver.cs | 12 + .../Tabular/Services/CdpTable.cs | 18 +- .../Entities/External/DataSourceInfo.cs | 11 +- .../Entities/External/INavigationProperty.cs | 18 + .../External/ISupportsNavigationProperties.cs | 12 + .../Entities/External/TableDelegationInfo.cs | 17 +- .../Delegation/DelegationCapability.cs | 12 +- .../DelegationMetadataOperatorConstants.cs | 8 +- .../Public/Values/DelegationParameters.cs | 11 +- .../FileTabularConnector.cs | 12 +- ....PowerFx.Connectors.Tests.Shared.projitems | 4 + .../PowerPlatformTabularTests.cs | 198 +++++++ .../PublicSurfaceTests.cs | 1 + .../Responses/SAP GetTables 2.json | 165 ++++++ .../SAP_BusinessPartnerSet_Schema.json | 507 ++++++++++++++++++ .../Responses/SAP_ProductSet_Schema.json | 191 +++++++ .../SAP_SalesOrderLineItemSet_Schema.json | 353 ++++++++++++ .../PublicSurfaceTests.cs | 24 +- 27 files changed, 1688 insertions(+), 70 deletions(-) create mode 100644 src/libraries/Microsoft.PowerFx.Connectors/Public/NavigationProperty.cs create mode 100644 src/libraries/Microsoft.PowerFx.Core/Entities/External/INavigationProperty.cs create mode 100644 src/libraries/Microsoft.PowerFx.Core/Entities/External/ISupportsNavigationProperties.cs create mode 100644 src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP GetTables 2.json create mode 100644 src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_BusinessPartnerSet_Schema.json create mode 100644 src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_ProductSet_Schema.json create mode 100644 src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_SalesOrderLineItemSet_Schema.json diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/ISwaggerSchema.cs b/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/ISwaggerSchema.cs index 1b4b482d6e..aca92618ca 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/ISwaggerSchema.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/ISwaggerSchema.cs @@ -38,6 +38,12 @@ internal interface ISwaggerSchema : ISwaggerExtensions // SalesForce specific string RelationshipName { get; } + string ForeignKey { get; } + + string SourceField { get; } + + string RelationshipType { get; } + // SalesForce specific string DataType { get; } } diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerJsonSchema.cs b/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerJsonSchema.cs index 099fc8a0e9..6a874d27c0 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerJsonSchema.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerJsonSchema.cs @@ -130,6 +130,12 @@ public IList Enum public string RelationshipName => SafeGetString("relationshipName"); + public string ForeignKey => SafeGetString("destinationKey"); + + public string SourceField => SafeGetString("sourceField"); + + public string RelationshipType => SafeGetString("relationshipType"); + public string DataType => SafeGetString("datatype"); private string SafeGetString(string key) diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerSchema.cs b/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerSchema.cs index 69bc9f47f0..9ca34f9328 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerSchema.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Internal/Wrappers/SwaggerSchema.cs @@ -87,15 +87,18 @@ public IList Enum public ISwaggerReference Reference => SwaggerReference.New(_schema?.Reference); - // SalesForce specific public ISet ReferenceTo => null; - // SalesForce specific public string RelationshipName => null; - // SalesForce specific public string DataType => null; + public string ForeignKey => throw new NotImplementedException(); + + public string SourceField => throw new NotImplementedException(); + + public string RelationshipType => throw new NotImplementedException(); + private static string GetTypeFromExtension(OpenApiSchema schema) { if (schema == null || schema.Extensions == null) @@ -104,8 +107,8 @@ private static string GetTypeFromExtension(OpenApiSchema schema) } // OpenAI special extension to indicate the type of the property - if (schema.Extensions.TryGetValue("x-oaiTypeLabel", out IOpenApiExtension ext) && - ext is OpenApiString str && + if (schema.Extensions.TryGetValue("x-oaiTypeLabel", out IOpenApiExtension ext) && + ext is OpenApiString str && !string.IsNullOrEmpty(str.Value)) { return str.Value; diff --git a/src/libraries/Microsoft.PowerFx.Connectors/OpenApiExtensions.cs b/src/libraries/Microsoft.PowerFx.Connectors/OpenApiExtensions.cs index 3a8656c951..ed6b324137 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/OpenApiExtensions.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/OpenApiExtensions.cs @@ -656,8 +656,7 @@ internal static ConnectorType GetConnectorType(this ISwaggerParameter openApiPar // Here, we have a circular reference and default to a string return new ConnectorType(schema, openApiParameter, FormulaType.String, hiddenfields.ToRecordType()); } - - //ConnectorType propertyType = new OpenApiParameter() { Name = propLogicalName, Required = schema.Required.Contains(propLogicalName), Schema = kv.Value, Extensions = kv.Value.Extensions }.GetConnectorType(settings.Stack(schemaIdentifier)); + ConnectorType propertyType = new SwaggerParameter(propLogicalName, schema.Required.Contains(propLogicalName), kv.Value, kv.Value.Extensions).GetConnectorType(settings.Stack(schemaIdentifier)); settings.UnStack(); @@ -682,6 +681,18 @@ internal static ConnectorType GetConnectorType(this ISwaggerParameter openApiPar } } + bool HasExternalRef(ConnectorType c) => c.ExternalTables?.Any() == true && !string.IsNullOrEmpty(c.SourceField); + + // Link navigation properties to source fields + foreach (ConnectorType ct in connectorTypes.Where(c => HasExternalRef(c)) + .Union(hiddenConnectorTypes.Where(c => HasExternalRef(c)))) + { + ConnectorType sourceField = connectorTypes.FirstOrDefault(c => c.Name == ct.SourceField) ?? + hiddenConnectorTypes.FirstOrDefault(c => c.Name == ct.SourceField); + + sourceField?.AddNavigationProperty(ct); + } + return new ConnectorType(schema, openApiParameter, fields.ToRecordType(), hiddenfields.ToRecordType(), connectorTypes.ToArray(), hiddenConnectorTypes.ToArray()); } diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpDelegationInfo.cs b/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpDelegationInfo.cs index 8628ba9d25..74cb9d833e 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpDelegationInfo.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpDelegationInfo.cs @@ -2,16 +2,26 @@ // Licensed under the MIT license. using System; +using System.Collections.Generic; +using Microsoft.PowerFx.Connectors; namespace Microsoft.PowerFx.Core.Entities { // Used by ServiceCapabilities.ToDelegationInfo for managing CDP x-ms-capabilities internal class CdpDelegationInfo : TableDelegationInfo { + private readonly ConnectorType _connectorType; + + public CdpDelegationInfo(ConnectorType connectorType) + : base() + { + _connectorType = connectorType; + } + public override ColumnCapabilitiesDefinition GetColumnCapability(string fieldName) { if (ColumnsCapabilities.TryGetValue(fieldName, out ColumnCapabilitiesBase columnCapabilitiesBase)) - { + { return columnCapabilitiesBase switch { ColumnCapabilities columnCapabilities => columnCapabilities.Definition, @@ -21,5 +31,10 @@ public override ColumnCapabilitiesDefinition GetColumnCapability(string fieldNam return null; } + + public override IReadOnlyList GetNavigationProperties(string fieldName) + { + return _connectorType.GetNavigationProperties(fieldName); + } } } diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpTableValue.cs b/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpTableValue.cs index c299b76506..3228b5f188 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpTableValue.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Public/CdpTableValue.cs @@ -18,7 +18,7 @@ public class CdpTableValue : TableValue, IRefreshable, IDelegatableTableValue { public bool IsDelegable => _tabularService.IsDelegable; - protected internal readonly CdpService _tabularService; + protected internal readonly CdpService _tabularService; internal readonly IReadOnlyDictionary Relationships; @@ -27,12 +27,12 @@ public class CdpTableValue : TableValue, IRefreshable, IDelegatableTableValue internal readonly HttpClient HttpClient; public RecordType RecordType => _tabularService?.RecordType; - + internal CdpTableValue(CdpService tabularService, IReadOnlyDictionary relationships) : base(IRContext.NotInSource(tabularService.TableType)) { _tabularService = tabularService; - Relationships = relationships; + Relationships = relationships; HttpClient = tabularService.HttpClient; } @@ -44,10 +44,18 @@ internal CdpTableValue(IRContext irContext) public override IEnumerable> Rows => GetRowsAsync(null, null, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); - public DelegationParameterFeatures SupportedFeatures => DelegationParameterFeatures.Filter | +#pragma warning disable SA1025 // CodeMustNotContainMultipleWhitespaceInARow + + public DelegationParameterFeatures SupportedFeatures => + DelegationParameterFeatures.Filter | DelegationParameterFeatures.Top | - DelegationParameterFeatures.Columns | // $select - DelegationParameterFeatures.Sort; // $orderby + DelegationParameterFeatures.Columns | // $select + DelegationParameterFeatures.Sort | // $orderby + DelegationParameterFeatures.ApplyGroupBy | // $groupby + DelegationParameterFeatures.ApplyJoin | // $apply + DelegationParameterFeatures.Expand; // $expand + +#pragma warning restore SA1025 public async Task>> GetRowsAsync(IServiceProvider services, DelegationParameters parameters, CancellationToken cancel) { @@ -76,26 +84,35 @@ public Task ExecuteQueryAsync(IServiceProvider services, Delegatio { throw new NotImplementedException(); } - } + } internal static class ODataParametersExtensions { +#pragma warning disable SA1025 // CodeMustNotContainMultipleWhitespaceInARow + public static ODataParameters ToOdataParameters(this DelegationParameters parameters) { - DelegationParameterFeatures allowedFeatures = - DelegationParameterFeatures.Filter | - DelegationParameterFeatures.Top | - DelegationParameterFeatures.Columns | // $select - DelegationParameterFeatures.Sort; // $orderby + DelegationParameterFeatures allowedFeatures = + DelegationParameterFeatures.Filter | + DelegationParameterFeatures.Top | + DelegationParameterFeatures.Columns | // $select + DelegationParameterFeatures.Sort | // $orderby + DelegationParameterFeatures.ApplyGroupBy | // $groupby + DelegationParameterFeatures.ApplyJoin | // $apply + DelegationParameterFeatures.Expand; // $expand +#pragma warning restore SA1025 parameters.EnsureOnlyFeatures(allowedFeatures); + string expand = parameters.GetExpand(); + ODataParameters op = new ODataParameters() { Filter = parameters.GetOdataFilter(), Top = parameters.Top.GetValueOrDefault(), - Select = parameters.GetColumns(), - OrderBy = parameters.GetOrderBy() + Select = string.IsNullOrEmpty(expand) ? parameters.GetColumns() : null, + OrderBy = parameters.GetOrderBy(), + Expand = expand }; return op; diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorType.cs b/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorType.cs index 83e8204eb3..49519d9483 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorType.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorType.cs @@ -10,6 +10,7 @@ using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.PowerFx.Core; +using Microsoft.PowerFx.Core.Entities; using Microsoft.PowerFx.Core.Localization; using Microsoft.PowerFx.Core.Utils; using Microsoft.PowerFx.Types; @@ -21,7 +22,7 @@ namespace Microsoft.PowerFx.Connectors // FormulaType is used to represent the type of the parameter in the Power Fx expression as used in Power Apps // ConnectorType contains more details information coming from the swagger file and extensions [DebuggerDisplay("{FormulaType._type}")] - public class ConnectorType : SupportsConnectorErrors + public class ConnectorType : SupportsConnectorErrors, ISupportsNavigationProperties { // "name" public string Name { get; internal set; } @@ -116,11 +117,19 @@ public class ConnectorType : SupportsConnectorErrors internal ISwaggerSchema Schema { get; private set; } = null; // Relationships to external tables - internal List ExternalTables { get; set; } + internal List ExternalTables { get; set; } = null; - internal string RelationshipName { get; set; } + internal string RelationshipName { get; set; } = null; - internal string ForeignKey { get; set; } + internal string ForeignKey { get; set; } = null; + + internal string SourceField { get; set; } = null; + + internal string RelationshipType { get; set; } = null; + + internal IReadOnlyList NavigationPropertyReferences => _navigationPropertyReferences; + + private List _navigationPropertyReferences = null; internal ConnectorType(ISwaggerSchema schema, ISwaggerParameter openApiParameter, FormulaType formulaType, ErrorResourceKey warning = default, IEnumerable> list = null, bool isNumber = false) { @@ -146,13 +155,14 @@ internal ConnectorType(ISwaggerSchema schema, ISwaggerParameter openApiParameter KeyOrder = schema.GetKeyOrder(); Permission = schema.GetPermission(); - // We only support one reference for now - // SalesForce only + // We only support one reference for now if (schema.ReferenceTo != null && schema.ReferenceTo.Count == 1) { ExternalTables = new List(schema.ReferenceTo); RelationshipName = schema.RelationshipName; - ForeignKey = null; // SalesForce doesn't provide it, defaults to "Id" + ForeignKey = schema.ForeignKey; // SalesForce doesn't provide it, defaults to "Id" + SourceField = schema.SourceField; + RelationshipType = schema.RelationshipType; } Fields = Array.Empty(); @@ -308,6 +318,12 @@ internal ConnectorType(ConnectorType connectorType, ConnectorType[] fields, Form _warnings = connectorType._warnings; } + internal void AddNavigationProperty(ConnectorType navigationProperty) + { + _navigationPropertyReferences ??= new List(); + _navigationPropertyReferences.Add(navigationProperty); + } + internal DisplayNameProvider DisplayNameProvider { get @@ -357,5 +373,31 @@ private Dictionary GetEnum() return enumDisplayNames.Zip(enumValues, (dn, ev) => new KeyValuePair(dn, ev)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } + + public IReadOnlyList GetNavigationProperties(string fieldName) + { + ConnectorType field = Fields.FirstOrDefault(ct => ct.Name == fieldName); + + if (field?.NavigationPropertyReferences?.Any() != true) + { + return null; + } + + List navProps = new List(); + + foreach (ConnectorType navPropRef in field.NavigationPropertyReferences) + { + navProps.Add(new NavigationProperty() + { + Name = navPropRef.Name, + SourceField = navPropRef.SourceField, + ForeignKey = navPropRef.ForeignKey, + RelationshipName = navPropRef.RelationshipName, + RelationshipType = navPropRef.RelationshipType, + }); + } + + return navProps; + } } } diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Public/NavigationProperty.cs b/src/libraries/Microsoft.PowerFx.Connectors/Public/NavigationProperty.cs new file mode 100644 index 0000000000..05422403cc --- /dev/null +++ b/src/libraries/Microsoft.PowerFx.Connectors/Public/NavigationProperty.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using Microsoft.PowerFx.Core.Entities; + +namespace Microsoft.PowerFx.Connectors +{ + public class NavigationProperty : INavigationProperty + { + public string Name { get; init; } + + public string SourceField { get; init; } + + public string ForeignKey { get; init; } + + public string RelationshipName { get; init; } + + public string RelationshipType { get; init; } + } +} diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Capabilities/ServiceCapabilities.cs b/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Capabilities/ServiceCapabilities.cs index d793165466..2bcef0f322 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Capabilities/ServiceCapabilities.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Capabilities/ServiceCapabilities.cs @@ -113,7 +113,7 @@ public ServiceCapabilities(SortRestriction sortRestriction, FilterRestriction fi Contracts.AssertValue(pagingCapabilities); SortRestriction = sortRestriction; - FilterRestriction = filterRestriction; + FilterRestriction = filterRestriction; PagingCapabilities = pagingCapabilities; SelectionRestriction = selectionRestriction; GroupRestriction = groupRestriction; @@ -181,7 +181,7 @@ public static TableDelegationInfo ToDelegationInfo(ServiceCapabilities serviceCa Dictionary columnWithRelationships = connectorType.Fields.Where(f => f.ExternalTables?.Any() == true).Select(f => (f.Name, f.ExternalTables.First())).ToDictionary(tpl => tpl.Name, tpl => tpl.Item2); string[] primaryKeyNames = connectorType.Fields.Where(f => f.KeyType == ConnectorKeyType.Primary).OrderBy(f => f.KeyOrder).Select(f => f.Name).ToArray(); - return new CdpDelegationInfo() + return new CdpDelegationInfo(connectorType) { TableName = tableName, IsReadOnly = isReadOnly, @@ -189,7 +189,7 @@ public static TableDelegationInfo ToDelegationInfo(ServiceCapabilities serviceCa SortRestriction = sortRestriction, FilterRestriction = filterRestriction, SelectionRestriction = selectionRestriction, - GroupRestriction = groupRestriction, + GroupRestriction = groupRestriction, FilterSupportedFunctions = serviceCapabilities?.FilterSupportedFunctionsEnum, PagingCapabilities = pagingCapabilities, SupportsRecordPermission = serviceCapabilities?.SupportsRecordPermission ?? false, diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Tabular/CdpTableResolver.cs b/src/libraries/Microsoft.PowerFx.Connectors/Tabular/CdpTableResolver.cs index f6ea4849b5..08ae51aa56 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Tabular/CdpTableResolver.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Tabular/CdpTableResolver.cs @@ -28,6 +28,10 @@ internal class CdpTableResolver : ICdpTableResolver private readonly bool _doubleEncoding; +#if DEBUG + internal Func UpdateShema = null; +#endif + public CdpTableResolver(CdpTable tabularTable, HttpClient httpClient, string uriPrefix, bool doubleEncoding, ConnectorLogger logger = null) { _tabularTable = tabularTable; @@ -57,6 +61,14 @@ public async Task ResolveTableAsync(string tableName, Cancellatio string text = await CdpServiceBase.GetObject(_httpClient, $"Get table metadata", uri, null, cancellationToken, Logger).ConfigureAwait(false); +#if DEBUG + // Used to return an alternate result + if (UpdateShema != null) + { + text = UpdateShema(tableName, text); + } +#endif + if (string.IsNullOrWhiteSpace(text)) { return null; diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Services/CdpTable.cs b/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Services/CdpTable.cs index f039efa1b5..2047fcc5e5 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Services/CdpTable.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Tabular/Services/CdpTable.cs @@ -7,7 +7,6 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using System.Web; using Microsoft.PowerFx.Core.Entities; using Microsoft.PowerFx.Core.IR; using Microsoft.PowerFx.Types; @@ -62,6 +61,14 @@ internal CdpTable(string dataset, string table, DatasetMetadata datasetMetadata, // GET: /$metadata.json/datasets/{datasetName}/tables/{tableName}?api-version=2015-09-01 public virtual async Task InitAsync(HttpClient httpClient, string uriPrefix, CancellationToken cancellationToken, ConnectorLogger logger = null) { +#if DEBUG + cancellationToken.ThrowIfCancellationRequested(); + await InitAsync(httpClient, uriPrefix, cancellationToken, null, logger).ConfigureAwait(false); + } + + public virtual async Task InitAsync(HttpClient httpClient, string uriPrefix, CancellationToken cancellationToken, Func updateSchema, ConnectorLogger logger = null) + { +#endif cancellationToken.ThrowIfCancellationRequested(); if (IsInitialized) @@ -78,7 +85,14 @@ public virtual async Task InitAsync(HttpClient httpClient, string uriPrefix, Can _uriPrefix = uriPrefix; - CdpTableResolver tableResolver = new CdpTableResolver(this, httpClient, uriPrefix, DatasetMetadata.IsDoubleEncoding, logger); + CdpTableResolver tableResolver = new CdpTableResolver(this, httpClient, uriPrefix, DatasetMetadata.IsDoubleEncoding, logger) +#if DEBUG + { + UpdateShema = updateSchema + } +#endif + ; + TabularTableDescriptor = await tableResolver.ResolveTableAsync(TableName, cancellationToken).ConfigureAwait(false); _relationships = TabularTableDescriptor.Relationships; diff --git a/src/libraries/Microsoft.PowerFx.Core/Entities/External/DataSourceInfo.cs b/src/libraries/Microsoft.PowerFx.Core/Entities/External/DataSourceInfo.cs index ef1e6a40d4..8e38f7bd78 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Entities/External/DataSourceInfo.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Entities/External/DataSourceInfo.cs @@ -16,7 +16,7 @@ namespace Microsoft.PowerFx.Core.Entities { // Implements a base data source, used in DType.AssociatedDataSources, itself in RecordType constructor to host a CDP record type - internal class DataSourceInfo : IExternalTabularDataSource + internal class DataSourceInfo : IExternalTabularDataSource, ISupportsNavigationProperties { // Key = field logical name, Value = foreign table logical name public readonly IReadOnlyDictionary ColumnsWithRelationships; @@ -156,13 +156,13 @@ void AddOrUpdate(Dictionary dic, string prop, Deleg FilterOpMetadata filterOpMetadata = new CdpFilterOpMetadata(recordType, delegationInfo); GroupOpMetadata groupOpMetadata = new GroupOpMetadata(type, groupByRestrictions); - ODataOpMetadata oDataOpMetadata = new ODataOpMetadata(type, oDataReplacements); + ODataOpMetadata oDataOpMetadata = new ODataOpMetadata(type, oDataReplacements); List metadataList = new List() { filterOpMetadata, groupOpMetadata, - oDataOpMetadata + oDataOpMetadata }; if (delegationInfo?.SortRestriction != null) @@ -212,5 +212,10 @@ internal static DPath GetReplacementPath(string alias, DPath currentColumnPath) return currentColumnPath.Append(new DName(alias)); } } + + public virtual IReadOnlyList GetNavigationProperties(string fieldName) + { + return _delegationInfo.GetNavigationProperties(fieldName); + } } } diff --git a/src/libraries/Microsoft.PowerFx.Core/Entities/External/INavigationProperty.cs b/src/libraries/Microsoft.PowerFx.Core/Entities/External/INavigationProperty.cs new file mode 100644 index 0000000000..9f8c6ddd32 --- /dev/null +++ b/src/libraries/Microsoft.PowerFx.Core/Entities/External/INavigationProperty.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace Microsoft.PowerFx.Core.Entities +{ + public interface INavigationProperty + { + string Name { get; } + + string SourceField { get; } + + string ForeignKey { get; } + + string RelationshipName { get; } + + string RelationshipType { get; } + } +} diff --git a/src/libraries/Microsoft.PowerFx.Core/Entities/External/ISupportsNavigationProperties.cs b/src/libraries/Microsoft.PowerFx.Core/Entities/External/ISupportsNavigationProperties.cs new file mode 100644 index 0000000000..dd4d2f8f1e --- /dev/null +++ b/src/libraries/Microsoft.PowerFx.Core/Entities/External/ISupportsNavigationProperties.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using System.Collections.Generic; + +namespace Microsoft.PowerFx.Core.Entities +{ + public interface ISupportsNavigationProperties + { + public IReadOnlyList GetNavigationProperties(string fieldName); + } +} diff --git a/src/libraries/Microsoft.PowerFx.Core/Entities/External/TableDelegationInfo.cs b/src/libraries/Microsoft.PowerFx.Core/Entities/External/TableDelegationInfo.cs index 21016d1086..918c93c8f3 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Entities/External/TableDelegationInfo.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Entities/External/TableDelegationInfo.cs @@ -11,7 +11,7 @@ namespace Microsoft.PowerFx.Core.Entities { // Supports delegation information for CDP connectors - public abstract class TableDelegationInfo + public abstract class TableDelegationInfo : ISupportsNavigationProperties { // Defines unsortable columns or columns only supporting ascending ordering // If set to null, the table is not sortable @@ -32,7 +32,7 @@ public abstract class TableDelegationInfo // Defines ungroupable columns public GroupRestrictions GroupRestriction { get; init; } - // Filter functions supported by all columns of the table + // Filter functions supported by all columns of the table public IEnumerable FilterSupportedFunctions { get; init; } // Defines paging capabilities @@ -84,6 +84,11 @@ public TableDelegationInfo() } public abstract ColumnCapabilitiesDefinition GetColumnCapability(string fieldName); + + public virtual IReadOnlyList GetNavigationProperties(string fieldName) + { + return null; + } } internal sealed class ComplexColumnCapabilities : ColumnCapabilitiesBase @@ -114,7 +119,7 @@ public sealed class ColumnCapabilities : ColumnCapabilitiesBase public ColumnCapabilitiesDefinition Definition => _capabilities; - // Those are default CDS filter supported functions + // Those are default CDS filter supported functions // From // PowerApps-Client\src\Language\PowerFx.Dataverse.Parser\Importers\DataDescription\CdsCapabilities.cs public static readonly IEnumerable DefaultFilterFunctionSupport = new DelegationOperator[] { @@ -191,7 +196,7 @@ public IEnumerable FilterFunctions internal bool? IsChoice { get; init; } private IEnumerable _filterFunctions; - + public ColumnCapabilitiesDefinition() { } @@ -228,7 +233,7 @@ internal sealed class PagingCapabilities public bool IsOnlyServerPagable { get; init; } // Only supported values "top" and "skiptoken" - // Used to define paging options to use + // Used to define paging options to use public IEnumerable ServerPagingOptions { get; init; } public PagingCapabilities() @@ -310,7 +315,7 @@ public CountCapabilities() } /// - /// If the table is countable, return true. + /// If the table is countable, return true. /// Relevant expression: CountRows(Table). /// /// diff --git a/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationCapability.cs b/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationCapability.cs index 73581b390e..8c4bae6aee 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationCapability.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationCapability.cs @@ -91,7 +91,8 @@ internal struct DelegationCapability { DelegationMetadataOperatorConstants.JoinInner, new DelegationCapability(JoinInner) }, { DelegationMetadataOperatorConstants.JoinLeft, new DelegationCapability(JoinLeft) }, { DelegationMetadataOperatorConstants.JoinRight, new DelegationCapability(JoinRight) }, - { DelegationMetadataOperatorConstants.JoinFull, new DelegationCapability(JoinFull) } + { DelegationMetadataOperatorConstants.JoinFull, new DelegationCapability(JoinFull) }, + { DelegationMetadataOperatorConstants.OdataExpand, new DelegationCapability(OdataExpand) } }, isThreadSafe: true); // Supported delegatable operations. @@ -147,9 +148,10 @@ internal struct DelegationCapability public static readonly BigInteger JoinLeft = BigInteger.Pow(2, 48); // 0x1000000000000 public static readonly BigInteger JoinRight = BigInteger.Pow(2, 49); // 0x2000000000000 public static readonly BigInteger JoinFull = BigInteger.Pow(2, 50); // 0x4000000000000 + public static readonly BigInteger OdataExpand = BigInteger.Pow(2, 51); // 0x8000000000000 // Please update it as max value changes. - private static BigInteger maxSingleCapabilityValue = JoinFull; + private static BigInteger maxSingleCapabilityValue = OdataExpand; // Indicates support all functionality. public static BigInteger SupportsAll @@ -511,6 +513,12 @@ internal string DebugString sb.Append(nameof(JoinFull)); } + if (HasCapability(OdataExpand)) + { + AddCommaIfNeeded(sb); + sb.Append(nameof(OdataExpand)); + } + return sb.ToString(); } } diff --git a/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationMetadataOperatorConstants.cs b/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationMetadataOperatorConstants.cs index fe4319a41f..3b18ec20ca 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationMetadataOperatorConstants.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Functions/Delegation/DelegationMetadataOperatorConstants.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -using System.Collections.Generic; -using Microsoft.PowerFx.Core.Types; -using Microsoft.PowerFx.Core.Utils; - namespace Microsoft.PowerFx.Core.Functions.Delegation { // Operator strings which are part of delegation metadata Json. @@ -56,6 +52,7 @@ internal static class DelegationMetadataOperatorConstants public const string JoinLeft = "joinleft"; public const string JoinRight = "joinright"; public const string JoinFull = "joinfull"; + public const string OdataExpand = "odataexpand"; } public enum DelegationOperator @@ -104,6 +101,7 @@ public enum DelegationOperator JoinInner, JoinLeft, JoinRight, - JoinFull + JoinFull, + OdataExpand } } diff --git a/src/libraries/Microsoft.PowerFx.Core/Public/Values/DelegationParameters.cs b/src/libraries/Microsoft.PowerFx.Core/Public/Values/DelegationParameters.cs index d328e8d425..d74b391868 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Public/Values/DelegationParameters.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Public/Values/DelegationParameters.cs @@ -42,6 +42,11 @@ public void EnsureOnlyFeatures(DelegationParameterFeatures allowedFeatures) public abstract string GetOdataFilter(); + public virtual string GetExpand() + { + return null; + } + // 0 columns means return all columns. public virtual IReadOnlyCollection GetColumns() { @@ -79,15 +84,15 @@ public enum DelegationParameterFeatures // $count Count = 1 << 6, + // $expand + Expand = 1 << 7 + /* To be implemented later when needed // $compute Compute = 1 << 5, - // $expand - Expand = 1 << 7, - // $format Format = 1 << 8, diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/FileTabularConnector.cs b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/FileTabularConnector.cs index c015faaebd..71d2ed21af 100644 --- a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/FileTabularConnector.cs +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/FileTabularConnector.cs @@ -57,7 +57,7 @@ public async Task FileTabularTest() CheckResult check = engine.Check(expr, options: new ParserOptions() { AllowsSideEffects = true }, symbolTable: symbolValues.SymbolTable); Assert.True(check.IsSuccess); - + // Use tabular connector. Internally we'll call CdpTableValue.GetRowsInternal to get the data FormulaValue result = await check.GetEvaluator().EvalAsync(CancellationToken.None, symbolValues); StringValue str = Assert.IsType(result); @@ -77,7 +77,7 @@ public FileTabularService(string fileName) _fileName = File.Exists(fileName) ? fileName : throw new FileNotFoundException($"File not found: {_fileName}"); } - public override bool IsDelegable => false; + public override bool IsDelegable => false; // No need for files public override HttpClient HttpClient => null; @@ -86,7 +86,7 @@ public FileTabularService(string fileName) // Initialization can be synchronous public void Init() - { + { RecordType = new FileTabularRecordType(RecordType.Empty().Add("line", FormulaType.String)); } @@ -116,13 +116,13 @@ public FileTabularRecordType(RecordType recordType) private static TableDelegationInfo GetDelegationInfo() { - return new CdpDelegationInfo() + return new CdpDelegationInfo(null) { TableName = "FileTabular" }; } - private static DisplayNameProvider GetDisplayNameProvider(RecordType recordType) => DisplayNameProvider.New(recordType.FieldNames.Select(f => new KeyValuePair(new Core.Utils.DName(f), new Core.Utils.DName(f)))); + private static DisplayNameProvider GetDisplayNameProvider(RecordType recordType) => DisplayNameProvider.New(recordType.FieldNames.Select(f => new KeyValuePair(new Core.Utils.DName(f), new Core.Utils.DName(f)))); public override bool TryGetFieldType(string name, out FormulaType type) { @@ -142,6 +142,6 @@ public override bool Equals(object other) public override int GetHashCode() { throw new NotImplementedException(); - } + } } } diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Microsoft.PowerFx.Connectors.Tests.Shared.projitems b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Microsoft.PowerFx.Connectors.Tests.Shared.projitems index 4e0403dfc9..ea998a1d9a 100644 --- a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Microsoft.PowerFx.Connectors.Tests.Shared.projitems +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Microsoft.PowerFx.Connectors.Tests.Shared.projitems @@ -230,6 +230,10 @@ + + + + diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformTabularTests.cs b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformTabularTests.cs index d88628b7bd..66bf3d5522 100644 --- a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformTabularTests.cs +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformTabularTests.cs @@ -339,6 +339,204 @@ public async Task SAP_CDP() Assert.Equal(string.Empty, string.Join("|", GetPrimaryKeyNames(sapTableValue.RecordType))); } + [Fact] + [Obsolete("Using Join function")] + public async Task SAP_CDP2() + { + using var testConnector = new LoggingTestServer(null /* no swagger */, _output); + var config = new PowerFxConfig(Features.PowerFxV1); + config.EnableJoinFunction(); + var engine = new RecalcEngine(config); + + ConsoleLogger logger = new ConsoleLogger(_output); + using var httpClient = new HttpClient(testConnector); + string connectionId = "b5097592f2ae498ea32458b1035634a9"; + string jwt = "eyJ0eXA..."; + using var client = new PowerPlatformConnectorClient("49970107-0806-e5a7-be5e-7c60e2750f01.12.common.firstrelease.azure-apihub.net", "49970107-0806-e5a7-be5e-7c60e2750f01", connectionId, () => jwt, httpClient) { SessionId = "8e67ebdc-d402-455a-b33a-304820832383" }; + + testConnector.SetResponseFromFile(@"Responses\SAP GetDataSetMetadata.json"); + DatasetMetadata dm = await CdpDataSource.GetDatasetsMetadataAsync(client, $"/apim/sapodata/{connectionId}", CancellationToken.None, logger); + + CdpDataSource cds = new CdpDataSource("https://sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC/"); + + testConnector.SetResponseFromFiles(@"Responses\SAP GetDataSetMetadata.json", @"Responses\SAP GetTables 2.json"); + CdpTable sapTableProductSet = await cds.GetTableAsync(client, $"/apim/sapodata/{connectionId}", "ProductSet", null, CancellationToken.None, logger); + + testConnector.SetResponseFromFiles(@"Responses\SAP GetTables 2.json"); + CdpTable sapTableBusinessPartnerSet = await cds.GetTableAsync(client, $"/apim/sapodata/{connectionId}", "BusinessPartnerSet", null, CancellationToken.None, logger); + + testConnector.SetResponseFromFile(@"Responses\SAP_ProductSet_Schema.json"); + await sapTableProductSet.InitAsync(client, $"/apim/sapodata/{connectionId}", CancellationToken.None, logger); + + testConnector.SetResponseFromFile(@"Responses\SAP_BusinessPartnerSet_Schema.json"); + await sapTableBusinessPartnerSet.InitAsync(client, $"/apim/sapodata/{connectionId}", CancellationToken.None, logger); + + Assert.True(sapTableProductSet.IsInitialized); + Assert.True(sapTableBusinessPartnerSet.IsInitialized); + + CdpTableValue sapTableValueProductSet = sapTableProductSet.GetTableValue(); + CdpTableValue sapTableValueBusinessPartnerSet = sapTableBusinessPartnerSet.GetTableValue(); + Assert.Equal( + "r*[Category:s, ChangedAt:s, CreatedAt:s, CurrencyCode:s, Depth:w, Description:s, DescriptionLanguage:s, DimUnit:s, Height:w, MeasureUnit:s, Name:s, " + + "NameLanguage:s, Price:w, ProductID:s, SupplierID:s, SupplierName:s, TaxTarifCode:w, ToSalesOrderLineItems:~SalesOrderLineItemSet:![], ToSupplier:~BusinessPartnerSet:![], " + + "TypeCode:s, WeightMeasure:w, WeightUnit:s, Width:w]", sapTableValueProductSet.Type.ToStringWithDisplayNames()); + + string expr = "Join(ProductSet, BusinessPartnerSet, LeftRecord.SupplierID = RightRecord.BusinessPartnerID, JoinType.Left, RightRecord.EmailAddress As Email)"; + + SymbolValues symbolValues = new SymbolValues() + .Add("ProductSet", sapTableValueProductSet) + .Add("BusinessPartnerSet", sapTableValueBusinessPartnerSet); + RuntimeConfig rc = new RuntimeConfig(symbolValues).AddService(logger); + + // Calls to resolve ToXX navigation properties + testConnector.SetResponseFromFiles(@"Responses\SAP_BusinessPartnerSet_Schema.json", @"Responses\SAP_SalesOrderLineItemSet_Schema.json"); + CheckResult check = engine.Check(expr, options: new ParserOptions() { AllowsSideEffects = true }, symbolTable: symbolValues.SymbolTable); + Assert.True(check.IsSuccess, string.Join("\r\n", check.Errors.Select((er, i) => $"{i:00}: {er.Message}"))); + + // Lazy Join leads to many network calls so this line is commented out + // We'd need to investigate / add a cache in tests + //FormulaValue result = await check.GetEvaluator().EvalAsync(CancellationToken.None, rc); + + /* + Non-delegated result = Table( + {Category:"Notebooks",ChangedAt:"2025-01-24T07:22:48.920808",CreatedAt:"2025-01-24T07:22:48.920808",CurrencyCode:"USD",Depth:Decimal(18),Description:"Notebook Basic",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(3),MeasureUnit:"EA",Name:"Notebook Basic 15",NameLanguage:"EN",Price:Decimal(956),ProductID:"GEAR",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.2),WeightUnit:"KG",Width:Decimal(30)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(18),Description:"Notebook Basic 15 with 2,80 GHz quad core, 15"" LCD, 4 GB DDR3 RAM, 500 GB Hard Disc, Windows 8 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-do.not.reply@sap.com",Height:Decimal(3),MeasureUnit:"EA",Name:"Notebook Basic 15",NameLanguage:"EN",Price:Decimal(956),ProductID:"HT-1000",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.2),WeightUnit:"KG",Width:Decimal(30)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(17),Description:"Notebook Basic 17 with 2,80 GHz quad core, 17"" LCD, 4 GB DDR3 RAM, 500 GB Hard Disc, Windows 8 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-dagmar.schulze@beckerberlin.de",Height:Decimal(3.1),MeasureUnit:"EA",Name:"Notebook Basic 17",NameLanguage:"EN",Price:Decimal(1249),ProductID:"HT-1001",SupplierID:"0100000047",SupplierName:"Becker Berlin",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.5),WeightUnit:"KG",Width:Decimal(29)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(19),Description:"Notebook Basic 18 with 2,80 GHz quad core, 18"" LCD, 8 GB DDR3 RAM, 1000 GB Hard Disc, Windows 8 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-maria.brown@delbont.com",Height:Decimal(2.5),MeasureUnit:"EA",Name:"Notebook Basic 18",NameLanguage:"EN",Price:Decimal(1570),ProductID:"HT-1002",SupplierID:"0100000048",SupplierName:"DelBont Industries",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.2),WeightUnit:"KG",Width:Decimal(28)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(21),Description:"Notebook Basic 19 with 2,80 GHz quad core, 19"" LCD, 8 GB DDR3 RAM, 1000 GB Hard Disc, Windows 8 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-saskia.sommer@talpa-hannover.de",Height:Decimal(4),MeasureUnit:"EA",Name:"Notebook Basic 19",NameLanguage:"EN",Price:Decimal(1650),ProductID:"HT-1003",SupplierID:"0100000049",SupplierName:"Talpa",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.2),WeightUnit:"KG",Width:Decimal(32)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(22),Description:"Digital Organizer with State-of-the-Art Storage Encryption",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-bob.buyer@panorama-studios.biz",Height:Decimal(3),MeasureUnit:"EA",Name:"ITelO Vault",NameLanguage:"EN",Price:Decimal(299),ProductID:"HT-1007",SupplierID:"0100000050",SupplierName:"Panorama Studios",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.2),WeightUnit:"KG",Width:Decimal(32)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(20),Description:"Notebook Professional 15 with 2,80 GHz quad core, 15"" Multitouch LCD, 8 GB DDR3 RAM, 500 GB SSD - DVD-Writer (DVD-R/+R/-RW/-RAM),Windows 8 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-bart.koenig@tecum-ag.de",Height:Decimal(3),MeasureUnit:"EA",Name:"Notebook Professional 15",NameLanguage:"EN",Price:Decimal(1999),ProductID:"HT-1010",SupplierID:"0100000051",SupplierName:"TECUM",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.3),WeightUnit:"KG",Width:Decimal(33)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(23),Description:"Notebook Professional 17 with 2,80 GHz quad core, 17"" Multitouch LCD, 8 GB DDR3 RAM, 500 GB SSD - DVD-Writer (DVD-R/+R/-RW/-RAM),Windows 8 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-yoko.nakamura@asia-ht.com",Height:Decimal(2),MeasureUnit:"EA",Name:"Notebook Professional 17",NameLanguage:"EN",Price:Decimal(2299),ProductID:"HT-1011",SupplierID:"0100000052",SupplierName:"Asia High tech",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.1),WeightUnit:"KG",Width:Decimal(33)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(1.8),Description:"Digital Organizer with State-of-the-Art Encryption for Storage and Network Communications",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sophie.ribery@laurent-paris.com",Height:Decimal(17),MeasureUnit:"EA",Name:"ITelO Vault Net",NameLanguage:"EN",Price:Decimal(459),ProductID:"HT-1020",SupplierID:"0100000053",SupplierName:"Laurent",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.16),WeightUnit:"KG",Width:Decimal(10)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(1.7),Description:"Digital Organizer with State-of-the-Art Encryption for Storage and Secure Stellite Link",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-victor.sanchez@avantel.com",Height:Decimal(18),MeasureUnit:"EA",Name:"ITelO Vault SAT",NameLanguage:"EN",Price:Decimal(149),ProductID:"HT-1021",SupplierID:"0100000054",SupplierName:"AVANTEL",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.18),WeightUnit:"KG",Width:Decimal(11)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(1.5),Description:"32 GB Digital Assistant with high-resolution color screen",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jorge.velez@telecomunicacionesstar.com",Height:Decimal(14),MeasureUnit:"EA",Name:"Comfort Easy",NameLanguage:"EN",Price:Decimal(1679),ProductID:"HT-1022",SupplierID:"0100000055",SupplierName:"Telecomunicaciones Star",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.2),WeightUnit:"KG",Width:Decimal(84)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(1.6),Description:"64 GB Digital Assistant with high-resolution color screen and synthesized voice output",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-franklin.jones@pear-computing.com",Height:Decimal(13),MeasureUnit:"EA",Name:"Comfort Senior",NameLanguage:"EN",Price:Decimal(512),ProductID:"HT-1023",SupplierID:"0100000056",SupplierName:"Pear Computing Services",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.8),WeightUnit:"KG",Width:Decimal(80)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(12),Description:"Optimum Hi-Resolution max. 1920 x 1080 @ 85Hz, Dot Pitch: 0.27mm",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-joseph_gschwandtner@alp-systems.at",Height:Decimal(36),MeasureUnit:"EA",Name:"Ergo Screen E-I",NameLanguage:"EN",Price:Decimal(230),ProductID:"HT-1030",SupplierID:"0100000057",SupplierName:"Alpine Systems",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(21),WeightUnit:"KG",Width:Decimal(37)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(19),Description:"Optimum Hi-Resolution max. 1920 x 1200 @ 85Hz, Dot Pitch: 0.26mm",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-george_d_grant@newlinedesign.co.uk",Height:Decimal(43),MeasureUnit:"EA",Name:"Ergo Screen E-II",NameLanguage:"EN",Price:Decimal(285),ProductID:"HT-1031",SupplierID:"0100000058",SupplierName:"New Line Design",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(21),WeightUnit:"KG",Width:Decimal(40.8)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(19),Description:"Optimum Hi-Resolution max. 2560 x 1440 @ 85Hz, Dot Pitch: 0.25mm",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sarah.schwind@hepa-tec.de",Height:Decimal(43),MeasureUnit:"EA",Name:"Ergo Screen E-III",NameLanguage:"EN",Price:Decimal(345),ProductID:"HT-1032",SupplierID:"0100000059",SupplierName:"HEPA Tec",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(21),WeightUnit:"KG",Width:Decimal(40.8)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(20),Description:"Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-theodor.monathy@anavideon.com",Height:Decimal(41),MeasureUnit:"EA",Name:"Flat Basic",NameLanguage:"EN",Price:Decimal(399),ProductID:"HT-1035",SupplierID:"0100000060",SupplierName:"Anav Ideon",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(14),WeightUnit:"KG",Width:Decimal(39)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(26),Description:"Optimum Hi-Resolution max. 2048 x 1080 @ 85Hz, Dot Pitch: 0.26mm",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-robert_brown@rb-entertainment.ca",Height:Decimal(46),MeasureUnit:"EA",Name:"Flat Future",NameLanguage:"EN",Price:Decimal(430),ProductID:"HT-1036",SupplierID:"0100000061",SupplierName:"Robert Brown Entertainment",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(15),WeightUnit:"KG",Width:Decimal(45)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(22.1),Description:"Optimum Hi-Resolution max. 2016 x 1512 @ 85Hz, Dot Pitch: 0.24mm",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jorgemontalban@motc.mx",Height:Decimal(39.1),MeasureUnit:"EA",Name:"Flat XL",NameLanguage:"EN",Price:Decimal(1230),ProductID:"HT-1037",SupplierID:"0100000062",SupplierName:"Mexican Oil Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(17),WeightUnit:"KG",Width:Decimal(54.5)}, + {Category:"Laser Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(46),Description:"Print 2400 dpi image quality color documents at speeds of up to 32 ppm (color) or 36 ppm (monochrome), letter/A4. Powerful 500 MHz processor, 512MB of memory",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-johanna.esther@meliva.de",Height:Decimal(30),MeasureUnit:"EA",Name:"Laser Professional Eco",NameLanguage:"EN",Price:Decimal(830),ProductID:"HT-1040",SupplierID:"0100000063",SupplierName:"Meliva",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(32),WeightUnit:"KG",Width:Decimal(51)}, + {Category:"Laser Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(42),Description:"Up to 22 ppm color or 24 ppm monochrome A4/letter, powerful 500 MHz processor and 128MB of memory",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-miguel.luengo@compostela.ar",Height:Decimal(26),MeasureUnit:"EA",Name:"Laser Basic",NameLanguage:"EN",Price:Decimal(490),ProductID:"HT-1041",SupplierID:"0100000064",SupplierName:"Compostela",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(23),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Laser Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(50),Description:"Print up to 25 ppm letter and 24 ppm A4 color or monochrome, with a first-page-out-time of less than 13 seconds for monochrome and less than 15 seconds for color",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-isabel.nemours@pateu.fr",Height:Decimal(65),MeasureUnit:"EA",Name:"Laser Allround",NameLanguage:"EN",Price:Decimal(349),ProductID:"HT-1042",SupplierID:"0100000065",SupplierName:"Pateu",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(17),WeightUnit:"KG",Width:Decimal(53)}, + {Category:"Ink Jet Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(41),Description:"4800 dpi x 1200 dpi - up to 35 ppm (mono) / up to 34 ppm (color) - capacity: 250 sheets - Hi-Speed USB, Ethernet",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-igor.tarassow@retc.ru",Height:Decimal(28),MeasureUnit:"EA",Name:"Ultra Jet Super Color",NameLanguage:"EN",Price:Decimal(139),ProductID:"HT-1050",SupplierID:"0100000066",SupplierName:"Russian Electronic Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3),WeightUnit:"KG",Width:Decimal(41)}, + {Category:"Ink Jet Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(32),Description:"1000 dpi x 1000 dpi - up to 35 ppm (mono) / up to 34 ppm (color) - capacity: 250 sheets - Hi-Speed USB - excellent dimensions for the small office",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-alexis.harper@flor-hc.com",Height:Decimal(25),MeasureUnit:"EA",Name:"Ultra Jet Mobile",NameLanguage:"EN",Price:Decimal(99),ProductID:"HT-1051",SupplierID:"0100000067",SupplierName:"Florida Holiday Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.9),WeightUnit:"KG",Width:Decimal(46)}, + {Category:"Ink Jet Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(41),Description:"4800 dpi x 1200 dpi - up to 35 ppm (mono) / up to 34 ppm (color) - capacity: 250 sheets - Hi-Speed USB2.0, Ethernet",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-c.alfaro@quimica-madrilenos.es",Height:Decimal(28),MeasureUnit:"EA",Name:"Ultra Jet Super Highspeed",NameLanguage:"EN",Price:Decimal(170),ProductID:"HT-1052",SupplierID:"0100000068",SupplierName:"Quimica Madrilenos",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(18),WeightUnit:"KG",Width:Decimal(41)}, + {Category:"Multifunction Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(45),Description:"1000 dpi x 1000 dpi - up to 16 ppm (mono) / up to 15 ppm (color)- capacity 80 sheets - scanner (216 x 297 mm, 1200dpi x 2400dpi)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sven.j@getraenke-janssen.de",Height:Decimal(29),MeasureUnit:"EA",Name:"Multi Print",NameLanguage:"EN",Price:Decimal(99),ProductID:"HT-1055",SupplierID:"0100000069",SupplierName:"Getränkegroßhandel Janssen",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(6.3),WeightUnit:"KG",Width:Decimal(55)}, + {Category:"Multifunction Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(41.3),Description:"1200 dpi x 1200 dpi - up to 25 ppm (mono) / up to 24 ppm (color)- capacity 80 sheets - scanner (216 x 297 mm, 2400dpi x 4800dpi, high resolution)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-yoshiko.kakuji@jateco.jp",Height:Decimal(22),MeasureUnit:"EA",Name:"Multi Color",NameLanguage:"EN",Price:Decimal(119),ProductID:"HT-1056",SupplierID:"0100000070",SupplierName:"JaTeCo",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.3),WeightUnit:"KG",Width:Decimal(51)}, + {Category:"Mice",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(14.5),Description:"Cordless Optical USB Mice, Laptop, Color: Black, Plug&Play",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-alessio.galasso@tcdr.it",Height:Decimal(3.5),MeasureUnit:"EA",Name:"Cordless Mouse",NameLanguage:"EN",Price:Decimal(9),ProductID:"HT-1060",SupplierID:"0100000071",SupplierName:"Tessile Casa Di Roma",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.09),WeightUnit:"KG",Width:Decimal(6)}, + {Category:"Mice",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(15),Description:"Optical USB, PS/2 Mouse, Color: Blue, 3-button-functionality (incl. Scroll wheel)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-romain.le_mason@verdo.fr",Height:Decimal(3.1),MeasureUnit:"EA",Name:"Speed Mouse",NameLanguage:"EN",Price:Decimal(7),ProductID:"HT-1061",SupplierID:"0100000072",SupplierName:"Vente Et Réparation de Ordinateur",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.09),WeightUnit:"KG",Width:Decimal(7)}, + {Category:"Mice",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(7),Description:"Optical USB Mouse, Color: Red, 5-button-functionality(incl. Scroll wheel), Plug&Play",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-martha.calcagno@dpg.ar",Height:Decimal(4),MeasureUnit:"EA",Name:"Track Mouse",NameLanguage:"EN",Price:Decimal(11),ProductID:"HT-1062",SupplierID:"0100000073",SupplierName:"Developement Para O Governo",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.03),WeightUnit:"KG",Width:Decimal(3)}, + {Category:"Keyboards",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(21),Description:"Ergonomic USB Keyboard for Desktop, Plug&Play",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-beatriz.da_silva@brazil-tec.br",Height:Decimal(3.5),MeasureUnit:"EA",Name:"Ergonomic Keyboard",NameLanguage:"EN",Price:Decimal(14),ProductID:"HT-1063",SupplierID:"0100000074",SupplierName:"Brazil Technologies",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.1),WeightUnit:"KG",Width:Decimal(50)}, + {Category:"Keyboards",ChangedAt:"2025-01-24T10:40:00.226274",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(25),Description:"Corded Keyboard with special keys for Internet Usability, USB",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-anthony.lebouef@crtu.ca",Height:Decimal(3),MeasureUnit:"EA",Name:"Internet Keyboard",NameLanguage:"EN",Price:Decimal(18),ProductID:"HT-1064",SupplierID:"0100000075",SupplierName:"C.R.T.U.",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.8),WeightUnit:"KG",Width:Decimal(52)}, + {Category:"Keyboards",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(23),Description:"Corded Ergonomic Keyboard with special keys for Media Usability, USB",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-lisa.felske@jologa.ch",Height:Decimal(4),MeasureUnit:"EA",Name:"Media Keyboard",NameLanguage:"EN",Price:Decimal(26),ProductID:"HT-1065",SupplierID:"0100000076",SupplierName:"Jologa",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.3),WeightUnit:"KG",Width:Decimal(51.4)}, + {Category:"Mousepads",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6),Description:"Nice mouse pad with ITelO Logo",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jonathan.d.mason@baleda.com",Height:Decimal(0.2),MeasureUnit:"EA",Name:"Mousepad",NameLanguage:"EN",Price:Decimal(6.99),ProductID:"HT-1066",SupplierID:"0100000077",SupplierName:"Baleda",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(80),WeightUnit:"G",Width:Decimal(15)}, + {Category:"Mousepads",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6),Description:"Ergonomic mouse pad with ITelO Logo",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-amelie.troyat@angere.fr",Height:Decimal(0.2),MeasureUnit:"EA",Name:"Ergo Mousepad",NameLanguage:"EN",Price:Decimal(8.99),ProductID:"HT-1067",SupplierID:"0100000078",SupplierName:"Angeré",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(80),WeightUnit:"G",Width:Decimal(15)}, + {Category:"Mousepads",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(24),Description:"ITelO Mousepad Special Edition",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-pete_waltham@pc-gym-tec.com",Height:Decimal(0.6),MeasureUnit:"EA",Name:"Designer Mousepad",NameLanguage:"EN",Price:Decimal(12.99),ProductID:"HT-1068",SupplierID:"0100000079",SupplierName:"PC Gym Tec",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(90),WeightUnit:"G",Width:Decimal(24)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6),Description:"Universal card reader",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-ryu.toshiro@jip.jp",Height:Decimal(3),MeasureUnit:"EA",Name:"Universal card reader",NameLanguage:"EN",Price:Decimal(14),ProductID:"HT-1069",SupplierID:"0100000080",SupplierName:"Japan Insurance Partner",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(45),WeightUnit:"G",Width:Decimal(6)}, + {Category:"Graphic Cards",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(35),Description:"Proctra X: PCI-E GDDR5 3072MB",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jose-lopez@en-ar.ar",Height:Decimal(17),MeasureUnit:"EA",Name:"Proctra X",NameLanguage:"EN",Price:Decimal(70.9),ProductID:"HT-1070",SupplierID:"0100000081",SupplierName:"Entertainment Argentinia",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.255),WeightUnit:"KG",Width:Decimal(22)}, + {Category:"Graphic Cards",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(35),Description:"Gladiator XLN: PCI-E GDDR5 3072MB DVI Out, TV Out low-noise",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-dahoma.lawla@agadc.co.za",Height:Decimal(17),MeasureUnit:"EA",Name:"Gladiator MX",NameLanguage:"EN",Price:Decimal(81.7),ProductID:"HT-1071",SupplierID:"0100000082",SupplierName:"African Gold And Diamond Corporation",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.3),WeightUnit:"KG",Width:Decimal(22)}, + {Category:"Graphic Cards",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(35),Description:"Hurricane GX: PCI-E 691 GFLOPS game-optimized",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jefferson.parker@pico-bit.com",Height:Decimal(17),MeasureUnit:"EA",Name:"Hurricane GX",NameLanguage:"EN",Price:Decimal(101.2),ProductID:"HT-1072",SupplierID:"0100000083",SupplierName:"PicoBit",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.4),WeightUnit:"KG",Width:Decimal(22)}, + {Category:"Graphic Cards",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(35),Description:"Hurricane GX/LN: PCI-E 691 GFLOPS game-optimized, low-noise.",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-tamara.flaig@brl-ag.de",Height:Decimal(17),MeasureUnit:"EA",Name:"Hurricane GX/LN",NameLanguage:"EN",Price:Decimal(139.99),ProductID:"HT-1073",SupplierID:"0100000084",SupplierName:"Bionic Research Lab",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.4),WeightUnit:"KG",Width:Decimal(22)}, + {Category:"Scanners",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(48),Description:"Flatbed scanner - 9.600 × 9.600 dpi - 216 x 297 mm - Hi-Speed USB - Bluetooth",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sunita-kapoor@it-trade.in",Height:Decimal(5),MeasureUnit:"EA",Name:"Photo Scan",NameLanguage:"EN",Price:Decimal(129),ProductID:"HT-1080",SupplierID:"0100000085",SupplierName:"Indian IT Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.3),WeightUnit:"KG",Width:Decimal(34)}, + {Category:"Scanners",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(43),Description:"Flatbed scanner - 9.600 × 9.600 dpi - 216 x 297 mm - SCSI for backward compatibility",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-pawel-lewandoski@catf.pl",Height:Decimal(7),MeasureUnit:"EA",Name:"Power Scan",NameLanguage:"EN",Price:Decimal(89),ProductID:"HT-1081",SupplierID:"0100000086",SupplierName:"Chemia A Technicznie Fabryka",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.4),WeightUnit:"KG",Width:Decimal(31)}, + {Category:"Scanners",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(41),Description:"Flatbed scanner - Letter - 2400 dpi x 2400 dpi - 216 x 297 mm - add-on module",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-laura.campillo@saitc.ar",Height:Decimal(12),MeasureUnit:"EA",Name:"Jet Scan Professional",NameLanguage:"EN",Price:Decimal(169),ProductID:"HT-1082",SupplierID:"0100000087",SupplierName:"South American IT Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.2),WeightUnit:"KG",Width:Decimal(33)}, + {Category:"Scanners",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(40),Description:"Flatbed scanner - A4 - 2400 dpi x 2400 dpi - 216 x 297 mm - add-on module",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jian.si@siwusha.cn",Height:Decimal(10),MeasureUnit:"EA",Name:"Jet Scan Professional",NameLanguage:"EN",Price:Decimal(189),ProductID:"HT-1083",SupplierID:"0100000088",SupplierName:"Siwusha",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.2),WeightUnit:"KG",Width:Decimal(35)}, + {Category:"Multifunction Printers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(42),Description:"Copymaster",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-frederik.christensen@dftc.dk",Height:Decimal(22),MeasureUnit:"EA",Name:"Copymaster",NameLanguage:"EN",Price:Decimal(1499),ProductID:"HT-1085",SupplierID:"0100000089",SupplierName:"Danish Fish Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(23.2),WeightUnit:"KG",Width:Decimal(45)}, + {Category:"Speakers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(10),Description:"PC multimedia speakers - 5 Watt (Total)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-mirjam.schmidt@sorali.de",Height:Decimal(16),MeasureUnit:"EA",Name:"Surround Sound",NameLanguage:"EN",Price:Decimal(39),ProductID:"HT-1090",SupplierID:"0100000090",SupplierName:"Sorali",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3),WeightUnit:"KG",Width:Decimal(12)}, + {Category:"Speakers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(11),Description:"PC multimedia speakers - 10 Watt (Total) - 2-way",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-do.not.reply@sap.com",Height:Decimal(17.5),MeasureUnit:"EA",Name:"Blaster Extreme",NameLanguage:"EN",Price:Decimal(26),ProductID:"HT-1091",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.4),WeightUnit:"KG",Width:Decimal(13)}, + {Category:"Speakers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(10.4),Description:"PC multimedia speakers - optimized for Blutooth/A2DP",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-dagmar.schulze@beckerberlin.de",Height:Decimal(18.1),MeasureUnit:"EA",Name:"Sound Booster",NameLanguage:"EN",Price:Decimal(45),ProductID:"HT-1092",SupplierID:"0100000047",SupplierName:"Becker Berlin",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.1),WeightUnit:"KG",Width:Decimal(12.4)}, + {Category:"Headsets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(19),Description:"5.1 Headset, 40 Hz-20 kHz, Wireless",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-pete_waltham@pc-gym-tec.com",Height:Decimal(23),MeasureUnit:"EA",Name:"Lovely Sound 5.1 Wireless",NameLanguage:"EN",Price:Decimal(49),ProductID:"HT-1095",SupplierID:"0100000079",SupplierName:"PC Gym Tec",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(80),WeightUnit:"G",Width:Decimal(24)}, + {Category:"Headsets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(17),Description:"5.1 Headset, 40 Hz-20 kHz, 3m cable",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-ryu.toshiro@jip.jp",Height:Decimal(19),MeasureUnit:"EA",Name:"Lovely Sound 5.1",NameLanguage:"EN",Price:Decimal(39),ProductID:"HT-1096",SupplierID:"0100000080",SupplierName:"Japan Insurance Partner",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(130),WeightUnit:"G",Width:Decimal(25)}, + {Category:"Headsets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(2.4),Description:"5.1 Headset, 40 Hz-20 kHz, 1m cable",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jose-lopez@en-ar.ar",Height:Decimal(19.7),MeasureUnit:"EA",Name:"Lovely Sound Stereo",NameLanguage:"EN",Price:Decimal(29),ProductID:"HT-1097",SupplierID:"0100000081",SupplierName:"Entertainment Argentinia",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(60),WeightUnit:"G",Width:Decimal(21.3)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6.5),Description:"Complete package, 1 User, Office Applications (word processing, spreadsheet, presentations)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-maria.brown@delbont.com",Height:Decimal(2.1),MeasureUnit:"EA",Name:"Smart Office",NameLanguage:"EN",Price:Decimal(89.9),ProductID:"HT-1100",SupplierID:"0100000048",SupplierName:"DelBont Industries",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.2),WeightUnit:"KG",Width:Decimal(15)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6.7),Description:"Complete package, 1 User, Image editing, processing",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-saskia.sommer@talpa-hannover.de",Height:Decimal(24),MeasureUnit:"EA",Name:"Smart Design",NameLanguage:"EN",Price:Decimal(79.9),ProductID:"HT-1101",SupplierID:"0100000049",SupplierName:"Talpa",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.8),WeightUnit:"KG",Width:Decimal(14)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6),Description:"Complete package, 1 User, Network Software Utilities, Useful Applications and Documentation",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-bob.buyer@panorama-studios.biz",Height:Decimal(27),MeasureUnit:"EA",Name:"Smart Network",NameLanguage:"EN",Price:Decimal(69),ProductID:"HT-1102",SupplierID:"0100000050",SupplierName:"Panorama Studios",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.8),WeightUnit:"KG",Width:Decimal(16)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(3.4),Description:"Complete package, 1 User, different Multimedia applications, playing music, watching DVDs, only with this Smart package",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-bart.koenig@tecum-ag.de",Height:Decimal(22),MeasureUnit:"EA",Name:"Smart Multimedia",NameLanguage:"EN",Price:Decimal(77),ProductID:"HT-1103",SupplierID:"0100000051",SupplierName:"TECUM",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.8),WeightUnit:"KG",Width:Decimal(11)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(3),Description:"Complete package, 1 User, various games for amusement, logic, action, jump&run",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-yoko.nakamura@asia-ht.com",Height:Decimal(30),MeasureUnit:"EA",Name:"Smart Games",NameLanguage:"EN",Price:Decimal(55),ProductID:"HT-1104",SupplierID:"0100000052",SupplierName:"Asia High tech",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.1),WeightUnit:"KG",Width:Decimal(10)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(4),Description:"Complete package, 1 User, highly recommended for internet users as anti-virus protection",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sophie.ribery@laurent-paris.com",Height:Decimal(21),MeasureUnit:"EA",Name:"Smart Internet Antivirus",NameLanguage:"EN",Price:Decimal(29),ProductID:"HT-1105",SupplierID:"0100000053",SupplierName:"Laurent",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.7),WeightUnit:"KG",Width:Decimal(16)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(4.2),Description:"Complete package, 1 User, recommended for internet users, protect your PC against cyber-crime",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-victor.sanchez@avantel.com",Height:Decimal(23.1),MeasureUnit:"EA",Name:"Smart Firewall",NameLanguage:"EN",Price:Decimal(34),ProductID:"HT-1106",SupplierID:"0100000054",SupplierName:"AVANTEL",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.9),WeightUnit:"KG",Width:Decimal(17.9)}, + {Category:"Software",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(1.5),Description:"Complete package, 1 User, bring your money in your mind, see what you have and what you want",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jorge.velez@telecomunicacionesstar.com",Height:Decimal(19),MeasureUnit:"EA",Name:"Smart Money",NameLanguage:"EN",Price:Decimal(29.9),ProductID:"HT-1107",SupplierID:"0100000055",SupplierName:"Telecomunicaciones Star",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.5),WeightUnit:"KG",Width:Decimal(12)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(8),Description:"Robust 3m anti-burglary protection for your laptop computer",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-franklin.jones@pear-computing.com",Height:Decimal(4.3),MeasureUnit:"EA",Name:"PC Lock",NameLanguage:"EN",Price:Decimal(8.9),ProductID:"HT-1110",SupplierID:"0100000056",SupplierName:"Pear Computing Services",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.03),WeightUnit:"KG",Width:Decimal(20)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(9),Description:"Robust 1m anti-burglary protection for your desktop computer",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-joseph_gschwandtner@alp-systems.at",Height:Decimal(7),MeasureUnit:"EA",Name:"Notebook Lock",NameLanguage:"EN",Price:Decimal(6.9),ProductID:"HT-1111",SupplierID:"0100000057",SupplierName:"Alpine Systems",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.02),WeightUnit:"KG",Width:Decimal(31)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(8.2),Description:"Color webcam, color, High-Speed USB",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-george_d_grant@newlinedesign.co.uk",Height:Decimal(1.3),MeasureUnit:"EA",Name:"Web cam reality",NameLanguage:"EN",Price:Decimal(39),ProductID:"HT-1112",SupplierID:"0100000058",SupplierName:"New Line Design",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.075),WeightUnit:"KG",Width:Decimal(9)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(2),Description:"10 separately packed screen wipes",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sarah.schwind@hepa-tec.de",Height:Decimal(0.1),MeasureUnit:"EA",Name:"Screen clean",NameLanguage:"EN",Price:Decimal(2.3),ProductID:"HT-1113",SupplierID:"0100000059",SupplierName:"HEPA Tec",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.05),WeightUnit:"KG",Width:Decimal(2)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(32),Description:"Notebook bag, plenty of room for stationery and writing materials",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-theodor.monathy@anavideon.com",Height:Decimal(7),MeasureUnit:"EA",Name:"Fabric bag professional",NameLanguage:"EN",Price:Decimal(31),ProductID:"HT-1114",SupplierID:"0100000060",SupplierName:"Anav Ideon",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.8),WeightUnit:"KG",Width:Decimal(42)}, + {Category:"Telecommunications",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(18),Description:"Wireless DSL Router (available in blue, black and silver)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-robert_brown@rb-entertainment.ca",Height:Decimal(5),MeasureUnit:"EA",Name:"Wireless DSL Router",NameLanguage:"EN",Price:Decimal(49),ProductID:"HT-1115",SupplierID:"0100000061",SupplierName:"Robert Brown Entertainment",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.45),WeightUnit:"KG",Width:Decimal(19.3)}, + {Category:"Telecommunications",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(18),Description:"Wireless DSL Router / Repeater (available in blue, black and silver)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jorgemontalban@motc.mx",Height:Decimal(5),MeasureUnit:"EA",Name:"Wireless DSL Router / Repeater",NameLanguage:"EN",Price:Decimal(59),ProductID:"HT-1116",SupplierID:"0100000062",SupplierName:"Mexican Oil Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.45),WeightUnit:"KG",Width:Decimal(19.3)}, + {Category:"Telecommunications",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(18),Description:"Wireless DSL Router / Repeater and Print Server (available in blue, black and silver)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-johanna.esther@meliva.de",Height:Decimal(5),MeasureUnit:"EA",Name:"Wireless DSL Router / Repeater and Print Server",NameLanguage:"EN",Price:Decimal(69),ProductID:"HT-1117",SupplierID:"0100000063",SupplierName:"Meliva",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.45),WeightUnit:"KG",Width:Decimal(19.3)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(8.7),Description:"USB 2.0 High-Speed 64 GB",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-miguel.luengo@compostela.ar",Height:Decimal(1.2),MeasureUnit:"EA",Name:"USB Stick",NameLanguage:"EN",Price:Decimal(35),ProductID:"HT-1118",SupplierID:"0100000064",SupplierName:"Compostela",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.015),WeightUnit:"KG",Width:Decimal(1.5)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(3.1),Description:"Universal Travel Adapter",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-franklin.jones@pear-computing.com",Height:Decimal(3.9),MeasureUnit:"EA",Name:"Travel Adapter",NameLanguage:"EN",Price:Decimal(79),ProductID:"HT-1119",SupplierID:"0100000056",SupplierName:"Pear Computing Services",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(88),WeightUnit:"G",Width:Decimal(2)}, + {Category:"Keyboards",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(23),Description:"Cordless Bluetooth Keyboard with English keys",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-isabel.nemours@pateu.fr",Height:Decimal(4),MeasureUnit:"EA",Name:"Cordless Bluetooth Keyboard, english international",NameLanguage:"EN",Price:Decimal(29),ProductID:"HT-1120",SupplierID:"0100000065",SupplierName:"Pateu",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1),WeightUnit:"KG",Width:Decimal(51.4)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(22),Description:"Optimum Hi-Resolution max. 2048 × 1536 @ 85Hz, Dot Pitch: 0.24mm",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-igor.tarassow@retc.ru",Height:Decimal(38),MeasureUnit:"EA",Name:"Flat XXL",NameLanguage:"EN",Price:Decimal(1430),ProductID:"HT-1137",SupplierID:"0100000066",SupplierName:"Russian Electronic Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(18),WeightUnit:"KG",Width:Decimal(54)}, + {Category:"Mice",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(0.5),Description:"Portable pocket Mouse with retracting cord",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-alexis.harper@flor-hc.com",Height:Decimal(1),MeasureUnit:"EA",Name:"Pocket Mouse",NameLanguage:"EN",Price:Decimal(23),ProductID:"HT-1138",SupplierID:"0100000067",SupplierName:"Florida Holiday Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.02),WeightUnit:"KG",Width:Decimal(0.3)}, + {Category:"PCs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"PC Power Station with 3,4 Ghz quad-core, 32 GB DDR3 SDRAM, feels like a PC, Windows 8 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-c.alfaro@quimica-madrilenos.es",Height:Decimal(43),MeasureUnit:"EA",Name:"PC Power Station",NameLanguage:"EN",Price:Decimal(2399),ProductID:"HT-1210",SupplierID:"0100000068",SupplierName:"Quimica Madrilenos",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.3),WeightUnit:"KG",Width:Decimal(28)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(18),Description:"Flexible Laptop with 2,5 GHz Quad Core, 15"" HD TN, 16 GB DDR SDRAM, 256 GB SSD, Windows 10 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-alessio.galasso@tcdr.it",Height:Decimal(3),MeasureUnit:"EA",Name:"Astro Laptop 1516",NameLanguage:"EN",Price:Decimal(989),ProductID:"HT-1251",SupplierID:"0100000071",SupplierName:"Tessile Casa Di Roma",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.2),WeightUnit:"KG",Width:Decimal(30)}, + {Category:"Smartphones",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6),Description:"6 inch 1280x800 HD display (216 ppi), Quad-core processor, 8 GB internal storage (actual formatted capacity will be less), 3050 mAh battery (Up to 8 hours of active use), grey or black",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-romain.le_mason@verdo.fr",Height:Decimal(1.5),MeasureUnit:"EA",Name:"Astro Phone 6",NameLanguage:"EN",Price:Decimal(649),ProductID:"HT-1252",SupplierID:"0100000072",SupplierName:"Vente Et Réparation de Ordinateur",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.75),WeightUnit:"KG",Width:Decimal(8)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(18),Description:"Flexible Laptop with 2,5 GHz Dual Core, 14"" HD+ TN, 8 GB DDR SDRAM, 324 GB SSD, Windows 10 Pro",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-martha.calcagno@dpg.ar",Height:Decimal(3),MeasureUnit:"EA",Name:"Benda Laptop 1408",NameLanguage:"EN",Price:Decimal(976),ProductID:"HT-1253",SupplierID:"0100000073",SupplierName:"Developement Para O Governo",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.2),WeightUnit:"KG",Width:Decimal(30)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(12),Description:"Optimum Hi-Resolution Widescreen max. 1920 x 1080 @ 85Hz, Dot Pitch: 0.27mm, HDMI, D-Sub",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-beatriz.da_silva@brazil-tec.br",Height:Decimal(36),MeasureUnit:"EA",Name:"Bending Screen 21HD",NameLanguage:"EN",Price:Decimal(250),ProductID:"HT-1254",SupplierID:"0100000074",SupplierName:"Brazil Technologies",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(15),WeightUnit:"KG",Width:Decimal(37)}, + {Category:"Flat Screen Monitors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(12),Description:"Optimum Hi-Resolution Widescreen max. 2048 x 1080 @ 85Hz, Dot Pitch: 0.27mm, HDMI, D-Sub",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-anthony.lebouef@crtu.ca",Height:Decimal(38),MeasureUnit:"EA",Name:"Broad Screen 22HD",NameLanguage:"EN",Price:Decimal(270),ProductID:"HT-1255",SupplierID:"0100000075",SupplierName:"C.R.T.U.",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(16),WeightUnit:"KG",Width:Decimal(39)}, + {Category:"Smartphones",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(15),Description:"7 inch 1280x800 HD display (216 ppi), Quad-core processor, 16 GB internal storage (actual formatted capacity will be less), 4325 mAh battery (Up to 8 hours of active use), white or black",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-lisa.felske@jologa.ch",Height:Decimal(1.5),MeasureUnit:"EA",Name:"Cerdik Phone 7",NameLanguage:"EN",Price:Decimal(549),ProductID:"HT-1256",SupplierID:"0100000076",SupplierName:"Jologa",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.75),WeightUnit:"KG",Width:Decimal(9)}, + {Category:"Tablets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"10.5-inch Multitouch HD Screen (1280 x 800), 16GB Internal Memory, Wireless N Wi-Fi; Bluetooth, GPS Enabled, 1GHz Dual-Core Processor",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jonathan.d.mason@baleda.com",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Cepat Tablet 10.5",NameLanguage:"EN",Price:Decimal(549),ProductID:"HT-1257",SupplierID:"0100000077",SupplierName:"Baleda",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.8),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Tablets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(21),Description:"8-inch Multitouch HD Screen (2000 x 1500) 32GB Internal Memory, Wireless N Wi-Fi, Bluetooth, GPS Enabled, 1.5 GHz Quad-Core Processor",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-amelie.troyat@angere.fr",Height:Decimal(3.5),MeasureUnit:"EA",Name:"Cepat Tablet 8",NameLanguage:"EN",Price:Decimal(529),ProductID:"HT-1258",SupplierID:"0100000078",SupplierName:"Angeré",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.5),WeightUnit:"KG",Width:Decimal(38)}, + {Category:"Servers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(35),Description:"Dual socket, quad-core processing server with 1333 MHz Front Side Bus with 10Gb connectivity",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sven.j@getraenke-janssen.de",Height:Decimal(23),MeasureUnit:"EA",Name:"Server Basic",NameLanguage:"EN",Price:Decimal(5000),ProductID:"HT-1500",SupplierID:"0100000069",SupplierName:"Getränkegroßhandel Janssen",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(18),WeightUnit:"KG",Width:Decimal(34)}, + {Category:"Servers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(30),Description:"Dual socket, quad-core processing server with 1644 MHz Front Side Bus with 10Gb connectivity",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-yoshiko.kakuji@jateco.jp",Height:Decimal(27),MeasureUnit:"EA",Name:"Server Professional",NameLanguage:"EN",Price:Decimal(15000),ProductID:"HT-1501",SupplierID:"0100000070",SupplierName:"JaTeCo",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(25),WeightUnit:"KG",Width:Decimal(29)}, + {Category:"Servers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(27.3),Description:"Dual socket, quad-core processing server with 1644 MHz Front Side Bus with 100Gb connectivity",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-alessio.galasso@tcdr.it",Height:Decimal(37),MeasureUnit:"EA",Name:"Server Power Pro",NameLanguage:"EN",Price:Decimal(25000),ProductID:"HT-1502",SupplierID:"0100000071",SupplierName:"Tessile Casa Di Roma",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(35),WeightUnit:"KG",Width:Decimal(22)}, + {Category:"PCs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(29),Description:"2,8 Ghz dual core, 4 GB DDR3 SDRAM, 500 GB Hard Disc, Graphic Card: Proctra X, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jorge.velez@telecomunicacionesstar.com",Height:Decimal(38),MeasureUnit:"EA",Name:"Family PC Basic",NameLanguage:"EN",Price:Decimal(600),ProductID:"HT-1600",SupplierID:"0100000055",SupplierName:"Telecomunicaciones Star",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.8),WeightUnit:"KG",Width:Decimal(21.4)}, + {Category:"PCs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31.7),Description:"2,8 Ghz dual core, 4 GB DDR3 SDRAM, 1000 GB Hard Disc, Graphic Card: Gladiator MX, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-victor.sanchez@avantel.com",Height:Decimal(40.2),MeasureUnit:"EA",Name:"Family PC Pro",NameLanguage:"EN",Price:Decimal(900),ProductID:"HT-1601",SupplierID:"0100000054",SupplierName:"AVANTEL",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(5.3),WeightUnit:"KG",Width:Decimal(25)}, + {Category:"PCs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(34),Description:"3,4 Ghz quad core, 8 GB DDR3 SDRAM, 2000 GB Hard Disc, Graphic Card: Gladiator MX, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sophie.ribery@laurent-paris.com",Height:Decimal(47),MeasureUnit:"EA",Name:"Gaming Monster",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-1602",SupplierID:"0100000053",SupplierName:"Laurent",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(5.9),WeightUnit:"KG",Width:Decimal(26.5)}, + {Category:"PCs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(28),Description:"3,4 Ghz quad core, 16 GB DDR3 SDRAM, 4000 GB Hard Disc, Graphic Card: Hurricane GX, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-yoko.nakamura@asia-ht.com",Height:Decimal(42),MeasureUnit:"EA",Name:"Gaming Monster Pro",NameLanguage:"EN",Price:Decimal(1700),ProductID:"HT-1603",SupplierID:"0100000052",SupplierName:"Asia High tech",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(6.8),WeightUnit:"KG",Width:Decimal(27)}, + {Category:"Portable Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(19),Description:"7"" LCD Screen, storage battery holds up to 6 hours!",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-bart.koenig@tecum-ag.de",Height:Decimal(27.6),MeasureUnit:"EA",Name:"7"" Widescreen Portable DVD Player w MP3",NameLanguage:"EN",Price:Decimal(249.99),ProductID:"HT-2000",SupplierID:"0100000051",SupplierName:"TECUM",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.79),WeightUnit:"KG",Width:Decimal(21.4)}, + {Category:"Portable Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(19.5),Description:"10"" LCD Screen, storage battery holds up to 8 hours",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-bob.buyer@panorama-studios.biz",Height:Decimal(29),MeasureUnit:"EA",Name:"10"" Portable DVD player",NameLanguage:"EN",Price:Decimal(449.99),ProductID:"HT-2001",SupplierID:"0100000050",SupplierName:"Panorama Studios",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.84),WeightUnit:"KG",Width:Decimal(24)}, + {Category:"Portable Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(16.5),Description:"9"" LCD Screen, storage holds up to 8 hours, 2 speakers included",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-mirjam.schmidt@sorali.de",Height:Decimal(14),MeasureUnit:"EA",Name:"Portable DVD Player with 9"" LCD Monitor",NameLanguage:"EN",Price:Decimal(853.99),ProductID:"HT-2002",SupplierID:"0100000090",SupplierName:"Sorali",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.72),WeightUnit:"KG",Width:Decimal(21)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(13),Description:"Organizer and protective case for 264 CDs and DVDs",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-saskia.sommer@talpa-hannover.de",Height:Decimal(20),MeasureUnit:"EA",Name:"CD/DVD case: 264 sleeves",NameLanguage:"EN",Price:Decimal(44.99),ProductID:"HT-2025",SupplierID:"0100000049",SupplierName:"Talpa",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.65),WeightUnit:"KG",Width:Decimal(13)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(10.2),Description:"Quality cables for notebooks and projectors",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-maria.brown@delbont.com",Height:Decimal(13),MeasureUnit:"EA",Name:"Audio/Video Cable Kit - 4m",NameLanguage:"EN",Price:Decimal(29.99),ProductID:"HT-2026",SupplierID:"0100000048",SupplierName:"DelBont Industries",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.2),WeightUnit:"KG",Width:Decimal(21)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(2),Description:"Removable jewel case labels, zero residues (100)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-dagmar.schulze@beckerberlin.de",Height:Decimal(2),MeasureUnit:"EA",Name:"Removable CD/DVD Laser Labels",NameLanguage:"EN",Price:Decimal(8.99),ProductID:"HT-2027",SupplierID:"0100000047",SupplierName:"Becker Berlin",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.15),WeightUnit:"KG",Width:Decimal(5.5)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T02:21:33.471027",CreatedAt:"2025-01-24T02:21:33.471027",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3691",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T02:31:21.579804",CreatedAt:"2025-01-24T02:31:21.579804",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3692",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T04:13:07.847993",CreatedAt:"2025-01-24T04:13:07.847993",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3693",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T04:17:27.253551",CreatedAt:"2025-01-24T04:17:27.253551",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3694",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T06:19:17.443068",CreatedAt:"2025-01-24T06:19:17.443068",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3695",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T06:56:30.088125",CreatedAt:"2025-01-24T06:56:30.088125",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3696",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T07:27:28.37042",CreatedAt:"2025-01-24T07:27:28.37042",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3697",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T07:52:10.898056",CreatedAt:"2025-01-24T07:52:10.898056",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3698",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T07:57:58.083724",CreatedAt:"2025-01-24T07:57:58.083724",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3699",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T07:58:51.04519",CreatedAt:"2025-01-24T07:58:51.04519",CurrencyCode:"USD",Depth:Decimal(0),Description:"High-performance laptop",DescriptionLanguage:"EN",DimUnit:"",Email:"supplier-do.not.reply@sap.com",Height:Decimal(0),MeasureUnit:"EA",Name:"Example Product",NameLanguage:"EN",Price:Decimal(1200),ProductID:"HT-3700",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0),WeightUnit:"",Width:Decimal(0)}, + {Category:"Projectors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(23.1),Description:"720p, DLP Projector max. 8,45 Meter, 2D",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-do.not.reply@sap.com",Height:Decimal(23),MeasureUnit:"EA",Name:"Beam Breaker B-1",NameLanguage:"EN",Price:Decimal(469),ProductID:"HT-6100",SupplierID:"0100000046",SupplierName:"SAP",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.7),WeightUnit:"KG",Width:Decimal(30.4)}, + {Category:"Projectors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(23.1),Description:"1080p, DLP max.9,34 Meter, 2D-ready",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-frederik.christensen@dftc.dk",Height:Decimal(23),MeasureUnit:"EA",Name:"Beam Breaker B-2",NameLanguage:"EN",Price:Decimal(679),ProductID:"HT-6101",SupplierID:"0100000089",SupplierName:"Danish Fish Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2),WeightUnit:"KG",Width:Decimal(30.4)}, + {Category:"Projectors",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(23.1),Description:"1080p, DLP max. 12,3 Meter, 3D-ready",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jian.si@siwusha.cn",Height:Decimal(23),MeasureUnit:"EA",Name:"Beam Breaker B-3",NameLanguage:"EN",Price:Decimal(889),ProductID:"HT-6102",SupplierID:"0100000088",SupplierName:"Siwusha",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.5),WeightUnit:"KG",Width:Decimal(30.4)}, + {Category:"Portable Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(24),Description:"CD-RW, DVD+R/RW, DVD-R/RW, MPEG 2 (Video-DVD), MPEG 4, VCD, SVCD, DivX, Xvid",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-laura.campillo@saitc.ar",Height:Decimal(6),MeasureUnit:"EA",Name:"Play Movie",NameLanguage:"EN",Price:Decimal(130),ProductID:"HT-6110",SupplierID:"0100000087",SupplierName:"South American IT Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.4),WeightUnit:"KG",Width:Decimal(37)}, + {Category:"Portable Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(26),Description:"160 GB HDD, CD-RW, DVD+R/RW, DVD-R/RW, MPEG 2 (Video-DVD), MPEG 4, VCD, SVCD, DivX, Xvid",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-pawel-lewandoski@catf.pl",Height:Decimal(6.2),MeasureUnit:"EA",Name:"Record Movie",NameLanguage:"EN",Price:Decimal(288),ProductID:"HT-6111",SupplierID:"0100000086",SupplierName:"Chemia A Technicznie Fabryka",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.1),WeightUnit:"KG",Width:Decimal(38)}, + {Category:"MP3 Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6),Description:"64 GB USB Music-on-a-Stick",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sunita-kapoor@it-trade.in",Height:Decimal(1),MeasureUnit:"EA",Name:"ITelo MusicStick",NameLanguage:"EN",Price:Decimal(45),ProductID:"HT-6120",SupplierID:"0100000085",SupplierName:"Indian IT Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(134),WeightUnit:"G",Width:Decimal(1.5)}, + {Category:"MP3 Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(8),Description:"ITelo Jog-Mate 64 GB HDD and Color Display, can play movies",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-tamara.flaig@brl-ag.de",Height:Decimal(9.2),MeasureUnit:"EA",Name:"ITelo Jog-Mate",NameLanguage:"EN",Price:Decimal(63),ProductID:"HT-6121",SupplierID:"0100000084",SupplierName:"Bionic Research Lab",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(134),WeightUnit:"G",Width:Decimal(5.1)}, + {Category:"MP3 Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(8),Description:"MP3-Player with 40 GB HDD and Color Display, can play movies",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jefferson.parker@pico-bit.com",Height:Decimal(9.2),MeasureUnit:"EA",Name:"Power Pro Player 40",NameLanguage:"EN",Price:Decimal(167),ProductID:"HT-6122",SupplierID:"0100000083",SupplierName:"PicoBit",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(266),WeightUnit:"G",Width:Decimal(5.1)}, + {Category:"MP3 Players",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(6),Description:"MP3-Player with 80 GB SSD and Color Display, can play movies",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-dahoma.lawla@agadc.co.za",Height:Decimal(0.8),MeasureUnit:"EA",Name:"Power Pro Player 80",NameLanguage:"EN",Price:Decimal(299),ProductID:"HT-6123",SupplierID:"0100000082",SupplierName:"African Gold And Diamond Corporation",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(267),WeightUnit:"G",Width:Decimal(4)}, + {Category:"Flat Screen TVs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(22.1),Description:"32-inch, 1366x768 Pixel, 16:9, HDTV ready",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-romain.le_mason@verdo.fr",Height:Decimal(55),MeasureUnit:"EA",Name:"Flat Watch HD32",NameLanguage:"EN",Price:Decimal(1459),ProductID:"HT-6130",SupplierID:"0100000072",SupplierName:"Vente Et Réparation de Ordinateur",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.6),WeightUnit:"KG",Width:Decimal(78)}, + {Category:"Flat Screen TVs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(26),Description:"37-inch, 1366x768 Pixel, 16:9, HDTV ready",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-martha.calcagno@dpg.ar",Height:Decimal(61),MeasureUnit:"EA",Name:"Flat Watch HD37",NameLanguage:"EN",Price:Decimal(1199),ProductID:"HT-6131",SupplierID:"0100000073",SupplierName:"Developement Para O Governo",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(2.2),WeightUnit:"KG",Width:Decimal(99.1)}, + {Category:"Flat Screen TVs",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(23),Description:"41-inch, 1366x768 Pixel, 16:9, HDTV ready",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-beatriz.da_silva@brazil-tec.br",Height:Decimal(79.1),MeasureUnit:"EA",Name:"Flat Watch HD41",NameLanguage:"EN",Price:Decimal(899),ProductID:"HT-6132",SupplierID:"0100000074",SupplierName:"Brazil Technologies",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(1.8),WeightUnit:"KG",Width:Decimal(128)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(13),Description:"Our new multifunctional Handheld with phone function in copper",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-amelie.troyat@angere.fr",Height:Decimal(12.1),MeasureUnit:"EA",Name:"Copperberry",NameLanguage:"EN",Price:Decimal(549),ProductID:"HT-7000",SupplierID:"0100000078",SupplierName:"Angeré",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.5),WeightUnit:"KG",Width:Decimal(8.1)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(13),Description:"Our new multifunctional Handheld with phone function in silver",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jonathan.d.mason@baleda.com",Height:Decimal(12.1),MeasureUnit:"EA",Name:"Silverberry",NameLanguage:"EN",Price:Decimal(549),ProductID:"HT-7010",SupplierID:"0100000077",SupplierName:"Baleda",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.5),WeightUnit:"KG",Width:Decimal(8.1)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(13),Description:"Our new multifunctional Handheld with phone function in gold",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-lisa.felske@jologa.ch",Height:Decimal(12.1),MeasureUnit:"EA",Name:"Goldberry",NameLanguage:"EN",Price:Decimal(549),ProductID:"HT-7020",SupplierID:"0100000076",SupplierName:"Jologa",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.5),WeightUnit:"KG",Width:Decimal(8.1)}, + {Category:"PDAs & Organizers",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(13),Description:"Our new multifunctional Handheld with phone function in platinum",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-anthony.lebouef@crtu.ca",Height:Decimal(12.1),MeasureUnit:"EA",Name:"Platinberry",NameLanguage:"EN",Price:Decimal(549),ProductID:"HT-7030",SupplierID:"0100000075",SupplierName:"C.R.T.U.",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.5),WeightUnit:"KG",Width:Decimal(8.1)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(19),Description:"Notebook with 2,80 GHz dual core, 4 GB DDR3 SDRAM, 500 GB Hard Disc, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-joseph_gschwandtner@alp-systems.at",Height:Decimal(3.1),MeasureUnit:"EA",Name:"ITelO FlexTop I4000",NameLanguage:"EN",Price:Decimal(799),ProductID:"HT-8000",SupplierID:"0100000057",SupplierName:"Alpine Systems",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4),WeightUnit:"KG",Width:Decimal(31)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(20),Description:"Notebook with 2,80 GHz dual core, 8 GB DDR3 SDRAM, 500 GB Hard Disc, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-george_d_grant@newlinedesign.co.uk",Height:Decimal(3.4),MeasureUnit:"EA",Name:"ITelO FlexTop I6300c",NameLanguage:"EN",Price:Decimal(999),ProductID:"HT-8001",SupplierID:"0100000058",SupplierName:"New Line Design",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(4.2),WeightUnit:"KG",Width:Decimal(32)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(21),Description:"Notebook with 2,80 GHz quad core, 4 GB DDR3 SDRAM, 1000 GB Hard Disc, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sarah.schwind@hepa-tec.de",Height:Decimal(4.1),MeasureUnit:"EA",Name:"ITelO FlexTop I9100",NameLanguage:"EN",Price:Decimal(1199),ProductID:"HT-8002",SupplierID:"0100000059",SupplierName:"HEPA Tec",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.5),WeightUnit:"KG",Width:Decimal(38)}, + {Category:"Notebooks",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"Notebook with 2,80 GHz quad core, 8 GB DDR3 SDRAM, 1000 GB Hard Disc, Windows 8",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-theodor.monathy@anavideon.com",Height:Decimal(4.5),MeasureUnit:"EA",Name:"ITelO FlexTop I9800",NameLanguage:"EN",Price:Decimal(1388),ProductID:"HT-8003",SupplierID:"0100000060",SupplierName:"Anav Ideon",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.8),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"Button Clasp, Quality Material, 100% Leather, compatible with many smartphone models",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-yoshiko.kakuji@jateco.jp",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Smartphone Leather Case",NameLanguage:"EN",Price:Decimal(25),ProductID:"HT-9991",SupplierID:"0100000070",SupplierName:"JaTeCo",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.02),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Smartphones",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"7 inch 1280x800 HD display (216 ppi), Quad-core processor, 16 GB internal storage (actual formatted capacity will be less), 4325 mAh battery (Up to 8 hours of active use), white or black",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-sven.j@getraenke-janssen.de",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Smartphone Alpha",NameLanguage:"EN",Price:Decimal(599),ProductID:"HT-9992",SupplierID:"0100000069",SupplierName:"Getränkegroßhandel Janssen",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.75),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Tablets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"7 inch 1280x800 HD display (216 ppi), Quad-core processor, 16 GB internal storage, 4325 mAh battery (Up to 8 hours of active use)",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-c.alfaro@quimica-madrilenos.es",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Mini Tablet",NameLanguage:"EN",Price:Decimal(833),ProductID:"HT-9993",SupplierID:"0100000068",SupplierName:"Quimica Madrilenos",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.8),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Camcorders",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"1920x1080 Full HD, image stabilization reduces blur, 27x Optical / 32x Extended Zoom, wide angle Lens, 2.7"" wide LCD display",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-alexis.harper@flor-hc.com",Height:Decimal(27),MeasureUnit:"EA",Name:"Camcorder View",NameLanguage:"EN",Price:Decimal(1388),ProductID:"HT-9994",SupplierID:"0100000067",SupplierName:"Florida Holiday Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.8),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"Durable high quality plastic bump-sleeve, lightweight, protects from scratches, rubber coating, multiple colors available, Accurate design and cut-outs for your device, snap-on design",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-igor.tarassow@retc.ru",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Smartphone Cover",NameLanguage:"EN",Price:Decimal(15),ProductID:"HT-9995",SupplierID:"0100000066",SupplierName:"Russian Electronic Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.02),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(40),Description:"Stylish tablet pouch, protects from scratches, color: black",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-isabel.nemours@pateu.fr",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Tablet Pouch",NameLanguage:"EN",Price:Decimal(20),ProductID:"HT-9996",SupplierID:"0100000065",SupplierName:"Pateu",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.03),WeightUnit:"KG",Width:Decimal(25)}, + {Category:"Tablets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"6-Inch E Ink Screen, Access To e-book Store, Adjustable Font Styles and Sizes, Stores Up To 1,000 Books",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-miguel.luengo@compostela.ar",Height:Decimal(4.5),MeasureUnit:"EA",Name:"e-Book Reader ReadMe",NameLanguage:"EN",Price:Decimal(633),ProductID:"HT-9997",SupplierID:"0100000064",SupplierName:"Compostela",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.8),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Smartphones",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"5 Megapixel Camera, Wi-Fi 802.11 b/g/n, Bluetooth, GPS A-GPS support",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-johanna.esther@meliva.de",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Smartphone Beta",NameLanguage:"EN",Price:Decimal(699),ProductID:"HT-9998",SupplierID:"0100000063",SupplierName:"Meliva",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(0.75),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Tablets",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(31),Description:"10.1-inch Multitouch HD Screen (1280 x 800), 16GB Internal Memory, Wireless N Wi-Fi; Bluetooth, GPS Enabled, 1GHz Dual-Core Processor",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-jorgemontalban@motc.mx",Height:Decimal(4.5),MeasureUnit:"EA",Name:"Maxi Tablet",NameLanguage:"EN",Price:Decimal(749),ProductID:"HT-9999",SupplierID:"0100000062",SupplierName:"Mexican Oil Trading Company",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"PR",WeightMeasure:Decimal(3.8),WeightUnit:"KG",Width:Decimal(48)}, + {Category:"Computer System Accessories",ChangedAt:"2025-01-24T01:00:57",CreatedAt:"2025-01-24T01:00:57",CurrencyCode:"USD",Depth:Decimal(30),Description:"Flyer for our product palette",DescriptionLanguage:"EN",DimUnit:"CM",Email:"supplier-robert_brown@rb-entertainment.ca",Height:Decimal(3),MeasureUnit:"EA",Name:"Flyer",NameLanguage:"EN",Price:Decimal(0),ProductID:"PF-1000",SupplierID:"0100000061",SupplierName:"Robert Brown Entertainment",TaxTarifCode:Decimal(1),ToSalesOrderLineItems:{},ToSupplier:If(false,First(FirstN(BusinessPartnerSet,0))),TypeCode:"AD",WeightMeasure:Decimal(0.01),WeightUnit:"KG",Width:Decimal(46)} + ) + */ + } + [Fact] public async Task SQL_CdpTabular() { diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PublicSurfaceTests.cs b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PublicSurfaceTests.cs index 93323a70df..07e029cce3 100644 --- a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PublicSurfaceTests.cs +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PublicSurfaceTests.cs @@ -55,6 +55,7 @@ public void PublicSurfaceTest_Connectors() "Microsoft.PowerFx.Connectors.MetadataDynamicValues", "Microsoft.PowerFx.Connectors.MetadataParameter", "Microsoft.PowerFx.Connectors.MetadataTabular", + "Microsoft.PowerFx.Connectors.NavigationProperty", "Microsoft.PowerFx.Connectors.ODataParameters", "Microsoft.PowerFx.Connectors.OpenApiExtensions", "Microsoft.PowerFx.Connectors.OpenApiParser", diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP GetTables 2.json b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP GetTables 2.json new file mode 100644 index 0000000000..33075fc533 --- /dev/null +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP GetTables 2.json @@ -0,0 +1,165 @@ +{ + "@odata.context": "https://49970107-0806-e5a7-be5e-7c60e2750f01.12.common.firstrelease.azure-apihub.net/apim/sapodata/b5097592f2ae498ea32458b1035634a9/datasets/https%253A%252F%252Fsapes5.sapdevcenter.com%252Fsap%252Fopu%252Fodata%252Fiwbep%252FGWSAMPLE_BASIC%252F/tables", + "value": [ + { + "Name": "BusinessPartnerSet", + "DisplayName": "BusinessPartnerSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "ProductSet", + "DisplayName": "ProductSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "SalesOrderSet", + "DisplayName": "SalesOrderSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "SalesOrderLineItemSet", + "DisplayName": "SalesOrderLineItemSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "ContactSet", + "DisplayName": "ContactSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_SexSet", + "DisplayName": "VH_SexSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_CountrySet", + "DisplayName": "VH_CountrySet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_AddressTypeSet", + "DisplayName": "VH_AddressTypeSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_CategorySet", + "DisplayName": "VH_CategorySet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_CurrencySet", + "DisplayName": "VH_CurrencySet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_UnitQuantitySet", + "DisplayName": "VH_UnitQuantitySet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_UnitWeightSet", + "DisplayName": "VH_UnitWeightSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_UnitLengthSet", + "DisplayName": "VH_UnitLengthSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_ProductTypeCodeSet", + "DisplayName": "VH_ProductTypeCodeSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_BPRoleSet", + "DisplayName": "VH_BPRoleSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + }, + { + "Name": "VH_LanguageSet", + "DisplayName": "VH_LanguageSet", + "tables": [ + ], + "procedures": [ + ], + "query": [ + ] + } + ] +} \ No newline at end of file diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_BusinessPartnerSet_Schema.json b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_BusinessPartnerSet_Schema.json new file mode 100644 index 0000000000..b11b20d032 --- /dev/null +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_BusinessPartnerSet_Schema.json @@ -0,0 +1,507 @@ +{ + "name": "BusinessPartnerSet", + "title": "BusinessPartnerSet", + "x-ms-permission": "read-write", + "x-ms-capabilities": { + "sortRestrictions": { + "sortable": true, + "unsortableProperties": [], + "ascendingOnlyProperties": [] + }, + "filterRestrictions": { + "filterable": true, + "nonFilterableProperties": [], + "requiredProperties": [] + }, + "selectRestrictions": { "selectable": true }, + "isOnlyServerPagable": true, + "supportsJoin": true, + "filterFunctionSupport": [ "eq", "ne", "joinleft", "odataexpand" ], + "serverPagingOptions": [ "skiptoken" ] + }, + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Address": { + "type": "object", + "properties": { + "City": { + "title": "City", + "description": "City", + "type": "string" + }, + "PostalCode": { + "title": "PostalCode", + "description": "Postal Code", + "type": "string" + }, + "Street": { + "title": "Street", + "description": "Street", + "type": "string" + }, + "Building": { + "title": "Building", + "description": "Building", + "type": "string" + }, + "Country": { + "title": "Country", + "description": "Country", + "type": "string" + }, + "AddressType": { + "title": "AddressType", + "description": "Address Type", + "type": "string" + } + } + }, + "BusinessPartnerID": { + "title": "BusinessPartnerID", + "description": "Bus. Part. ID", + "type": "string", + "required": [ + "BusinessPartnerID" + ], + "x-ms-keyType": "primary", + "x-ms-keyOrder": 0, + "x-ms-capabilities": { "filterFunctions": [ "eq" ] } + }, + "CompanyName": { + "title": "CompanyName", + "description": "Company Name", + "type": "string", + "required": [ + "CompanyName" + ] + }, + "WebAddress": { + "title": "WebAddress", + "description": "Web Address", + "type": "string" + }, + "EmailAddress": { + "title": "EmailAddress", + "description": "E-Mail Address", + "type": "string", + "required": [ + "EmailAddress" + ] + }, + "PhoneNumber": { + "title": "PhoneNumber", + "description": "Phone No.", + "type": "string" + }, + "FaxNumber": { + "title": "FaxNumber", + "description": "Fax Number", + "type": "string" + }, + "LegalForm": { + "title": "LegalForm", + "description": "Legal Form", + "type": "string" + }, + "CurrencyCode": { + "title": "CurrencyCode", + "description": "Currency", + "type": "string", + "required": [ + "CurrencyCode" + ] + }, + "BusinessPartnerRole": { + "title": "BusinessPartnerRole", + "description": "Bus. Part. Role", + "type": "string", + "required": [ + "BusinessPartnerRole" + ] + }, + "CreatedAt": { + "title": "CreatedAt", + "description": "Time Stamp", + "type": "string" + }, + "ChangedAt": { + "title": "ChangedAt", + "description": "Time Stamp", + "type": "string" + }, + "ToSalesOrders": { + "type": "array", + "items": { + "type": "object", + "properties": { + "SalesOrderID": { + "title": "SalesOrderID", + "description": "Sa. Ord. ID", + "type": "string", + "required": [ + "SalesOrderID" + ] + }, + "Note": { + "title": "Note", + "description": "Description", + "type": "string" + }, + "NoteLanguage": { + "title": "NoteLanguage", + "description": "Language", + "type": "string" + }, + "CustomerID": { + "title": "CustomerID", + "description": "Bus. Part. ID", + "type": "string", + "required": [ + "CustomerID" + ] + }, + "CustomerName": { + "title": "CustomerName", + "description": "Company Name", + "type": "string" + }, + "CurrencyCode": { + "title": "CurrencyCode", + "description": "Currency", + "type": "string" + }, + "GrossAmount": { + "title": "GrossAmount", + "description": "Gross Amt.", + "type": "number" + }, + "NetAmount": { + "title": "NetAmount", + "description": "Net Amt.", + "type": "number" + }, + "TaxAmount": { + "title": "TaxAmount", + "description": "Tax Amt.", + "type": "number" + }, + "LifecycleStatus": { + "title": "LifecycleStatus", + "description": "PO Lifecycle", + "type": "string" + }, + "LifecycleStatusDescription": { + "title": "LifecycleStatusDescription", + "description": "Lifecycle Descript.", + "type": "string" + }, + "BillingStatus": { + "title": "BillingStatus", + "description": "PO Confirmation", + "type": "string" + }, + "BillingStatusDescription": { + "title": "BillingStatusDescription", + "description": "Billing Description", + "type": "string" + }, + "DeliveryStatus": { + "title": "DeliveryStatus", + "description": "PO Ordering", + "type": "string" + }, + "DeliveryStatusDescription": { + "title": "DeliveryStatusDescription", + "description": "Delivery Description", + "type": "string" + }, + "CreatedAt": { + "title": "CreatedAt", + "description": "Time Stamp", + "type": "string" + }, + "ChangedAt": { + "title": "ChangedAt", + "description": "Time Stamp", + "type": "string" + } + } + } + }, + "ToContacts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Address": { + "type": "object", + "properties": { + "City": { + "title": "City", + "description": "City", + "type": "string" + }, + "PostalCode": { + "title": "PostalCode", + "description": "Postal Code", + "type": "string" + }, + "Street": { + "title": "Street", + "description": "Street", + "type": "string" + }, + "Building": { + "title": "Building", + "description": "Building", + "type": "string" + }, + "Country": { + "title": "Country", + "description": "Country", + "type": "string" + }, + "AddressType": { + "title": "AddressType", + "description": "Address Type", + "type": "string" + } + } + }, + "ContactGuid": { + "title": "ContactGuid", + "description": "Contact GUID", + "type": "string", + "required": [ + "ContactGuid" + ] + }, + "BusinessPartnerID": { + "title": "BusinessPartnerID", + "description": "Bus. Part. ID", + "type": "string", + "required": [ + "BusinessPartnerID" + ] + }, + "Title": { + "title": "Title", + "description": "Title", + "type": "string" + }, + "FirstName": { + "title": "FirstName", + "description": "First Name", + "type": "string", + "required": [ + "FirstName" + ] + }, + "MiddleName": { + "title": "MiddleName", + "description": "Middle Name", + "type": "string" + }, + "LastName": { + "title": "LastName", + "description": "Last Name", + "type": "string" + }, + "Nickname": { + "title": "Nickname", + "description": "Nickname", + "type": "string" + }, + "Initials": { + "title": "Initials", + "description": "Initials", + "type": "string" + }, + "Sex": { + "title": "Sex", + "description": "Sex", + "type": "string", + "required": [ + "Sex" + ] + }, + "PhoneNumber": { + "title": "PhoneNumber", + "description": "Phone No.", + "type": "string" + }, + "FaxNumber": { + "title": "FaxNumber", + "description": "Fax Number", + "type": "string" + }, + "EmailAddress": { + "title": "EmailAddress", + "description": "E-Mail Address", + "type": "string" + }, + "Language": { + "title": "Language", + "description": "Language Key", + "type": "string" + }, + "DateOfBirth": { + "title": "DateOfBirth", + "description": "Date of Birth", + "type": "string" + } + } + } + }, + "ToProducts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ProductID": { + "title": "ProductID", + "description": "Product ID", + "type": "string", + "required": [ + "ProductID" + ] + }, + "TypeCode": { + "title": "TypeCode", + "description": "Prod. Type Code", + "type": "string", + "required": [ + "TypeCode" + ] + }, + "Category": { + "title": "Category", + "description": "Prod. Cat.", + "type": "string", + "required": [ + "Category" + ] + }, + "Name": { + "title": "Name", + "description": "Product Name", + "type": "string", + "required": [ + "Name" + ] + }, + "NameLanguage": { + "title": "NameLanguage", + "description": "Language", + "type": "string" + }, + "Description": { + "title": "Description", + "description": "Prod.Descrip.", + "type": "string" + }, + "DescriptionLanguage": { + "title": "DescriptionLanguage", + "description": "Language", + "type": "string" + }, + "SupplierID": { + "title": "SupplierID", + "description": "Bus. Part. ID", + "type": "string", + "required": [ + "SupplierID" + ] + }, + "SupplierName": { + "title": "SupplierName", + "description": "Company Name", + "type": "string" + }, + "TaxTarifCode": { + "title": "TaxTarifCode", + "description": "Prod. Tax Code", + "type": "integer", + "required": [ + "TaxTarifCode" + ] + }, + "MeasureUnit": { + "title": "MeasureUnit", + "description": "Qty. Unit", + "type": "string", + "required": [ + "MeasureUnit" + ] + }, + "WeightMeasure": { + "title": "WeightMeasure", + "description": "Wt. Measure", + "type": "number" + }, + "WeightUnit": { + "title": "WeightUnit", + "description": "Qty. Unit", + "type": "string" + }, + "CurrencyCode": { + "title": "CurrencyCode", + "description": "Currency", + "type": "string", + "required": [ + "CurrencyCode" + ] + }, + "Price": { + "title": "Price", + "description": "Unit Price", + "type": "number" + }, + "Width": { + "title": "Width", + "description": "Dimensions", + "type": "number" + }, + "Depth": { + "title": "Depth", + "description": "Dimensions", + "type": "number" + }, + "Height": { + "title": "Height", + "description": "Dimensions", + "type": "number" + }, + "DimUnit": { + "title": "DimUnit", + "description": "Dim. Unit", + "type": "string" + }, + "CreatedAt": { + "title": "CreatedAt", + "description": "Time Stamp", + "type": "string" + }, + "ChangedAt": { + "title": "ChangedAt", + "description": "Time Stamp", + "type": "string" + } + } + } + } + }, + "required": [ + "BusinessPartnerID", + "CompanyName", + "EmailAddress", + "CurrencyCode", + "BusinessPartnerRole" + ] + } + }, + "webUrl": "https://49970107-0806-e5a7-be5e-7c60e2750f01.12.common.firstrelease.azure-apihub.net/apim/sapodata/b5097592f2ae498ea32458b1035634a9/$metadata.json/datasets/https%253A%252F%252Fsapes5.sapdevcenter.com%252Fsap%252Fopu%252Fodata%252Fiwbep%252FGWSAMPLE_BASIC%252F/tables/BusinessPartnerSet?api-version=2015-09-01" +} \ No newline at end of file diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_ProductSet_Schema.json b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_ProductSet_Schema.json new file mode 100644 index 0000000000..57b429ca5d --- /dev/null +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_ProductSet_Schema.json @@ -0,0 +1,191 @@ +{ + "name": "ProductSet", + "title": "ProductSet", + "x-ms-permission": "read-write", + "x-ms-capabilities": { + "sortRestrictions": { + "sortable": true, + "unsortableProperties": [], + "ascendingOnlyProperties": [] + }, + "filterRestrictions": { + "filterable": true, + "nonFilterableProperties": [], + "requiredProperties": [] + }, + "selectRestrictions": { "selectable": true }, + "isOnlyServerPagable": true, + "supportsJoin": true, + "filterFunctionSupport": [ "eq", "ne", "joinleft", "odataexpand" ], + "serverPagingOptions": [ "skiptoken" ] + }, + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ProductID": { + "title": "ProductID", + "description": "Product ID", + "type": "string", + "required": [ + "ProductID" + ] + }, + "TypeCode": { + "title": "TypeCode", + "description": "Prod. Type Code", + "type": "string", + "required": [ + "TypeCode" + ] + }, + "Category": { + "title": "Category", + "description": "Prod. Cat.", + "type": "string", + "required": [ + "Category" + ] + }, + "Name": { + "title": "Name", + "description": "Product Name", + "type": "string", + "required": [ + "Name" + ] + }, + "NameLanguage": { + "title": "NameLanguage", + "description": "Language", + "type": "string" + }, + "Description": { + "title": "Description", + "description": "Prod.Descrip.", + "type": "string" + }, + "DescriptionLanguage": { + "title": "DescriptionLanguage", + "description": "Language", + "type": "string" + }, + "SupplierID": { + "title": "SupplierID", + "description": "Bus. Part. ID", + "type": "string", + "required": [ + "SupplierID" + ], + "x-ms-capabilities": { "filterFunctions": [ "eq" ] } + }, + "SupplierName": { + "title": "SupplierName", + "description": "Company Name", + "type": "string" + }, + "TaxTarifCode": { + "title": "TaxTarifCode", + "description": "Prod. Tax Code", + "type": "integer", + "required": [ + "TaxTarifCode" + ] + }, + "MeasureUnit": { + "title": "MeasureUnit", + "description": "Qty. Unit", + "type": "string", + "required": [ + "MeasureUnit" + ] + }, + "WeightMeasure": { + "title": "WeightMeasure", + "description": "Wt. Measure", + "type": "number" + }, + "WeightUnit": { + "title": "WeightUnit", + "description": "Qty. Unit", + "type": "string" + }, + "CurrencyCode": { + "title": "CurrencyCode", + "description": "Currency", + "type": "string", + "required": [ + "CurrencyCode" + ] + }, + "Price": { + "title": "Price", + "description": "Unit Price", + "type": "number" + }, + "Width": { + "title": "Width", + "description": "Dimensions", + "type": "number" + }, + "Depth": { + "title": "Depth", + "description": "Dimensions", + "type": "number" + }, + "Height": { + "title": "Height", + "description": "Dimensions", + "type": "number" + }, + "DimUnit": { + "title": "DimUnit", + "description": "Dim. Unit", + "type": "string" + }, + "CreatedAt": { + "title": "CreatedAt", + "description": "Time Stamp", + "type": "string" + }, + "ChangedAt": { + "title": "ChangedAt", + "description": "Time Stamp", + "type": "string" + }, + "ToSupplier": { + "type": "object", + "datatype": "reference", + "referenceTo": [ "BusinessPartnerSet" ], + "sourceField": "SupplierID", + "destinationKey": "BusinessPartnerID", + "relationshipType": "ManyToOne", + "relationshipName": "Assoc_BusinessPartner_Products", + "properties": {} + }, + "ToSalesOrderLineItems": { + "type": "object", + "datatype": "reference", + "referenceTo": [ "SalesOrderLineItemSet" ], + "sourceField": "ProductID", + "destinationKey": "ProductID", + "relationshipType": "OneToMany", + "relationshipName": "Assoc_Product_SalesOrderLineItems", + "properties": {} + } + }, + "required": [ + "ProductID", + "TypeCode", + "Category", + "Name", + "SupplierID", + "TaxTarifCode", + "MeasureUnit", + "CurrencyCode" + ] + } + }, + "webUrl": "https://49970107-0806-e5a7-be5e-7c60e2750f01.12.common.firstrelease.azure-apihub.net/apim/sapodata/b5097592f2ae498ea32458b1035634a9/$metadata.json/datasets/https%253A%252F%252Fsapes5.sapdevcenter.com%252Fsap%252Fopu%252Fodata%252Fiwbep%252FGWSAMPLE_BASIC%252F/tables/ProductSet?api-version=2015-09-01" +} \ No newline at end of file diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_SalesOrderLineItemSet_Schema.json b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_SalesOrderLineItemSet_Schema.json new file mode 100644 index 0000000000..187c96bb8b --- /dev/null +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/Responses/SAP_SalesOrderLineItemSet_Schema.json @@ -0,0 +1,353 @@ +{ + "name": "SalesOrderLineItemSet", + "title": "SalesOrderLineItemSet", + "x-ms-permission": "read-write", + "x-ms-capabilities": { + "sortRestrictions": { + "sortable": true, + "unsortableProperties": [ + ], + "ascendingOnlyProperties": [ + ] + }, + "filterRestrictions": { + "filterable": true, + "nonFilterableProperties": [ + ], + "requiredProperties": [ + ] + }, + "selectRestrictions": { + "selectable": true + }, + "isOnlyServerPagable": true, + "filterFunctionSupport": [ + "eq", + "ne" + ], + "serverPagingOptions": [ + "skiptoken" + ] + }, + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "SalesOrderID": { + "title": "SalesOrderID", + "description": "Sa. Ord. ID", + "type": "string", + "required": [ + "SalesOrderID" + ] + }, + "ItemPosition": { + "title": "ItemPosition", + "description": "PO Item Pos", + "type": "string", + "required": [ + "ItemPosition" + ] + }, + "ProductID": { + "title": "ProductID", + "description": "Product ID", + "type": "string", + "required": [ + "ProductID" + ] + }, + "Note": { + "title": "Note", + "description": "Description", + "type": "string" + }, + "NoteLanguage": { + "title": "NoteLanguage", + "description": "Language", + "type": "string" + }, + "CurrencyCode": { + "title": "CurrencyCode", + "description": "Currency", + "type": "string" + }, + "GrossAmount": { + "title": "GrossAmount", + "description": "Gross Amt.", + "type": "number" + }, + "NetAmount": { + "title": "NetAmount", + "description": "Net Amt.", + "type": "number" + }, + "TaxAmount": { + "title": "TaxAmount", + "description": "Tax Amt.", + "type": "number" + }, + "DeliveryDate": { + "title": "DeliveryDate", + "description": "Time Stamp", + "type": "string", + "required": [ + "DeliveryDate" + ] + }, + "Quantity": { + "title": "Quantity", + "description": "Quantity", + "type": "number", + "required": [ + "Quantity" + ] + }, + "QuantityUnit": { + "title": "QuantityUnit", + "description": "Qty. Unit", + "type": "string" + }, + "ToHeader": { + "type": "object", + "properties": { + "SalesOrderID": { + "title": "SalesOrderID", + "description": "Sa. Ord. ID", + "type": "string", + "required": [ + "SalesOrderID" + ] + }, + "Note": { + "title": "Note", + "description": "Description", + "type": "string" + }, + "NoteLanguage": { + "title": "NoteLanguage", + "description": "Language", + "type": "string" + }, + "CustomerID": { + "title": "CustomerID", + "description": "Bus. Part. ID", + "type": "string", + "required": [ + "CustomerID" + ] + }, + "CustomerName": { + "title": "CustomerName", + "description": "Company Name", + "type": "string" + }, + "CurrencyCode": { + "title": "CurrencyCode", + "description": "Currency", + "type": "string" + }, + "GrossAmount": { + "title": "GrossAmount", + "description": "Gross Amt.", + "type": "number" + }, + "NetAmount": { + "title": "NetAmount", + "description": "Net Amt.", + "type": "number" + }, + "TaxAmount": { + "title": "TaxAmount", + "description": "Tax Amt.", + "type": "number" + }, + "LifecycleStatus": { + "title": "LifecycleStatus", + "description": "PO Lifecycle", + "type": "string" + }, + "LifecycleStatusDescription": { + "title": "LifecycleStatusDescription", + "description": "Lifecycle Descript.", + "type": "string" + }, + "BillingStatus": { + "title": "BillingStatus", + "description": "PO Confirmation", + "type": "string" + }, + "BillingStatusDescription": { + "title": "BillingStatusDescription", + "description": "Billing Description", + "type": "string" + }, + "DeliveryStatus": { + "title": "DeliveryStatus", + "description": "PO Ordering", + "type": "string" + }, + "DeliveryStatusDescription": { + "title": "DeliveryStatusDescription", + "description": "Delivery Description", + "type": "string" + }, + "CreatedAt": { + "title": "CreatedAt", + "description": "Time Stamp", + "type": "string" + }, + "ChangedAt": { + "title": "ChangedAt", + "description": "Time Stamp", + "type": "string" + } + } + }, + "ToProduct": { + "type": "object", + "properties": { + "ProductID": { + "title": "ProductID", + "description": "Product ID", + "type": "string", + "required": [ + "ProductID" + ] + }, + "TypeCode": { + "title": "TypeCode", + "description": "Prod. Type Code", + "type": "string", + "required": [ + "TypeCode" + ] + }, + "Category": { + "title": "Category", + "description": "Prod. Cat.", + "type": "string", + "required": [ + "Category" + ] + }, + "Name": { + "title": "Name", + "description": "Product Name", + "type": "string", + "required": [ + "Name" + ] + }, + "NameLanguage": { + "title": "NameLanguage", + "description": "Language", + "type": "string" + }, + "Description": { + "title": "Description", + "description": "Prod.Descrip.", + "type": "string" + }, + "DescriptionLanguage": { + "title": "DescriptionLanguage", + "description": "Language", + "type": "string" + }, + "SupplierID": { + "title": "SupplierID", + "description": "Bus. Part. ID", + "type": "string", + "required": [ + "SupplierID" + ] + }, + "SupplierName": { + "title": "SupplierName", + "description": "Company Name", + "type": "string" + }, + "TaxTarifCode": { + "title": "TaxTarifCode", + "description": "Prod. Tax Code", + "type": "integer", + "required": [ + "TaxTarifCode" + ] + }, + "MeasureUnit": { + "title": "MeasureUnit", + "description": "Qty. Unit", + "type": "string", + "required": [ + "MeasureUnit" + ] + }, + "WeightMeasure": { + "title": "WeightMeasure", + "description": "Wt. Measure", + "type": "number" + }, + "WeightUnit": { + "title": "WeightUnit", + "description": "Qty. Unit", + "type": "string" + }, + "CurrencyCode": { + "title": "CurrencyCode", + "description": "Currency", + "type": "string", + "required": [ + "CurrencyCode" + ] + }, + "Price": { + "title": "Price", + "description": "Unit Price", + "type": "number" + }, + "Width": { + "title": "Width", + "description": "Dimensions", + "type": "number" + }, + "Depth": { + "title": "Depth", + "description": "Dimensions", + "type": "number" + }, + "Height": { + "title": "Height", + "description": "Dimensions", + "type": "number" + }, + "DimUnit": { + "title": "DimUnit", + "description": "Dim. Unit", + "type": "string" + }, + "CreatedAt": { + "title": "CreatedAt", + "description": "Time Stamp", + "type": "string" + }, + "ChangedAt": { + "title": "ChangedAt", + "description": "Time Stamp", + "type": "string" + } + } + } + }, + "required": [ + "SalesOrderID", + "ItemPosition", + "ProductID", + "DeliveryDate", + "Quantity" + ] + } + }, + "webUrl": "https://49970107-0806-e5a7-be5e-7c60e2750f01.12.common.firstrelease.azure-apihub.net/apim/sapodata/b5097592f2ae498ea32458b1035634a9/$metadata.json/datasets/https%253A%252F%252Fsapes5.sapdevcenter.com%252Fsap%252Fopu%252Fodata%252Fiwbep%252FGWSAMPLE_BASIC%252F/tables/SalesOrderLineItemSet?api-version=2015-09-01" +} \ No newline at end of file diff --git a/src/tests/Microsoft.PowerFx.Core.Tests.Shared/PublicSurfaceTests.cs b/src/tests/Microsoft.PowerFx.Core.Tests.Shared/PublicSurfaceTests.cs index 484d1bd13c..2ccfdb1cec 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests.Shared/PublicSurfaceTests.cs +++ b/src/tests/Microsoft.PowerFx.Core.Tests.Shared/PublicSurfaceTests.cs @@ -18,7 +18,7 @@ public void PublicSurface_Tests() { var asm = typeof(Parser.TexlParser).Assembly; - // The goal for public namespaces is to make the SDK easy for the consumer. + // The goal for public namespaces is to make the SDK easy for the consumer. // Namespace principles for public classes: // - prefer fewer namespaces. See C# for example: https://docs.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis // - For easy discovery, but Engine in "Microsoft.PowerFx". @@ -27,7 +27,7 @@ public void PublicSurface_Tests() var allowed = new HashSet() { - // Core namespace. + // Core namespace. "Microsoft.PowerFx.CheckResult", "Microsoft.PowerFx.DefinitionsCheckResult", "Microsoft.PowerFx.CheckContextSummary", @@ -58,8 +58,8 @@ public void PublicSurface_Tests() "Microsoft.PowerFx.SymbolProperties", "Microsoft.PowerFx.SymbolEntry", "Microsoft.PowerFx.DeferredSymbolPlaceholder", - - // Lexer + + // Lexer "Microsoft.PowerFx.Syntax.BinaryOp", "Microsoft.PowerFx.Syntax.CommentToken", "Microsoft.PowerFx.Syntax.DecLitToken", @@ -101,13 +101,13 @@ public void PublicSurface_Tests() "Microsoft.PowerFx.Syntax.VariadicBase", "Microsoft.PowerFx.Syntax.VariadicOpNode", "Microsoft.PowerFx.Syntax.TypeLiteralNode", - + // Visitors "Microsoft.PowerFx.Syntax.IdentityTexlVisitor", "Microsoft.PowerFx.Syntax.TexlFunctionalVisitor`2", "Microsoft.PowerFx.Syntax.TexlVisitor", - // Power Fx Type system and Values. + // Power Fx Type system and Values. "Microsoft.PowerFx.Types.AggregateType", "Microsoft.PowerFx.Types.BindingErrorType", "Microsoft.PowerFx.Types.BlankType", @@ -168,9 +168,9 @@ public void PublicSurface_Tests() "Microsoft.PowerFx.Types.ValidFormulaValue", "Microsoft.PowerFx.Types.Void", "Microsoft.PowerFx.Types.VoidValue", - + // Intellisense classes. Used primarily by the Language Service Provider. - // Most evaluators should never need these. + // Most evaluators should never need these. "Microsoft.PowerFx.Intellisense.CodeFixHandler", "Microsoft.PowerFx.Intellisense.CodeFixSuggestion", "Microsoft.PowerFx.Intellisense.ConnectorSuggestion", @@ -199,7 +199,9 @@ public void PublicSurface_Tests() "Microsoft.PowerFx.Core.Entities.ColumnCapabilitiesDefinition", "Microsoft.PowerFx.Core.Entities.FilterRestrictions", "Microsoft.PowerFx.Core.Entities.GroupRestrictions", - "Microsoft.PowerFx.Core.Entities.IRefreshable", + "Microsoft.PowerFx.Core.Entities.INavigationProperty", + "Microsoft.PowerFx.Core.Entities.IRefreshable", + "Microsoft.PowerFx.Core.Entities.ISupportsNavigationProperties", "Microsoft.PowerFx.Core.Entities.SelectionRestrictions", "Microsoft.PowerFx.Core.Entities.SortRestrictions", "Microsoft.PowerFx.Core.Entities.CountCapabilities", @@ -234,7 +236,7 @@ public void PublicSurface_Tests() Assert.True(count == 0, $"Unexpected public types: {sb}"); - // Types we expect to be in the assembly are all there. + // Types we expect to be in the assembly are all there. Assert.Empty(allowed); } @@ -264,7 +266,7 @@ public void NoTransportInPublicTypes() } } - // Assert DocumentErrorSeverity and ErrorSeverity are in sync. + // Assert DocumentErrorSeverity and ErrorSeverity are in sync. [Fact] public void ErrorSeverityEnumsMatch() {