stepxmlclient 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stepxmlclient/__init__.py +22 -0
- stepxmlclient/client.py +373 -0
- stepxmlclient/creator.py +317 -0
- stepxmlclient/model/__init__.py +418 -0
- stepxmlclient/model/asset.py +250 -0
- stepxmlclient/model/attribute.py +288 -0
- stepxmlclient/model/business.py +233 -0
- stepxmlclient/model/classification.py +409 -0
- stepxmlclient/model/complex_elements.py +260 -0
- stepxmlclient/model/deletion.py +87 -0
- stepxmlclient/model/entity.py +368 -0
- stepxmlclient/model/metadata.py +199 -0
- stepxmlclient/model/organization.py +167 -0
- stepxmlclient/model/product.py +519 -0
- stepxmlclient/model/relations.py +105 -0
- stepxmlclient/model/replacement.py +417 -0
- stepxmlclient/parser.py +2805 -0
- stepxmlclient/rest_client/__init__.py +16 -0
- stepxmlclient/rest_client/base.py +388 -0
- stepxmlclient/rest_client/client.py +127 -0
- stepxmlclient/rest_client/exceptions.py +97 -0
- stepxmlclient/rest_client/models/__init__.py +175 -0
- stepxmlclient/rest_client/models/asset.py +253 -0
- stepxmlclient/rest_client/models/attribute.py +112 -0
- stepxmlclient/rest_client/models/background_process.py +23 -0
- stepxmlclient/rest_client/models/batch.py +41 -0
- stepxmlclient/rest_client/models/classification.py +57 -0
- stepxmlclient/rest_client/models/collection.py +26 -0
- stepxmlclient/rest_client/models/common.py +192 -0
- stepxmlclient/rest_client/models/context.py +16 -0
- stepxmlclient/rest_client/models/data_type_group.py +15 -0
- stepxmlclient/rest_client/models/entity.py +63 -0
- stepxmlclient/rest_client/models/event_processor.py +15 -0
- stepxmlclient/rest_client/models/import_export.py +43 -0
- stepxmlclient/rest_client/models/integration_endpoint.py +16 -0
- stepxmlclient/rest_client/models/product.py +200 -0
- stepxmlclient/rest_client/models/relations.py +280 -0
- stepxmlclient/rest_client/models/system_information.py +11 -0
- stepxmlclient/rest_client/models/user.py +28 -0
- stepxmlclient/rest_client/models/workflow.py +30 -0
- stepxmlclient/rest_client/operations/__init__.py +54 -0
- stepxmlclient/rest_client/operations/assets.py +652 -0
- stepxmlclient/rest_client/operations/attributes.py +252 -0
- stepxmlclient/rest_client/operations/background_processes.py +84 -0
- stepxmlclient/rest_client/operations/batch.py +28 -0
- stepxmlclient/rest_client/operations/classifications.py +248 -0
- stepxmlclient/rest_client/operations/collection_groups.py +46 -0
- stepxmlclient/rest_client/operations/collections.py +67 -0
- stepxmlclient/rest_client/operations/contexts.py +88 -0
- stepxmlclient/rest_client/operations/data_type_groups.py +68 -0
- stepxmlclient/rest_client/operations/entities.py +295 -0
- stepxmlclient/rest_client/operations/event_processors.py +109 -0
- stepxmlclient/rest_client/operations/exports.py +153 -0
- stepxmlclient/rest_client/operations/gateway.py +53 -0
- stepxmlclient/rest_client/operations/inbound.py +472 -0
- stepxmlclient/rest_client/operations/outbound.py +64 -0
- stepxmlclient/rest_client/operations/products.py +489 -0
- stepxmlclient/rest_client/operations/relations.py +349 -0
- stepxmlclient/rest_client/operations/reports.py +27 -0
- stepxmlclient/rest_client/operations/system_information.py +28 -0
- stepxmlclient/rest_client/operations/user_groups.py +79 -0
- stepxmlclient/rest_client/operations/users.py +119 -0
- stepxmlclient/rest_client/operations/workflow_tasks.py +61 -0
- stepxmlclient/rest_client/operations/workflows.py +50 -0
- stepxmlclient/upload.py +293 -0
- stepxmlclient-1.0.0.dist-info/METADATA +666 -0
- stepxmlclient-1.0.0.dist-info/RECORD +70 -0
- stepxmlclient-1.0.0.dist-info/WHEEL +5 -0
- stepxmlclient-1.0.0.dist-info/licenses/LICENSE +21 -0
- stepxmlclient-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"""Attribute model for STEP XML Client.
|
|
2
|
+
|
|
3
|
+
Defines the Attribute entity class for representing attribute definitions in STEP MDM.
|
|
4
|
+
Attributes define the properties that can be assigned to products, assets, and entities.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional, Any, Dict, TYPE_CHECKING
|
|
8
|
+
from . import BaseObject
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Attribute(BaseObject):
|
|
15
|
+
"""Attribute definition in STEP MDM.
|
|
16
|
+
|
|
17
|
+
Defines a property/characteristic that can be assigned to products, assets, and entities.
|
|
18
|
+
Supports multiple data types, validation rules, units, and dimensional analysis.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
ID: Unique attribute identifier
|
|
22
|
+
DefaultUnitID: Default unit for numeric values
|
|
23
|
+
ProductMode: 'Normal' or 'Property' (property attributes have limited usage)
|
|
24
|
+
CryptographicKeyID: Optional encryption key for sensitive data
|
|
25
|
+
HierarchicalFiltering: Whether to use hierarchical filtering
|
|
26
|
+
ClassificationHierarchicalFiltering: Whether to use classification hierarchy filtering
|
|
27
|
+
ExternallyMaintained: Whether values are maintained externally
|
|
28
|
+
FullTextIndexed: Whether to index for full-text search
|
|
29
|
+
MultiValued: Whether attribute can have multiple values
|
|
30
|
+
Mandatory: Whether attribute is required
|
|
31
|
+
Derived: Whether value is computed/derived
|
|
32
|
+
Selected: Whether attribute is selected in UI
|
|
33
|
+
Referenced: Whether attribute is referenced elsewhere
|
|
34
|
+
Changed: Whether attribute was modified
|
|
35
|
+
Deleted: Whether attribute is marked for deletion
|
|
36
|
+
Name: Attribute name (localized)
|
|
37
|
+
Validation: Data type validation configuration
|
|
38
|
+
ListOfValueLink: Link to List-of-Values for choice attributes
|
|
39
|
+
ValueTemplate: Template for attribute values
|
|
40
|
+
UnitTemplate: Template for units
|
|
41
|
+
DimensionLink: Links to dimensional definitions
|
|
42
|
+
MetaData: Metadata associated with attribute
|
|
43
|
+
AttributeGroupLink: Links to attribute groups
|
|
44
|
+
UserTypeLink: Links to user types
|
|
45
|
+
LinkType: Link type associations
|
|
46
|
+
ValueFilter: Filters for attribute values
|
|
47
|
+
CurrentTasks: Current task information
|
|
48
|
+
"""
|
|
49
|
+
_GROUP_NAME: str = 'attributes'
|
|
50
|
+
_TAG_NAME: str = 'Attribute'
|
|
51
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
52
|
+
"ID", "DefaultUnitID", "ProductMode", "CryptographicKeyID",
|
|
53
|
+
"HierarchicalFiltering", "ClassificationHierarchicalFiltering",
|
|
54
|
+
"ExternallyMaintained", "FullTextIndexed", "MultiValued",
|
|
55
|
+
"Mandatory", "Derived", "Selected", "Referenced", "Changed", "Deleted"
|
|
56
|
+
]
|
|
57
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
58
|
+
_CHILDREN_NAMES: List[str] = [
|
|
59
|
+
"Validation",
|
|
60
|
+
"ListOfValueLink",
|
|
61
|
+
"ValueTemplate",
|
|
62
|
+
"UnitTemplate",
|
|
63
|
+
"DimensionLink",
|
|
64
|
+
"MetaData",
|
|
65
|
+
"AttributeGroupLink",
|
|
66
|
+
"UserTypeLink",
|
|
67
|
+
"LinkType",
|
|
68
|
+
"ValueFilter",
|
|
69
|
+
"CurrentTasks"
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
73
|
+
super().__init__(data)
|
|
74
|
+
# Initialize link lists if not provided
|
|
75
|
+
for link_name in ["DimensionLink", "AttributeGroupLink", "UserTypeLink", "LinkType"]:
|
|
76
|
+
if link_name not in self._data:
|
|
77
|
+
self._data[link_name] = []
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class AttributeGroup(BaseObject):
|
|
81
|
+
"""AttributeGroup - hierarchical grouping of attributes for organizational purposes.
|
|
82
|
+
|
|
83
|
+
Supports:
|
|
84
|
+
- Nested attribute groups (parent/child hierarchy)
|
|
85
|
+
- Workbench visibility settings
|
|
86
|
+
- Manual sorting control
|
|
87
|
+
- Profiling exclusion options
|
|
88
|
+
- Configuration/view definitions
|
|
89
|
+
- Boolean state tracking (ShowInWorkbench, ExcludeFromProfiling, Selected, Referenced, etc.)
|
|
90
|
+
"""
|
|
91
|
+
_GROUP_NAME: str = 'attributegroups'
|
|
92
|
+
_TAG_NAME: str = 'AttributeGroup'
|
|
93
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
94
|
+
"ID", "ParentID", "ShowInWorkbench", "ExcludeFromProfiling",
|
|
95
|
+
"Referenced", "ManuallySorted", "Selected", "Changed", "Deleted"
|
|
96
|
+
]
|
|
97
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
98
|
+
_CHILDREN_NAMES: List[str] = [
|
|
99
|
+
"MetaData",
|
|
100
|
+
"Configuration",
|
|
101
|
+
"AttributeSequence",
|
|
102
|
+
"AttributeGroup" # Nested attribute groups
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
106
|
+
super().__init__(data)
|
|
107
|
+
# Initialize nested attribute groups list
|
|
108
|
+
if "AttributeGroup" not in self._data:
|
|
109
|
+
self._data["AttributeGroup"] = []
|
|
110
|
+
|
|
111
|
+
def add_nested_attribute_group(self, attribute_group: Optional['AttributeGroup'] = None,
|
|
112
|
+
**kwargs) -> None:
|
|
113
|
+
"""Add nested child attribute group.
|
|
114
|
+
|
|
115
|
+
Can be called two ways:
|
|
116
|
+
1. With object: add_nested_attribute_group(attribute_group=child_group)
|
|
117
|
+
2. With parameters: add_nested_attribute_group(ID="AG002", Name="Child Group")
|
|
118
|
+
"""
|
|
119
|
+
if attribute_group is not None:
|
|
120
|
+
nested = attribute_group
|
|
121
|
+
else:
|
|
122
|
+
nested = AttributeGroup(kwargs)
|
|
123
|
+
|
|
124
|
+
if not isinstance(self._data["AttributeGroup"], list):
|
|
125
|
+
self._data["AttributeGroup"] = []
|
|
126
|
+
self._data["AttributeGroup"].append(nested)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class ListOfValues(BaseObject):
|
|
130
|
+
"""ListOfValues - defines a set of allowed values for an attribute with optional grouping.
|
|
131
|
+
|
|
132
|
+
Supports:
|
|
133
|
+
- Hierarchical value groups (parent/child)
|
|
134
|
+
- Value definitions and deletion
|
|
135
|
+
- User-contributed values
|
|
136
|
+
- Value ID usage control
|
|
137
|
+
- Validation rules
|
|
138
|
+
- Dimensional analysis (DimensionLink)
|
|
139
|
+
- Unit definitions (DefaultUnitID)
|
|
140
|
+
- Boolean state tracking (AllowUserValueAddition, UseValueID, ReplaceListOfValuesValues, etc.)
|
|
141
|
+
"""
|
|
142
|
+
_GROUP_NAME: str = 'listofvalues'
|
|
143
|
+
_TAG_NAME: str = 'ListOfValues'
|
|
144
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
145
|
+
"ID", "ParentID", "AllowUserValueAddition", "UseValueID",
|
|
146
|
+
"IDPattern", "ReplaceListOfValuesValues", "DefaultUnitID"
|
|
147
|
+
]
|
|
148
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
149
|
+
_CHILDREN_NAMES: List[str] = [
|
|
150
|
+
"Validation",
|
|
151
|
+
"DimensionLink",
|
|
152
|
+
"MetaData",
|
|
153
|
+
"AttributeGroupLink",
|
|
154
|
+
"Value",
|
|
155
|
+
"ValueGroup",
|
|
156
|
+
"DeleteValue",
|
|
157
|
+
"ListOfValuesGroup" # Nested groups
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
161
|
+
super().__init__(data)
|
|
162
|
+
# Initialize link lists if not provided
|
|
163
|
+
for link_name in ["DimensionLink", "AttributeGroupLink"]:
|
|
164
|
+
if link_name not in self._data:
|
|
165
|
+
self._data[link_name] = []
|
|
166
|
+
|
|
167
|
+
# Initialize value lists
|
|
168
|
+
for value_name in ["Value", "ValueGroup", "DeleteValue", "ListOfValuesGroup"]:
|
|
169
|
+
if value_name not in self._data:
|
|
170
|
+
self._data[value_name] = []
|
|
171
|
+
|
|
172
|
+
def add_value(self, value_id: Optional[str] = None,
|
|
173
|
+
name: Optional[str] = None,
|
|
174
|
+
**kwargs) -> None:
|
|
175
|
+
"""Add a value to this list of values.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
value_id: ID of the value (if UseValueID=true)
|
|
179
|
+
name: Display name of the value
|
|
180
|
+
**kwargs: Additional attributes to pass to Value element
|
|
181
|
+
"""
|
|
182
|
+
value_dict = {}
|
|
183
|
+
if value_id is not None:
|
|
184
|
+
value_dict["ID"] = value_id
|
|
185
|
+
if name is not None:
|
|
186
|
+
value_dict["Name"] = name
|
|
187
|
+
value_dict.update(kwargs)
|
|
188
|
+
|
|
189
|
+
if not isinstance(self._data["Value"], list):
|
|
190
|
+
self._data["Value"] = []
|
|
191
|
+
self._data["Value"].append(value_dict)
|
|
192
|
+
|
|
193
|
+
def delete_value(self, value_id: str) -> None:
|
|
194
|
+
"""Mark a value for deletion from this list of values.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
value_id: ID of the value to delete
|
|
198
|
+
"""
|
|
199
|
+
delete_dict = {"ID": value_id}
|
|
200
|
+
|
|
201
|
+
if not isinstance(self._data["DeleteValue"], list):
|
|
202
|
+
self._data["DeleteValue"] = []
|
|
203
|
+
self._data["DeleteValue"].append(delete_dict)
|
|
204
|
+
|
|
205
|
+
def add_value_group(self, value_group: Optional['ValueGroup'] = None,
|
|
206
|
+
**kwargs) -> None:
|
|
207
|
+
"""Add a value group (for grouped value organization).
|
|
208
|
+
|
|
209
|
+
Can be called two ways:
|
|
210
|
+
1. With object: add_value_group(value_group=group_obj)
|
|
211
|
+
2. With parameters: add_value_group(ID="VG001", Name="Group Name")
|
|
212
|
+
"""
|
|
213
|
+
if value_group is not None:
|
|
214
|
+
group = value_group
|
|
215
|
+
else:
|
|
216
|
+
group = ValueGroup(kwargs)
|
|
217
|
+
|
|
218
|
+
if not isinstance(self._data["ValueGroup"], list):
|
|
219
|
+
self._data["ValueGroup"] = []
|
|
220
|
+
self._data["ValueGroup"].append(group)
|
|
221
|
+
|
|
222
|
+
def add_nested_list_of_values_group(self, group: Optional['ListOfValuesGroup'] = None,
|
|
223
|
+
**kwargs) -> None:
|
|
224
|
+
"""Add nested list of values group for hierarchical organization.
|
|
225
|
+
|
|
226
|
+
Can be called two ways:
|
|
227
|
+
1. With object: add_nested_list_of_values_group(group=child_group)
|
|
228
|
+
2. With parameters: add_nested_list_of_values_group(ID="LOG001", Name="Group")
|
|
229
|
+
"""
|
|
230
|
+
if group is not None:
|
|
231
|
+
nested = group
|
|
232
|
+
else:
|
|
233
|
+
nested = ListOfValuesGroup(kwargs)
|
|
234
|
+
|
|
235
|
+
if not isinstance(self._data["ListOfValuesGroup"], list):
|
|
236
|
+
self._data["ListOfValuesGroup"] = []
|
|
237
|
+
self._data["ListOfValuesGroup"].append(nested)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class ValueGroup(BaseObject):
|
|
241
|
+
"""ValueGroup - groups related values within a ListOfValues for organizational purposes."""
|
|
242
|
+
_GROUP_NAME: Optional[str] = None # Used as child element only
|
|
243
|
+
_TAG_NAME: str = 'ValueGroup'
|
|
244
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID"]
|
|
245
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
246
|
+
_CHILDREN_NAMES: List[str] = ["Value"]
|
|
247
|
+
|
|
248
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
249
|
+
super().__init__(data)
|
|
250
|
+
if "Value" not in self._data:
|
|
251
|
+
self._data["Value"] = []
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
class ListOfValuesGroup(BaseObject):
|
|
255
|
+
"""ListOfValuesGroup - hierarchical grouping of lists of values."""
|
|
256
|
+
_GROUP_NAME: Optional[str] = None # Used as child element only
|
|
257
|
+
_TAG_NAME: str = 'ListOfValuesGroup'
|
|
258
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "ParentID", "Selected", "Referenced", "Changed"]
|
|
259
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
260
|
+
_CHILDREN_NAMES: List[str] = [
|
|
261
|
+
"MetaData",
|
|
262
|
+
"AttributeGroupLink",
|
|
263
|
+
"ListOfValuesGroup" # Nested groups
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
267
|
+
super().__init__(data)
|
|
268
|
+
if "AttributeGroupLink" not in self._data:
|
|
269
|
+
self._data["AttributeGroupLink"] = []
|
|
270
|
+
if "ListOfValuesGroup" not in self._data:
|
|
271
|
+
self._data["ListOfValuesGroup"] = []
|
|
272
|
+
|
|
273
|
+
def add_nested_list_of_values_group(self, group: Optional['ListOfValuesGroup'] = None,
|
|
274
|
+
**kwargs) -> None:
|
|
275
|
+
"""Add nested list of values group.
|
|
276
|
+
|
|
277
|
+
Can be called two ways:
|
|
278
|
+
1. With object: add_nested_list_of_values_group(group=child_group)
|
|
279
|
+
2. With parameters: add_nested_list_of_values_group(ID="LOG002", Name="Child")
|
|
280
|
+
"""
|
|
281
|
+
if group is not None:
|
|
282
|
+
nested = group
|
|
283
|
+
else:
|
|
284
|
+
nested = ListOfValuesGroup(kwargs)
|
|
285
|
+
|
|
286
|
+
if not isinstance(self._data["ListOfValuesGroup"], list):
|
|
287
|
+
self._data["ListOfValuesGroup"] = []
|
|
288
|
+
self._data["ListOfValuesGroup"].append(nested)
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"""Business rules and workflow models for STEP XML Client.
|
|
2
|
+
|
|
3
|
+
Defines business logic execution entities including Business Rules and Workflows
|
|
4
|
+
that control behavior and processes within STEP MDM systems.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional, Any, Dict, TYPE_CHECKING
|
|
8
|
+
from . import BaseObject
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BusinessRule(BaseObject):
|
|
15
|
+
"""Business logic executable in STEP MDM.
|
|
16
|
+
|
|
17
|
+
Defines executable business logic including actions, conditions, functions, and libraries.
|
|
18
|
+
Business rules contain logic that executes within the STEP system to automate processes.
|
|
19
|
+
|
|
20
|
+
Supports:
|
|
21
|
+
- Multiple rule types (Action, Condition, Function, Library)
|
|
22
|
+
- Rule scope (Local or Global)
|
|
23
|
+
- Privileged execution mode
|
|
24
|
+
- Dependencies on other rules
|
|
25
|
+
- Multi-language names and descriptions
|
|
26
|
+
- Setup group configuration
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
ID: Unique business rule identifier
|
|
30
|
+
Type: Rule type (Action, Condition, Function, Library, etc.)
|
|
31
|
+
Scope: Scope of execution (Local or Global)
|
|
32
|
+
RunPrivileged: Whether to run with elevated privileges
|
|
33
|
+
Name: Rule name (localized)
|
|
34
|
+
Description: Rule description (localized)
|
|
35
|
+
Dependency: List of dependent rules
|
|
36
|
+
FunctionDependency: List of function dependencies
|
|
37
|
+
OnApprove: On-approval behavior configuration
|
|
38
|
+
Configuration: Rule-specific configuration
|
|
39
|
+
ValidObjectTypes: Object types this rule applies to
|
|
40
|
+
SetupGroupLink: Link to setup groups
|
|
41
|
+
"""
|
|
42
|
+
_GROUP_NAME: str = 'businessrules'
|
|
43
|
+
_TAG_NAME: str = 'BusinessRule'
|
|
44
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "Type", "Scope", "RunPrivileged", "Selected", "Referenced", "Changed"]
|
|
45
|
+
_TEXT_NAMES: List[str] = ["Name", "Description"]
|
|
46
|
+
_CHILDREN_NAMES: List[str] = [
|
|
47
|
+
"Dependency",
|
|
48
|
+
"FunctionDependency",
|
|
49
|
+
"OnApprove",
|
|
50
|
+
"Configuration",
|
|
51
|
+
"ValidObjectTypes",
|
|
52
|
+
"SetupGroupLink"
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
56
|
+
super().__init__(data)
|
|
57
|
+
# Initialize dependency lists if not provided
|
|
58
|
+
for dep_name in ["Dependency", "FunctionDependency"]:
|
|
59
|
+
if dep_name not in self._data:
|
|
60
|
+
self._data[dep_name] = []
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class Workflow(BaseObject):
|
|
64
|
+
"""Workflow - orchestrates business processes in STEP.
|
|
65
|
+
|
|
66
|
+
Workflows define states, transitions, and validations that control how objects
|
|
67
|
+
move through business processes. Workflows enforce rules about what operations
|
|
68
|
+
are allowed in each state and what data must be valid before transitions.
|
|
69
|
+
|
|
70
|
+
Supports:
|
|
71
|
+
- Object type constraints (ValidUserTypeLink)
|
|
72
|
+
- Start conditions
|
|
73
|
+
- Embedded business rules
|
|
74
|
+
- Business rule references
|
|
75
|
+
- Setup group configuration
|
|
76
|
+
- Multi-language names
|
|
77
|
+
- Boolean state tracking (Selected, Referenced, Changed)
|
|
78
|
+
|
|
79
|
+
Attributes:
|
|
80
|
+
ID: Unique workflow identifier
|
|
81
|
+
Name: Workflow name (localized)
|
|
82
|
+
Description: Workflow description
|
|
83
|
+
ValidUserTypeLink: Links to object types this workflow applies to
|
|
84
|
+
ValidBusinessRuleLink: Links to relevant business rules
|
|
85
|
+
StartCondition: Condition for workflow start
|
|
86
|
+
STEPAction: Workflow actions
|
|
87
|
+
STEPState: Workflow states
|
|
88
|
+
STEPEdge: State transitions
|
|
89
|
+
SetupGroupLink: Setup group associations
|
|
90
|
+
"""
|
|
91
|
+
_GROUP_NAME: str = 'workflows'
|
|
92
|
+
_TAG_NAME: str = 'Workflow'
|
|
93
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "Selected", "Referenced", "Changed"]
|
|
94
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
95
|
+
_CHILDREN_NAMES: List[str] = [
|
|
96
|
+
"MetaData",
|
|
97
|
+
"ValidUserTypeLink",
|
|
98
|
+
"StartCondition",
|
|
99
|
+
"Configuration",
|
|
100
|
+
"LocalBusinessRule",
|
|
101
|
+
"BusinessRuleLink",
|
|
102
|
+
"SetupGroupLink"
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
106
|
+
super().__init__(data)
|
|
107
|
+
# Initialize link lists if not provided
|
|
108
|
+
for link_name in ["ValidUserTypeLink", "LocalBusinessRule", "BusinessRuleLink"]:
|
|
109
|
+
if link_name not in self._data:
|
|
110
|
+
self._data[link_name] = []
|
|
111
|
+
|
|
112
|
+
def add_valid_user_type_link(self, user_type_id: str) -> None:
|
|
113
|
+
"""Add a valid user type link to this workflow.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
user_type_id: ID of the user type
|
|
117
|
+
"""
|
|
118
|
+
if not isinstance(self._data["ValidUserTypeLink"], list):
|
|
119
|
+
self._data["ValidUserTypeLink"] = []
|
|
120
|
+
self._data["ValidUserTypeLink"].append(user_type_id)
|
|
121
|
+
|
|
122
|
+
def add_business_rule_link(self, business_rule_id: str) -> None:
|
|
123
|
+
"""Add a business rule link to this workflow.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
business_rule_id: ID of the business rule
|
|
127
|
+
"""
|
|
128
|
+
if not isinstance(self._data["BusinessRuleLink"], list):
|
|
129
|
+
self._data["BusinessRuleLink"] = []
|
|
130
|
+
self._data["BusinessRuleLink"].append(business_rule_id)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class Collection(BaseObject):
|
|
134
|
+
"""Collection - represents a user-defined collection of objects.
|
|
135
|
+
|
|
136
|
+
Collections group objects based on queries or manual selection.
|
|
137
|
+
They provide flexible organization outside fixed hierarchies.
|
|
138
|
+
|
|
139
|
+
Supports:
|
|
140
|
+
- Query-based membership (QueryURL)
|
|
141
|
+
- Parent collection linking for hierarchies
|
|
142
|
+
- Multi-language names
|
|
143
|
+
- Metadata tracking
|
|
144
|
+
"""
|
|
145
|
+
_GROUP_NAME: str = 'collections'
|
|
146
|
+
_TAG_NAME: str = 'Collection'
|
|
147
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "ParentID", "QueryURL"]
|
|
148
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
149
|
+
_CHILDREN_NAMES: List[str] = ["MetaData", "CollectionGroup"]
|
|
150
|
+
|
|
151
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
152
|
+
super().__init__(data)
|
|
153
|
+
# Initialize nested collection groups list
|
|
154
|
+
if "CollectionGroup" not in self._data:
|
|
155
|
+
self._data["CollectionGroup"] = []
|
|
156
|
+
|
|
157
|
+
def add_nested_collection_group(self, collection_group: Optional['CollectionGroup'] = None,
|
|
158
|
+
**kwargs) -> None:
|
|
159
|
+
"""Add nested collection group.
|
|
160
|
+
|
|
161
|
+
Can be called two ways:
|
|
162
|
+
1. With object: add_nested_collection_group(collection_group=group_obj)
|
|
163
|
+
2. With parameters: add_nested_collection_group(ID="CG001", Name="Group")
|
|
164
|
+
"""
|
|
165
|
+
if collection_group is not None:
|
|
166
|
+
group = collection_group
|
|
167
|
+
else:
|
|
168
|
+
group = CollectionGroup(kwargs)
|
|
169
|
+
|
|
170
|
+
if not isinstance(self._data["CollectionGroup"], list):
|
|
171
|
+
self._data["CollectionGroup"] = []
|
|
172
|
+
self._data["CollectionGroup"].append(group)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class CollectionGroup(BaseObject):
|
|
176
|
+
"""CollectionGroup - hierarchical grouping of collections.
|
|
177
|
+
|
|
178
|
+
Collection groups organize collections and nested groups into
|
|
179
|
+
logical hierarchies for better navigation and management.
|
|
180
|
+
|
|
181
|
+
Supports:
|
|
182
|
+
- Nested collection groups (parent/child hierarchy)
|
|
183
|
+
- Nested collections
|
|
184
|
+
- Multi-language names
|
|
185
|
+
- Metadata tracking
|
|
186
|
+
"""
|
|
187
|
+
_GROUP_NAME: str = 'collectiongroups'
|
|
188
|
+
_TAG_NAME: str = 'CollectionGroup'
|
|
189
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "ParentID"]
|
|
190
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
191
|
+
_CHILDREN_NAMES: List[str] = ["MetaData", "CollectionGroup", "Collection"]
|
|
192
|
+
|
|
193
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
194
|
+
super().__init__(data)
|
|
195
|
+
# Initialize nested groups and collections lists
|
|
196
|
+
if "CollectionGroup" not in self._data:
|
|
197
|
+
self._data["CollectionGroup"] = []
|
|
198
|
+
if "Collection" not in self._data:
|
|
199
|
+
self._data["Collection"] = []
|
|
200
|
+
|
|
201
|
+
def add_nested_collection_group(self, collection_group: Optional['CollectionGroup'] = None,
|
|
202
|
+
**kwargs) -> None:
|
|
203
|
+
"""Add nested collection group.
|
|
204
|
+
|
|
205
|
+
Can be called two ways:
|
|
206
|
+
1. With object: add_nested_collection_group(collection_group=group_obj)
|
|
207
|
+
2. With parameters: add_nested_collection_group(ID="CG002", Name="Nested")
|
|
208
|
+
"""
|
|
209
|
+
if collection_group is not None:
|
|
210
|
+
group = collection_group
|
|
211
|
+
else:
|
|
212
|
+
group = CollectionGroup(kwargs)
|
|
213
|
+
|
|
214
|
+
if not isinstance(self._data["CollectionGroup"], list):
|
|
215
|
+
self._data["CollectionGroup"] = []
|
|
216
|
+
self._data["CollectionGroup"].append(group)
|
|
217
|
+
|
|
218
|
+
def add_collection(self, collection: Optional['Collection'] = None,
|
|
219
|
+
**kwargs) -> None:
|
|
220
|
+
"""Add a collection to this group.
|
|
221
|
+
|
|
222
|
+
Can be called two ways:
|
|
223
|
+
1. With object: add_collection(collection=coll_obj)
|
|
224
|
+
2. With parameters: add_collection(ID="C001", Name="Collection Name")
|
|
225
|
+
"""
|
|
226
|
+
if collection is not None:
|
|
227
|
+
coll = collection
|
|
228
|
+
else:
|
|
229
|
+
coll = Collection(kwargs)
|
|
230
|
+
|
|
231
|
+
if not isinstance(self._data["Collection"], list):
|
|
232
|
+
self._data["Collection"] = []
|
|
233
|
+
self._data["Collection"].append(coll)
|