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,167 @@
|
|
|
1
|
+
"""Organization and dimensional models for STEP XML Client.
|
|
2
|
+
|
|
3
|
+
Defines organizational and dimensional configuration classes including Contexts,
|
|
4
|
+
Qualifiers, Dimensions, Tags, and Units used to organize and structure STEP MDM data.
|
|
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 Context(BaseObject):
|
|
15
|
+
"""Context - multi-language/multi-dimensional context for data.
|
|
16
|
+
|
|
17
|
+
Defines a context in which data can exist with language and dimensional variations.
|
|
18
|
+
Contexts enable organizing data by language, region, or dimensional axes.
|
|
19
|
+
|
|
20
|
+
Supports:
|
|
21
|
+
- Multiple languages via Name elements
|
|
22
|
+
- Dimension point associations for multi-dimensional data
|
|
23
|
+
- Locale specification (language/region codes)
|
|
24
|
+
- Priority management for cross-context resolution
|
|
25
|
+
- Boolean state tracking (Selected, Referenced, Changed, Deleted)
|
|
26
|
+
|
|
27
|
+
Attributes:
|
|
28
|
+
ID: Unique context identifier
|
|
29
|
+
Priority: Priority for context resolution
|
|
30
|
+
Locale: Language/locale code (e.g., 'en_US')
|
|
31
|
+
Name: Context name (localized)
|
|
32
|
+
DimensionPointLink: Links to dimension points
|
|
33
|
+
MetaData: Associated metadata
|
|
34
|
+
Selected: Whether context is selected
|
|
35
|
+
Referenced: Whether context is referenced
|
|
36
|
+
Changed: Whether context was changed
|
|
37
|
+
Deleted: Whether context is marked for deletion
|
|
38
|
+
"""
|
|
39
|
+
_GROUP_NAME: str = 'contexts'
|
|
40
|
+
_TAG_NAME: str = 'Context'
|
|
41
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "Priority", "Locale", "Selected", "Referenced", "Changed", "Deleted"]
|
|
42
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
43
|
+
_CHILDREN_NAMES: List[str] = ["DimensionPointLink", "MetaData"]
|
|
44
|
+
|
|
45
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
46
|
+
super().__init__(data)
|
|
47
|
+
# Initialize link lists if not provided
|
|
48
|
+
if "DimensionPointLink" not in self._data:
|
|
49
|
+
self._data["DimensionPointLink"] = []
|
|
50
|
+
|
|
51
|
+
def add_dimension_point_link(self, dimension_id: str, dimension_point_id: str) -> None:
|
|
52
|
+
"""Add a dimension point link to this context.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
dimension_id: ID of the dimension
|
|
56
|
+
dimension_point_id: ID of the dimension point
|
|
57
|
+
"""
|
|
58
|
+
link_dict = {
|
|
59
|
+
"DimensionID": dimension_id,
|
|
60
|
+
"DimensionPointID": dimension_point_id
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if not isinstance(self._data["DimensionPointLink"], list):
|
|
64
|
+
self._data["DimensionPointLink"] = []
|
|
65
|
+
self._data["DimensionPointLink"].append(link_dict)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Qualifier(BaseObject):
|
|
69
|
+
"""Qualifier - represents a dimension qualifier or multi-dimensional data point.
|
|
70
|
+
|
|
71
|
+
Qualifiers enable multi-dimensional attribute management in STEP.
|
|
72
|
+
They combine dimension points to define a specific multi-dimensional position.
|
|
73
|
+
|
|
74
|
+
Supports:
|
|
75
|
+
- Multiple dimension point associations
|
|
76
|
+
- Multi-language names
|
|
77
|
+
- Metadata tracking
|
|
78
|
+
"""
|
|
79
|
+
_GROUP_NAME: str = 'qualifiers'
|
|
80
|
+
_TAG_NAME: str = 'Qualifier'
|
|
81
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID"]
|
|
82
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
83
|
+
_CHILDREN_NAMES: List[str] = ["DimensionPointLink", "MetaData"]
|
|
84
|
+
|
|
85
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
86
|
+
super().__init__(data)
|
|
87
|
+
# Initialize link lists if not provided
|
|
88
|
+
if "DimensionPointLink" not in self._data:
|
|
89
|
+
self._data["DimensionPointLink"] = []
|
|
90
|
+
|
|
91
|
+
def add_dimension_point_link(self, dimension_id: str, dimension_point_id: str) -> None:
|
|
92
|
+
"""Add a dimension point link to this qualifier.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
dimension_id: ID of the dimension
|
|
96
|
+
dimension_point_id: ID of the dimension point
|
|
97
|
+
"""
|
|
98
|
+
link_dict = {
|
|
99
|
+
"DimensionID": dimension_id,
|
|
100
|
+
"DimensionPointID": dimension_point_id
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if not isinstance(self._data["DimensionPointLink"], list):
|
|
104
|
+
self._data["DimensionPointLink"] = []
|
|
105
|
+
self._data["DimensionPointLink"].append(link_dict)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class Dimension(BaseObject):
|
|
109
|
+
"""Dimension - defines an axis for multi-dimensional data organization.
|
|
110
|
+
|
|
111
|
+
Dimensions define categorization axes (e.g., Market, Color, Size) along which
|
|
112
|
+
products and attributes can be organized. Each dimension contains dimension points.
|
|
113
|
+
|
|
114
|
+
Supports:
|
|
115
|
+
- Dimension points (values/positions along this axis)
|
|
116
|
+
- Multi-language names
|
|
117
|
+
- Duplicate point control
|
|
118
|
+
- Metadata tracking
|
|
119
|
+
"""
|
|
120
|
+
_GROUP_NAME: str = 'dimensions'
|
|
121
|
+
_TAG_NAME: str = 'Dimension'
|
|
122
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "AllowDuplicates"]
|
|
123
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
124
|
+
_CHILDREN_NAMES: List[str] = ["DimensionPoint", "MetaData"]
|
|
125
|
+
|
|
126
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
127
|
+
super().__init__(data)
|
|
128
|
+
# Initialize dimension points list if not provided
|
|
129
|
+
if "DimensionPoint" not in self._data:
|
|
130
|
+
self._data["DimensionPoint"] = []
|
|
131
|
+
|
|
132
|
+
def add_dimension_point(self, dimension_point: Optional['DimensionPoint'] = None,
|
|
133
|
+
**kwargs) -> None:
|
|
134
|
+
"""Add a dimension point to this dimension.
|
|
135
|
+
|
|
136
|
+
Can be called two ways:
|
|
137
|
+
1. With object: add_dimension_point(dimension_point=point_obj)
|
|
138
|
+
2. With parameters: add_dimension_point(ID="DP001", Name="Point Name")
|
|
139
|
+
"""
|
|
140
|
+
if dimension_point is not None:
|
|
141
|
+
point = dimension_point
|
|
142
|
+
else:
|
|
143
|
+
point = DimensionPoint(kwargs)
|
|
144
|
+
|
|
145
|
+
if not isinstance(self._data["DimensionPoint"], list):
|
|
146
|
+
self._data["DimensionPoint"] = []
|
|
147
|
+
self._data["DimensionPoint"].append(point)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class DimensionPoint(BaseObject):
|
|
151
|
+
"""DimensionPoint - represents a point/value within a dimension.
|
|
152
|
+
|
|
153
|
+
Dimension points define the valid positions or values along a dimension axis.
|
|
154
|
+
For example, a "Color" dimension might have points: Red, Blue, Green.
|
|
155
|
+
|
|
156
|
+
Supports:
|
|
157
|
+
- Multi-language names
|
|
158
|
+
- Metadata tracking
|
|
159
|
+
"""
|
|
160
|
+
_GROUP_NAME: Optional[str] = None # Used as child element only
|
|
161
|
+
_TAG_NAME: str = 'DimensionPoint'
|
|
162
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID"]
|
|
163
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
164
|
+
_CHILDREN_NAMES: List[str] = ["MetaData"]
|
|
165
|
+
|
|
166
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
167
|
+
super().__init__(data)
|
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
from typing import List, Optional, Any, Dict, TYPE_CHECKING
|
|
2
|
+
from . import BaseObject
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from .relations import (
|
|
6
|
+
AssetCrossReference,
|
|
7
|
+
ProductCrossReference,
|
|
8
|
+
ClassificationReference,
|
|
9
|
+
ClassificationCrossReference,
|
|
10
|
+
EntityCrossReference,
|
|
11
|
+
)
|
|
12
|
+
from .deletion import DeleteAssetCrossReference, DeleteProductCrossReference
|
|
13
|
+
from .complex_elements import (
|
|
14
|
+
STEPWorkflowStateBind,
|
|
15
|
+
SequenceProduct,
|
|
16
|
+
OverrideSubProduct,
|
|
17
|
+
PackagingReference,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Product(BaseObject):
|
|
22
|
+
"""Product entity in STEP MDM.
|
|
23
|
+
|
|
24
|
+
This model serializes to STEP ``Product`` and supports both direct dictionary
|
|
25
|
+
payloads and helper methods.
|
|
26
|
+
|
|
27
|
+
Common top-level ``data`` keys:
|
|
28
|
+
- ``ID`` (str): Product identifier
|
|
29
|
+
- ``ParentId`` (str): Parent product ID
|
|
30
|
+
- ``UserTypeID`` (str): Product object type
|
|
31
|
+
- ``Name`` (str): Product name
|
|
32
|
+
- ``KeyValue`` (dict/list): external keys, e.g. ``{"KeyID": "ExternalKey", "value": "P-1"}``
|
|
33
|
+
- ``Values`` (dict): attribute value map
|
|
34
|
+
|
|
35
|
+
Frequently used child collections:
|
|
36
|
+
- ``AssetCrossReference``
|
|
37
|
+
- ``ProductCrossReference``
|
|
38
|
+
- ``ClassificationReference``
|
|
39
|
+
- ``ClassificationCrossReference``
|
|
40
|
+
- ``EntityCrossReference``
|
|
41
|
+
|
|
42
|
+
Usage examples:
|
|
43
|
+
Dict-first style::
|
|
44
|
+
|
|
45
|
+
product = Product({"ID": "P100", "UserTypeID": "UT_PRODUCT", "Name": "Bike"})
|
|
46
|
+
product.set_workflow_state_bind(workflow_id="WF_APPROVAL", state_id="STATE_DRAFT")
|
|
47
|
+
product.add_packaging_reference(product_id="BOX_01", quantity="1")
|
|
48
|
+
|
|
49
|
+
Pre-built object style::
|
|
50
|
+
|
|
51
|
+
from stepxmlclient.model import STEPWorkflowStateBind, SequenceProduct
|
|
52
|
+
product = Product({"ID": "P200", "UserTypeID": "UT_PRODUCT"})
|
|
53
|
+
product.set_workflow_state_bind(bind_object=STEPWorkflowStateBind({
|
|
54
|
+
"WorkflowID": "WF_APPROVAL", "StateID": "STATE_READY"
|
|
55
|
+
}))
|
|
56
|
+
product.add_sequence_product(sequence_object=SequenceProduct({"ID": "P201"}))
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
_GROUP_NAME: str = "products"
|
|
60
|
+
_TAG_NAME: str = "Product"
|
|
61
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
62
|
+
"ID",
|
|
63
|
+
"ParentId",
|
|
64
|
+
"UserTypeID",
|
|
65
|
+
"QualifierID",
|
|
66
|
+
"Changed",
|
|
67
|
+
"Republished",
|
|
68
|
+
"Selected",
|
|
69
|
+
"Referenced",
|
|
70
|
+
]
|
|
71
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
72
|
+
_CHILDREN_NAMES: List[str] = [
|
|
73
|
+
"KeyValue",
|
|
74
|
+
"ParentKeyValue",
|
|
75
|
+
"STEPWorkflowStateBind",
|
|
76
|
+
"Values",
|
|
77
|
+
"DeleteSuppressedAssetCrossReference",
|
|
78
|
+
"SuppressedAssetCrossReference",
|
|
79
|
+
"AssetCrossReference",
|
|
80
|
+
"DeleteSuppressedProductCrossReference",
|
|
81
|
+
"SuppressedProductCrossReference",
|
|
82
|
+
"ProductCrossReference",
|
|
83
|
+
"DeleteSuppressedClassificationReference",
|
|
84
|
+
"DeleteClassificationReference",
|
|
85
|
+
"SuppressedClassificationReference",
|
|
86
|
+
"ClassificationReference",
|
|
87
|
+
"DeleteSuppressedClassificationCrossReference",
|
|
88
|
+
"DeleteClassificationCrossReference",
|
|
89
|
+
"SuppressedClassificationCrossReference",
|
|
90
|
+
"ClassificationCrossReference",
|
|
91
|
+
"DeleteSuppressedEntityCrossReference",
|
|
92
|
+
"DeleteEntityCrossReference",
|
|
93
|
+
"SuppressedEntityCrossReference",
|
|
94
|
+
"EntityCrossReference",
|
|
95
|
+
"DeleteAttributeLink",
|
|
96
|
+
"AttributeLink",
|
|
97
|
+
"DataContainerTypeLink",
|
|
98
|
+
"DeleteDataContainerTypeLink",
|
|
99
|
+
"DataContainers",
|
|
100
|
+
"DeleteAssetCrossReference",
|
|
101
|
+
"DeleteProductCrossReference",
|
|
102
|
+
"SequenceProduct",
|
|
103
|
+
"CurrentTasks",
|
|
104
|
+
"Terms",
|
|
105
|
+
"Tables",
|
|
106
|
+
"OverrideSubProduct",
|
|
107
|
+
"PackagingReference",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
111
|
+
super().__init__(data)
|
|
112
|
+
for rel_name in [
|
|
113
|
+
"DeleteSuppressedAssetCrossReference",
|
|
114
|
+
"SuppressedAssetCrossReference",
|
|
115
|
+
"AssetCrossReference",
|
|
116
|
+
"DeleteSuppressedProductCrossReference",
|
|
117
|
+
"SuppressedProductCrossReference",
|
|
118
|
+
"ProductCrossReference",
|
|
119
|
+
"DeleteSuppressedClassificationReference",
|
|
120
|
+
"DeleteClassificationReference",
|
|
121
|
+
"SuppressedClassificationReference",
|
|
122
|
+
"ClassificationReference",
|
|
123
|
+
"DeleteSuppressedClassificationCrossReference",
|
|
124
|
+
"DeleteClassificationCrossReference",
|
|
125
|
+
"SuppressedClassificationCrossReference",
|
|
126
|
+
"ClassificationCrossReference",
|
|
127
|
+
"DeleteSuppressedEntityCrossReference",
|
|
128
|
+
"DeleteEntityCrossReference",
|
|
129
|
+
"SuppressedEntityCrossReference",
|
|
130
|
+
"EntityCrossReference",
|
|
131
|
+
"DeleteAttributeLink",
|
|
132
|
+
"AttributeLink",
|
|
133
|
+
"DataContainerTypeLink",
|
|
134
|
+
"DeleteDataContainerTypeLink",
|
|
135
|
+
"DeleteAssetCrossReference",
|
|
136
|
+
"DeleteProductCrossReference",
|
|
137
|
+
"SequenceProduct",
|
|
138
|
+
"CurrentTasks",
|
|
139
|
+
"Terms",
|
|
140
|
+
"Tables",
|
|
141
|
+
"OverrideSubProduct",
|
|
142
|
+
"PackagingReference",
|
|
143
|
+
]:
|
|
144
|
+
if rel_name not in self._data:
|
|
145
|
+
self._data[rel_name] = []
|
|
146
|
+
|
|
147
|
+
def add_asset_reference(
|
|
148
|
+
self,
|
|
149
|
+
asset_id: Optional[str] = None,
|
|
150
|
+
type_: Optional[str] = None,
|
|
151
|
+
qualifier_id: Optional[str] = None,
|
|
152
|
+
ref_object: Optional["AssetCrossReference"] = None,
|
|
153
|
+
) -> None:
|
|
154
|
+
"""Add an ``AssetCrossReference``.
|
|
155
|
+
|
|
156
|
+
Fields:
|
|
157
|
+
- ``AssetID``
|
|
158
|
+
- ``Type``
|
|
159
|
+
- ``QualifierID``
|
|
160
|
+
"""
|
|
161
|
+
from .relations import AssetCrossReference
|
|
162
|
+
|
|
163
|
+
ref = ref_object or AssetCrossReference(
|
|
164
|
+
{"AssetID": asset_id, "Type": type_, "QualifierID": qualifier_id}
|
|
165
|
+
)
|
|
166
|
+
if not isinstance(self._data["AssetCrossReference"], list):
|
|
167
|
+
self._data["AssetCrossReference"] = []
|
|
168
|
+
self._data["AssetCrossReference"].append(ref)
|
|
169
|
+
|
|
170
|
+
def delete_asset_reference(
|
|
171
|
+
self,
|
|
172
|
+
asset_id: Optional[str] = None,
|
|
173
|
+
type_: Optional[str] = None,
|
|
174
|
+
qualifier_id: Optional[str] = None,
|
|
175
|
+
delete_ref_object: Optional["DeleteAssetCrossReference"] = None,
|
|
176
|
+
) -> None:
|
|
177
|
+
"""Add ``DeleteAssetCrossReference`` to remove an asset link.
|
|
178
|
+
|
|
179
|
+
Fields:
|
|
180
|
+
- ``AssetID``
|
|
181
|
+
- ``Type``
|
|
182
|
+
- ``QualifierID``
|
|
183
|
+
"""
|
|
184
|
+
from .deletion import DeleteAssetCrossReference
|
|
185
|
+
|
|
186
|
+
delete_ref = delete_ref_object or DeleteAssetCrossReference(
|
|
187
|
+
{"AssetID": asset_id, "Type": type_, "QualifierID": qualifier_id}
|
|
188
|
+
)
|
|
189
|
+
if not isinstance(self._data["DeleteAssetCrossReference"], list):
|
|
190
|
+
self._data["DeleteAssetCrossReference"] = []
|
|
191
|
+
self._data["DeleteAssetCrossReference"].append(delete_ref)
|
|
192
|
+
|
|
193
|
+
def add_product_reference(
|
|
194
|
+
self,
|
|
195
|
+
product_id: Optional[str] = None,
|
|
196
|
+
type_: Optional[str] = None,
|
|
197
|
+
qualifier_id: Optional[str] = None,
|
|
198
|
+
mount_location: Optional[str] = None,
|
|
199
|
+
ref_object: Optional["ProductCrossReference"] = None,
|
|
200
|
+
) -> None:
|
|
201
|
+
"""Add a ``ProductCrossReference``.
|
|
202
|
+
|
|
203
|
+
Fields:
|
|
204
|
+
- ``ProductID``
|
|
205
|
+
- ``Type``
|
|
206
|
+
- ``QualifierID``
|
|
207
|
+
- ``MountLocation``
|
|
208
|
+
"""
|
|
209
|
+
from .relations import ProductCrossReference
|
|
210
|
+
|
|
211
|
+
ref = ref_object or ProductCrossReference(
|
|
212
|
+
{
|
|
213
|
+
"ProductID": product_id,
|
|
214
|
+
"Type": type_,
|
|
215
|
+
"QualifierID": qualifier_id,
|
|
216
|
+
"MountLocation": mount_location,
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
if not isinstance(self._data["ProductCrossReference"], list):
|
|
220
|
+
self._data["ProductCrossReference"] = []
|
|
221
|
+
self._data["ProductCrossReference"].append(ref)
|
|
222
|
+
|
|
223
|
+
def delete_product_reference(
|
|
224
|
+
self,
|
|
225
|
+
product_id: Optional[str] = None,
|
|
226
|
+
type_: Optional[str] = None,
|
|
227
|
+
qualifier_id: Optional[str] = None,
|
|
228
|
+
mount_location: Optional[str] = None,
|
|
229
|
+
delete_ref_object: Optional["DeleteProductCrossReference"] = None,
|
|
230
|
+
) -> None:
|
|
231
|
+
"""Add ``DeleteProductCrossReference`` to remove a product link.
|
|
232
|
+
|
|
233
|
+
Fields:
|
|
234
|
+
- ``ProductID``
|
|
235
|
+
- ``Type``
|
|
236
|
+
- ``QualifierID``
|
|
237
|
+
- ``MountLocation``
|
|
238
|
+
"""
|
|
239
|
+
from .deletion import DeleteProductCrossReference
|
|
240
|
+
|
|
241
|
+
delete_ref = delete_ref_object or DeleteProductCrossReference(
|
|
242
|
+
{
|
|
243
|
+
"ProductID": product_id,
|
|
244
|
+
"Type": type_,
|
|
245
|
+
"QualifierID": qualifier_id,
|
|
246
|
+
"MountLocation": mount_location,
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
if not isinstance(self._data["DeleteProductCrossReference"], list):
|
|
250
|
+
self._data["DeleteProductCrossReference"] = []
|
|
251
|
+
self._data["DeleteProductCrossReference"].append(delete_ref)
|
|
252
|
+
|
|
253
|
+
def add_classification_reference(
|
|
254
|
+
self,
|
|
255
|
+
classification_id: Optional[str] = None,
|
|
256
|
+
type_: Optional[str] = None,
|
|
257
|
+
qualifier_id: Optional[str] = None,
|
|
258
|
+
mount_location: Optional[str] = None,
|
|
259
|
+
ref_object: Optional["ClassificationReference"] = None,
|
|
260
|
+
) -> None:
|
|
261
|
+
"""Add ``ClassificationReference`` (not CrossReference).
|
|
262
|
+
|
|
263
|
+
Fields:
|
|
264
|
+
- ``ClassificationID``
|
|
265
|
+
- ``Type``
|
|
266
|
+
- ``QualifierID``
|
|
267
|
+
- ``MountLocation``
|
|
268
|
+
"""
|
|
269
|
+
from .relations import ClassificationReference, ClassificationCrossReference
|
|
270
|
+
|
|
271
|
+
if ref_object is not None:
|
|
272
|
+
ref = ref_object
|
|
273
|
+
if isinstance(ref, ClassificationCrossReference):
|
|
274
|
+
ref = ClassificationReference(dict(ref._data))
|
|
275
|
+
else:
|
|
276
|
+
ref = ClassificationReference(
|
|
277
|
+
{
|
|
278
|
+
"ClassificationID": classification_id,
|
|
279
|
+
"Type": type_,
|
|
280
|
+
"QualifierID": qualifier_id,
|
|
281
|
+
"MountLocation": mount_location,
|
|
282
|
+
}
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
if not isinstance(self._data["ClassificationReference"], list):
|
|
286
|
+
self._data["ClassificationReference"] = []
|
|
287
|
+
self._data["ClassificationReference"].append(ref)
|
|
288
|
+
|
|
289
|
+
def add_classification_cross_reference(
|
|
290
|
+
self,
|
|
291
|
+
classification_id: Optional[str] = None,
|
|
292
|
+
type_: Optional[str] = None,
|
|
293
|
+
qualifier_id: Optional[str] = None,
|
|
294
|
+
mount_location: Optional[str] = None,
|
|
295
|
+
ref_object: Optional["ClassificationCrossReference"] = None,
|
|
296
|
+
) -> None:
|
|
297
|
+
"""Add explicit ``ClassificationCrossReference``.
|
|
298
|
+
|
|
299
|
+
Fields:
|
|
300
|
+
- ``ClassificationID``
|
|
301
|
+
- ``Type``
|
|
302
|
+
- ``QualifierID``
|
|
303
|
+
- ``MountLocation``
|
|
304
|
+
"""
|
|
305
|
+
from .relations import ClassificationCrossReference
|
|
306
|
+
|
|
307
|
+
ref = ref_object or ClassificationCrossReference(
|
|
308
|
+
{
|
|
309
|
+
"ClassificationID": classification_id,
|
|
310
|
+
"Type": type_,
|
|
311
|
+
"QualifierID": qualifier_id,
|
|
312
|
+
"MountLocation": mount_location,
|
|
313
|
+
}
|
|
314
|
+
)
|
|
315
|
+
if not isinstance(self._data["ClassificationCrossReference"], list):
|
|
316
|
+
self._data["ClassificationCrossReference"] = []
|
|
317
|
+
self._data["ClassificationCrossReference"].append(ref)
|
|
318
|
+
|
|
319
|
+
def add_entity_reference(
|
|
320
|
+
self,
|
|
321
|
+
entity_id: Optional[str] = None,
|
|
322
|
+
type_: Optional[str] = None,
|
|
323
|
+
qualifier_id: Optional[str] = None,
|
|
324
|
+
mount_location: Optional[str] = None,
|
|
325
|
+
ref_object: Optional["EntityCrossReference"] = None,
|
|
326
|
+
) -> None:
|
|
327
|
+
"""Add ``EntityCrossReference``.
|
|
328
|
+
|
|
329
|
+
Fields:
|
|
330
|
+
- ``EntityID``
|
|
331
|
+
- ``Type``
|
|
332
|
+
- ``QualifierID``
|
|
333
|
+
- ``MountLocation``
|
|
334
|
+
"""
|
|
335
|
+
from .relations import EntityCrossReference
|
|
336
|
+
|
|
337
|
+
ref = ref_object or EntityCrossReference(
|
|
338
|
+
{
|
|
339
|
+
"EntityID": entity_id,
|
|
340
|
+
"Type": type_,
|
|
341
|
+
"QualifierID": qualifier_id,
|
|
342
|
+
"MountLocation": mount_location,
|
|
343
|
+
}
|
|
344
|
+
)
|
|
345
|
+
if not isinstance(self._data["EntityCrossReference"], list):
|
|
346
|
+
self._data["EntityCrossReference"] = []
|
|
347
|
+
self._data["EntityCrossReference"].append(ref)
|
|
348
|
+
|
|
349
|
+
def set_workflow_state_bind(
|
|
350
|
+
self,
|
|
351
|
+
workflow_id: Optional[str] = None,
|
|
352
|
+
state_id: Optional[str] = None,
|
|
353
|
+
bind_data: Optional[Dict[str, Any]] = None,
|
|
354
|
+
bind_object: Optional["STEPWorkflowStateBind"] = None,
|
|
355
|
+
) -> None:
|
|
356
|
+
"""Set ``STEPWorkflowStateBind``.
|
|
357
|
+
|
|
358
|
+
Required XSD keys:
|
|
359
|
+
- ``WorkflowID``
|
|
360
|
+
- ``StateID``
|
|
361
|
+
|
|
362
|
+
Compatibility:
|
|
363
|
+
- legacy dict keys ``ID`` and ``CurrentStateID`` are normalized.
|
|
364
|
+
"""
|
|
365
|
+
if bind_object is not None:
|
|
366
|
+
self._data["STEPWorkflowStateBind"] = bind_object
|
|
367
|
+
return
|
|
368
|
+
|
|
369
|
+
if bind_data is not None:
|
|
370
|
+
normalized = dict(bind_data)
|
|
371
|
+
if "WorkflowID" not in normalized and "ID" in normalized:
|
|
372
|
+
normalized["WorkflowID"] = normalized.pop("ID")
|
|
373
|
+
if "StateID" not in normalized and "CurrentStateID" in normalized:
|
|
374
|
+
normalized["StateID"] = normalized.pop("CurrentStateID")
|
|
375
|
+
self._data["STEPWorkflowStateBind"] = normalized
|
|
376
|
+
return
|
|
377
|
+
|
|
378
|
+
self._data["STEPWorkflowStateBind"] = {
|
|
379
|
+
"WorkflowID": workflow_id,
|
|
380
|
+
"StateID": state_id,
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
def add_sequence_product(
|
|
384
|
+
self,
|
|
385
|
+
product_id: Optional[str] = None,
|
|
386
|
+
changed: Optional[bool] = None,
|
|
387
|
+
key_values: Optional[List[Dict[str, Any]]] = None,
|
|
388
|
+
sequence_data: Optional[Dict[str, Any]] = None,
|
|
389
|
+
sequence_object: Optional["SequenceProduct"] = None,
|
|
390
|
+
) -> None:
|
|
391
|
+
"""Add ``SequenceProduct``.
|
|
392
|
+
|
|
393
|
+
XSD fields:
|
|
394
|
+
- ``ID`` (required)
|
|
395
|
+
- ``Changed`` (optional)
|
|
396
|
+
- ``KeyValue`` (optional, list)
|
|
397
|
+
"""
|
|
398
|
+
if sequence_object is not None:
|
|
399
|
+
entry: Any = sequence_object
|
|
400
|
+
elif sequence_data is not None:
|
|
401
|
+
entry = sequence_data
|
|
402
|
+
else:
|
|
403
|
+
entry = {"ID": product_id, "Changed": changed, "KeyValue": key_values}
|
|
404
|
+
|
|
405
|
+
if not isinstance(self._data.get("SequenceProduct"), list):
|
|
406
|
+
self._data["SequenceProduct"] = []
|
|
407
|
+
self._data["SequenceProduct"].append(entry)
|
|
408
|
+
|
|
409
|
+
def add_current_task(self, task_data: Optional[Dict[str, Any]] = None) -> None:
|
|
410
|
+
"""Add ``CurrentTasks``/``Task`` data.
|
|
411
|
+
|
|
412
|
+
Typical task keys:
|
|
413
|
+
- ``STEPWorkflowID``
|
|
414
|
+
- ``StateID``
|
|
415
|
+
- ``AssigneeID``
|
|
416
|
+
- ``AssignedToGroup``
|
|
417
|
+
- ``EntryTime``
|
|
418
|
+
- optional: ``Deadline``, ``Priority``, ``StatusID``
|
|
419
|
+
"""
|
|
420
|
+
if not isinstance(self._data.get("CurrentTasks"), list):
|
|
421
|
+
self._data["CurrentTasks"] = []
|
|
422
|
+
self._data["CurrentTasks"].append(task_data or {})
|
|
423
|
+
|
|
424
|
+
def add_term(self, term_data: Optional[Dict[str, Any]] = None) -> None:
|
|
425
|
+
"""Add ``Terms``/``Term`` data.
|
|
426
|
+
|
|
427
|
+
Common term keys:
|
|
428
|
+
- ``TermsListID``
|
|
429
|
+
- ``MinimumQuantity`` / ``MaximumQuantity``
|
|
430
|
+
- ``StartDate`` / ``EndDate``
|
|
431
|
+
- ``LeadTime``
|
|
432
|
+
- ``UnitID``
|
|
433
|
+
- ``LotSize``
|
|
434
|
+
- optional text value: ``value``
|
|
435
|
+
"""
|
|
436
|
+
if not isinstance(self._data.get("Terms"), list):
|
|
437
|
+
self._data["Terms"] = []
|
|
438
|
+
self._data["Terms"].append(term_data or {})
|
|
439
|
+
|
|
440
|
+
def add_table(self, table_data: Optional[Dict[str, Any]] = None) -> None:
|
|
441
|
+
"""Add ``Tables`` data.
|
|
442
|
+
|
|
443
|
+
Supported container forms:
|
|
444
|
+
- ``{"Table": {...}}``
|
|
445
|
+
- ``{"TableDefinition": {...}}``
|
|
446
|
+
|
|
447
|
+
Common ``Table`` attributes:
|
|
448
|
+
- ``ID``
|
|
449
|
+
- ``ContextID``
|
|
450
|
+
- ``TableTypeID``
|
|
451
|
+
"""
|
|
452
|
+
if not isinstance(self._data.get("Tables"), list):
|
|
453
|
+
self._data["Tables"] = []
|
|
454
|
+
self._data["Tables"].append(table_data or {})
|
|
455
|
+
|
|
456
|
+
def add_override_sub_product(
|
|
457
|
+
self,
|
|
458
|
+
product_id: Optional[str] = None,
|
|
459
|
+
analyzer_result: Optional[str] = None,
|
|
460
|
+
override_data: Optional[Dict[str, Any]] = None,
|
|
461
|
+
override_object: Optional["OverrideSubProduct"] = None,
|
|
462
|
+
) -> None:
|
|
463
|
+
"""Add ``OverrideSubProduct``.
|
|
464
|
+
|
|
465
|
+
XSD fields:
|
|
466
|
+
- ``ProductID`` (required)
|
|
467
|
+
- ``AnalyzerResult`` (optional, deprecated)
|
|
468
|
+
"""
|
|
469
|
+
if override_object is not None:
|
|
470
|
+
entry: Any = override_object
|
|
471
|
+
elif override_data is not None:
|
|
472
|
+
entry = override_data
|
|
473
|
+
else:
|
|
474
|
+
entry = {"ProductID": product_id, "AnalyzerResult": analyzer_result}
|
|
475
|
+
|
|
476
|
+
if not isinstance(self._data.get("OverrideSubProduct"), list):
|
|
477
|
+
self._data["OverrideSubProduct"] = []
|
|
478
|
+
self._data["OverrideSubProduct"].append(entry)
|
|
479
|
+
|
|
480
|
+
def add_packaging_reference(
|
|
481
|
+
self,
|
|
482
|
+
product_id: Optional[str] = None,
|
|
483
|
+
quantity: Optional[str] = None,
|
|
484
|
+
packaging_data: Optional[Dict[str, Any]] = None,
|
|
485
|
+
packaging_object: Optional["PackagingReference"] = None,
|
|
486
|
+
) -> None:
|
|
487
|
+
"""Add ``PackagingReference``.
|
|
488
|
+
|
|
489
|
+
Required XSD fields:
|
|
490
|
+
- ``ProductID``
|
|
491
|
+
- ``Quantity``
|
|
492
|
+
"""
|
|
493
|
+
if packaging_object is not None:
|
|
494
|
+
entry: Any = packaging_object
|
|
495
|
+
elif packaging_data is not None:
|
|
496
|
+
entry = packaging_data
|
|
497
|
+
else:
|
|
498
|
+
entry = {"ProductID": product_id, "Quantity": quantity}
|
|
499
|
+
|
|
500
|
+
if not isinstance(self._data.get("PackagingReference"), list):
|
|
501
|
+
self._data["PackagingReference"] = []
|
|
502
|
+
self._data["PackagingReference"].append(entry)
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
class ProductReplacementRule(BaseObject):
|
|
506
|
+
_GROUP_NAME: str = "product_replacement_rules"
|
|
507
|
+
_TAG_NAME: str = "Product"
|
|
508
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
509
|
+
"ID",
|
|
510
|
+
"ParentId",
|
|
511
|
+
"UserTypeID",
|
|
512
|
+
"QualifierID",
|
|
513
|
+
"Changed",
|
|
514
|
+
"Republished",
|
|
515
|
+
"Selected",
|
|
516
|
+
"Referenced",
|
|
517
|
+
]
|
|
518
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
519
|
+
_CHILDREN_NAMES: List[str] = ["KeyValue", "ParentKeyValue", "Values"]
|