Skip to content

Commit 2f419c5

Browse files
committed
fixes for copilot reviews and add complex support for picklist attribute type
1 parent 2d8fabb commit 2f419c5

2 files changed

Lines changed: 27 additions & 13 deletions

File tree

src/PowerPlatform/Dataverse/data/_odata.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,12 @@ def _build_localizedlabels_payload(self, translations: Dict[int, str]) -> Dict[s
13641364
}
13651365

13661366
def _enum_optionset_payload(
1367-
self, column_schema_name: str, enum_cls: type[Enum], is_primary_name: bool = False
1367+
self,
1368+
column_schema_name: str,
1369+
enum_cls: type[Enum],
1370+
is_primary_name: bool = False,
1371+
*,
1372+
complex: bool = False,
13681373
) -> Dict[str, Any]:
13691374
"""Create local (IsGlobal=False) PicklistAttributeMetadata from an Enum subclass.
13701375
@@ -1375,7 +1380,14 @@ def _enum_optionset_payload(
13751380
Keys inside per-language dict may be either enum member objects or their names.
13761381
If a language lacks a label for a member, member.name is used as fallback.
13771382
The client's configured language code is always ensured to exist.
1383+
1384+
:param complex: When ``True``, emit ``ComplexPicklistAttributeMetadata`` /
1385+
``ComplexOptionSetMetadata`` types required by the ``CreateEntities``
1386+
action. When ``False`` (default), emit the standard types used by the
1387+
``EntityDefinitions/{id}/Attributes`` endpoint.
13781388
"""
1389+
prefix = "Microsoft.Dynamics.CRM.Complex" if complex else "Microsoft.Dynamics.CRM."
1390+
13791391
all_member_items = list(enum_cls.__members__.items())
13801392
if not all_member_items:
13811393
raise ValueError(f"Enum {enum_cls.__name__} has no members")
@@ -1436,21 +1448,21 @@ def _enum_optionset_payload(
14361448
per_lang[lang] = label_text
14371449
options.append(
14381450
{
1439-
"@odata.type": "Microsoft.Dynamics.CRM.OptionMetadata",
1451+
"@odata.type": f"{prefix}.OptionMetadata",
14401452
"Value": m.value,
14411453
"Label": self._build_localizedlabels_payload(per_lang),
14421454
}
14431455
)
14441456

14451457
attr_label = column_schema_name.split("_")[-1]
14461458
return {
1447-
"@odata.type": "Microsoft.Dynamics.CRM.PicklistAttributeMetadata",
1459+
"@odata.type": f"{prefix}PicklistAttributeMetadata",
14481460
"SchemaName": column_schema_name,
14491461
"DisplayName": self._label(attr_label),
14501462
"RequiredLevel": {"Value": "None"},
14511463
"IsPrimaryName": bool(is_primary_name),
14521464
"OptionSet": {
1453-
"@odata.type": "Microsoft.Dynamics.CRM.OptionSetMetadata",
1465+
"@odata.type": f"{prefix}OptionSetMetadata",
14541466
"IsGlobal": False,
14551467
"Options": options,
14561468
},
@@ -1597,7 +1609,9 @@ def _attribute_payload(
15971609
"""
15981610
# Enum-based local option set support
15991611
if isinstance(dtype, type) and issubclass(dtype, Enum):
1600-
return self._enum_optionset_payload(column_schema_name, dtype, is_primary_name=is_primary_name)
1612+
return self._enum_optionset_payload(
1613+
column_schema_name, dtype, is_primary_name=is_primary_name, complex=complex
1614+
)
16011615
if not isinstance(dtype, str):
16021616
raise ValueError(
16031617
f"Unsupported column spec type for '{column_schema_name}': {type(dtype)} (expected str or Enum subclass)"

tests/unit/data/test_odata_internal.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,7 +1519,7 @@ def test_int_dtype(self):
15191519
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.IntegerAttributeMetadata")
15201520

15211521
def test_complex_int_dtype(self):
1522-
"""'int' produces ComplexIntegerAttributeMetadata."""
1522+
"""'int' with complex=True produces ComplexIntegerAttributeMetadata."""
15231523
result = self.od._attribute_payload("new_Count", "int", complex=True)
15241524
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexIntegerAttributeMetadata")
15251525

@@ -1534,7 +1534,7 @@ def test_decimal_dtype(self):
15341534
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.DecimalAttributeMetadata")
15351535

15361536
def test_complex_decimal_dtype(self):
1537-
"""'decimal' produces ComplexDecimalAttributeMetadata."""
1537+
"""'decimal' with complex=True produces ComplexDecimalAttributeMetadata."""
15381538
result = self.od._attribute_payload("new_Price", "decimal", complex=True)
15391539
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexDecimalAttributeMetadata")
15401540

@@ -1549,7 +1549,7 @@ def test_float_dtype(self):
15491549
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.DoubleAttributeMetadata")
15501550

15511551
def test_complex_float_dtype(self):
1552-
"""'float' produces ComplexDoubleAttributeMetadata."""
1552+
"""'float' with complex=True produces ComplexDoubleAttributeMetadata."""
15531553
result = self.od._attribute_payload("new_Score", "float", complex=True)
15541554
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexDoubleAttributeMetadata")
15551555

@@ -1564,7 +1564,7 @@ def test_datetime_dtype(self):
15641564
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.DateTimeAttributeMetadata")
15651565

15661566
def test_complex_datetime_dtype(self):
1567-
"""'datetime' produces ComplexDateTimeAttributeMetadata."""
1567+
"""'datetime' with complex=True produces ComplexDateTimeAttributeMetadata."""
15681568
result = self.od._attribute_payload("new_CreatedDate", "datetime", complex=True)
15691569
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexDateTimeAttributeMetadata")
15701570

@@ -1579,7 +1579,7 @@ def test_bool_dtype(self):
15791579
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.BooleanAttributeMetadata")
15801580

15811581
def test_complex_bool_dtype(self):
1582-
"""'bool' produces ComplexBooleanAttributeMetadata."""
1582+
"""'bool' with complex=True produces ComplexBooleanAttributeMetadata."""
15831583
result = self.od._attribute_payload("new_IsActive", "bool", complex=True)
15841584
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexBooleanAttributeMetadata")
15851585

@@ -1594,7 +1594,7 @@ def test_file_dtype(self):
15941594
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.FileAttributeMetadata")
15951595

15961596
def test_complex_file_dtype(self):
1597-
"""'file' produces ComplexFileAttributeMetadata."""
1597+
"""'file' with complex=True produces ComplexFileAttributeMetadata."""
15981598
result = self.od._attribute_payload("new_Attachment", "file", complex=True)
15991599
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexFileAttributeMetadata")
16001600

@@ -1613,7 +1613,7 @@ def test_memo_type(self):
16131613
self.assertNotIn("IsPrimaryName", result)
16141614

16151615
def test_complex_memo_type(self):
1616-
"""'memo' produces ComplexMemoAttributeMetadata with MaxLength 4000."""
1616+
"""'memo' with complex=True produces ComplexMemoAttributeMetadata with MaxLength 4000."""
16171617
result = self.od._attribute_payload("new_Notes", "memo", complex=True)
16181618
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexMemoAttributeMetadata")
16191619
self.assertEqual(result["SchemaName"], "new_Notes")
@@ -1635,7 +1635,7 @@ def test_string_type_max_length(self):
16351635
self.assertEqual(result["FormatName"], {"Value": "Text"})
16361636

16371637
def test_complex_string_type_max_length(self):
1638-
"""'string' produces ComplexStringAttributeMetadata with MaxLength 200."""
1638+
"""'string' with complex=True produces ComplexStringAttributeMetadata with MaxLength 200."""
16391639
result = self.od._attribute_payload("new_Title", "string", complex=True)
16401640
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexStringAttributeMetadata")
16411641
self.assertEqual(result["MaxLength"], 200)

0 commit comments

Comments
 (0)