logs-py 4.0.7__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.
- LOGS/Auxiliary/CheckClassName.py +1075 -0
- LOGS/Auxiliary/Constants.py +99 -0
- LOGS/Auxiliary/CustomEntityClassGenerator.py +254 -0
- LOGS/Auxiliary/CustomFieldClassGenerator.py +115 -0
- LOGS/Auxiliary/CustomFieldValueTypeChecker.py +168 -0
- LOGS/Auxiliary/CustomSectionClassGenerator.py +113 -0
- LOGS/Auxiliary/CustomTypeClassGenerator.py +147 -0
- LOGS/Auxiliary/DateTimeConverter.py +66 -0
- LOGS/Auxiliary/Decorators.py +109 -0
- LOGS/Auxiliary/Exceptions.py +341 -0
- LOGS/Auxiliary/LOGSErrorResponse.py +89 -0
- LOGS/Auxiliary/MinimalModelGenerator.py +236 -0
- LOGS/Auxiliary/ParameterHelper.py +56 -0
- LOGS/Auxiliary/ReplaceMessage.py +13 -0
- LOGS/Auxiliary/Tools.py +432 -0
- LOGS/Auxiliary/__init__.py +15 -0
- LOGS/Converter/Conversion.py +248 -0
- LOGS/Converter/Converter.py +96 -0
- LOGS/Converter/ConverterParameter.py +88 -0
- LOGS/Converter/DateTimeRange.py +58 -0
- LOGS/Converter/ExportParameters.py +89 -0
- LOGS/Converter/__init__.py +13 -0
- LOGS/Entities/Attachment.py +84 -0
- LOGS/Entities/AttachmentMinimal.py +8 -0
- LOGS/Entities/AttachmentRequestParameter.py +42 -0
- LOGS/Entities/Attachments.py +53 -0
- LOGS/Entities/AutoloadFileInfo.py +12 -0
- LOGS/Entities/AutoloadStatusError.py +7 -0
- LOGS/Entities/AxisNaming.py +33 -0
- LOGS/Entities/AxisZoom.py +33 -0
- LOGS/Entities/Bridge.py +165 -0
- LOGS/Entities/BridgeClientInfo.py +93 -0
- LOGS/Entities/BridgeMinimal.py +8 -0
- LOGS/Entities/BridgeRequestParameter.py +49 -0
- LOGS/Entities/BridgeType.py +7 -0
- LOGS/Entities/Bridges.py +12 -0
- LOGS/Entities/CustomField.py +243 -0
- LOGS/Entities/CustomFieldMinimal.py +8 -0
- LOGS/Entities/CustomFieldModels.py +111 -0
- LOGS/Entities/CustomFieldRequestParameter.py +69 -0
- LOGS/Entities/CustomFieldSearchQuery.py +40 -0
- LOGS/Entities/CustomFields.py +12 -0
- LOGS/Entities/CustomType.py +212 -0
- LOGS/Entities/CustomTypeMinimal.py +8 -0
- LOGS/Entities/CustomTypeRequestParameter.py +60 -0
- LOGS/Entities/CustomTypeSection.py +63 -0
- LOGS/Entities/CustomTypes.py +12 -0
- LOGS/Entities/DataFormat.py +97 -0
- LOGS/Entities/DataFormatInstrument.py +18 -0
- LOGS/Entities/DataFormatInstrumentMinimal.py +8 -0
- LOGS/Entities/DataFormatInstrumentRequestParameter.py +17 -0
- LOGS/Entities/DataFormatInstruments.py +16 -0
- LOGS/Entities/DataFormatMinimal.py +18 -0
- LOGS/Entities/DataFormatRequestParameter.py +21 -0
- LOGS/Entities/DataFormats.py +12 -0
- LOGS/Entities/DataSource.py +218 -0
- LOGS/Entities/DataSourceConnectionStatus.py +12 -0
- LOGS/Entities/DataSourceMinimal.py +8 -0
- LOGS/Entities/DataSourceRequestParameter.py +57 -0
- LOGS/Entities/DataSourceStatus.py +108 -0
- LOGS/Entities/DataSourceStatusIterator.py +16 -0
- LOGS/Entities/DataSourceStatusRequestParameter.py +31 -0
- LOGS/Entities/DataSources.py +12 -0
- LOGS/Entities/Dataset.py +439 -0
- LOGS/Entities/DatasetBase.py +196 -0
- LOGS/Entities/DatasetCreator.py +148 -0
- LOGS/Entities/DatasetInfo.py +147 -0
- LOGS/Entities/DatasetMatchTypes.py +157 -0
- LOGS/Entities/DatasetMatching.py +196 -0
- LOGS/Entities/DatasetMinimal.py +8 -0
- LOGS/Entities/DatasetModels.py +33 -0
- LOGS/Entities/DatasetRequestParameter.py +92 -0
- LOGS/Entities/DatasetTemplate.py +23 -0
- LOGS/Entities/DatasetUploadParameter.py +14 -0
- LOGS/Entities/Datasets.py +142 -0
- LOGS/Entities/Datatrack.py +179 -0
- LOGS/Entities/DatatrackFormattedTable.py +25 -0
- LOGS/Entities/DatatrackGeneric.py +34 -0
- LOGS/Entities/DatatrackImage.py +25 -0
- LOGS/Entities/DatatrackNumericArray.py +30 -0
- LOGS/Entities/DatatrackNumericMatrix.py +98 -0
- LOGS/Entities/Entities.py +71 -0
- LOGS/Entities/EntitiesRequestParameter.py +18 -0
- LOGS/Entities/EntityOriginWriteModelWithId.py +15 -0
- LOGS/Entities/FileEntry.py +138 -0
- LOGS/Entities/FileExcludePattern.py +8 -0
- LOGS/Entities/FormatMetaData.py +56 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTable.py +135 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableCell.py +108 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableSettings.py +11 -0
- LOGS/Entities/FormattedTable/__init__.py +9 -0
- LOGS/Entities/HierarchyLeaf.py +15 -0
- LOGS/Entities/HierarchyNode.py +40 -0
- LOGS/Entities/ILiteraryTypedEntity.py +19 -0
- LOGS/Entities/InventoryItem.py +102 -0
- LOGS/Entities/InventoryItemMinimal.py +25 -0
- LOGS/Entities/InventoryItemRequestParameter.py +58 -0
- LOGS/Entities/InventoryItems.py +12 -0
- LOGS/Entities/LabNotebook.py +33 -0
- LOGS/Entities/LabNotebookEntries.py +16 -0
- LOGS/Entities/LabNotebookEntry.py +106 -0
- LOGS/Entities/LabNotebookEntryContent/BasicAttribute.py +15 -0
- LOGS/Entities/LabNotebookEntryContent/EntityAttribute.py +85 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBlockquote.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBulletList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentCallout.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentContentPlaceholderNode.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentConverter.py +207 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentDocument.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntity.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntityMention.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHeading.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHorizontalRule.py +12 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentItem.py +37 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentListItem.py +49 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentOrderedList.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentParagraph.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTable.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableCell.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableRow.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskListItem.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentText.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithAttribute.py +23 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithContent.py +38 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithTextAttribute.py +16 -0
- LOGS/Entities/LabNotebookEntryContent/TextAttribute.py +46 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkAtributes.py +64 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkConverter.py +45 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarks.py +71 -0
- LOGS/Entities/LabNotebookEntryContent/__init__.py +34 -0
- LOGS/Entities/LabNotebookEntryMinimal.py +8 -0
- LOGS/Entities/LabNotebookEntryRequestParameter.py +59 -0
- LOGS/Entities/LabNotebookExperiment.py +58 -0
- LOGS/Entities/LabNotebookExperimentMinimal.py +8 -0
- LOGS/Entities/LabNotebookExperimentRequestParameter.py +52 -0
- LOGS/Entities/LabNotebookExperiments.py +16 -0
- LOGS/Entities/LabNotebookMinimal.py +8 -0
- LOGS/Entities/LabNotebookModels.py +14 -0
- LOGS/Entities/LabNotebookRequestParameter.py +42 -0
- LOGS/Entities/LabNotebookTemplate.py +42 -0
- LOGS/Entities/LabNotebookTemplateMinimal.py +8 -0
- LOGS/Entities/LabNotebookTemplateRequestParameter.py +38 -0
- LOGS/Entities/LabNotebookTemplates.py +16 -0
- LOGS/Entities/LabNotebooks.py +12 -0
- LOGS/Entities/Method.py +66 -0
- LOGS/Entities/MethodMinimal.py +8 -0
- LOGS/Entities/MethodRequestParameter.py +16 -0
- LOGS/Entities/Methods.py +12 -0
- LOGS/Entities/Origin.py +53 -0
- LOGS/Entities/OriginMinimal.py +8 -0
- LOGS/Entities/OriginRequestParameter.py +28 -0
- LOGS/Entities/Origins.py +12 -0
- LOGS/Entities/ParserLog.py +49 -0
- LOGS/Entities/Permission.py +9 -0
- LOGS/Entities/Person.py +145 -0
- LOGS/Entities/PersonCategory.py +12 -0
- LOGS/Entities/PersonMinimal.py +8 -0
- LOGS/Entities/PersonRequestParameter.py +58 -0
- LOGS/Entities/Persons.py +12 -0
- LOGS/Entities/Project.py +52 -0
- LOGS/Entities/ProjectMinimal.py +8 -0
- LOGS/Entities/ProjectPersonPermission.py +102 -0
- LOGS/Entities/ProjectRequestParameter.py +58 -0
- LOGS/Entities/Projects.py +12 -0
- LOGS/Entities/Role.py +94 -0
- LOGS/Entities/RoleMinimal.py +8 -0
- LOGS/Entities/RoleRequestParameter.py +40 -0
- LOGS/Entities/Roles.py +12 -0
- LOGS/Entities/RunState.py +9 -0
- LOGS/Entities/Sample.py +53 -0
- LOGS/Entities/SampleMinimal.py +8 -0
- LOGS/Entities/SampleRequestParameter.py +54 -0
- LOGS/Entities/Samples.py +12 -0
- LOGS/Entities/SharedContent.py +87 -0
- LOGS/Entities/SharedContentMinimal.py +8 -0
- LOGS/Entities/SharedContentRequestParameter.py +38 -0
- LOGS/Entities/SharedContents.py +12 -0
- LOGS/Entities/Signature.py +60 -0
- LOGS/Entities/Track.py +93 -0
- LOGS/Entities/TrackData.py +20 -0
- LOGS/Entities/TrackImage.py +21 -0
- LOGS/Entities/TrackImageData.py +20 -0
- LOGS/Entities/TrackMatrix.py +28 -0
- LOGS/Entities/TrackMatrixData.py +22 -0
- LOGS/Entities/TrackSettings.py +55 -0
- LOGS/Entities/TrackTable.py +21 -0
- LOGS/Entities/TrackTableData.py +22 -0
- LOGS/Entities/TrackXY.py +40 -0
- LOGS/Entities/TrackXYComplex.py +51 -0
- LOGS/Entities/TrackXYComplexData.py +50 -0
- LOGS/Entities/TrackXYData.py +31 -0
- LOGS/Entities/Vendor.py +40 -0
- LOGS/Entities/VendorMinimal.py +8 -0
- LOGS/Entities/VendorRequestParameter.py +17 -0
- LOGS/Entities/Vendors.py +12 -0
- LOGS/Entities/__init__.py +118 -0
- LOGS/Entity/ConnectedEntity.py +170 -0
- LOGS/Entity/Entity.py +203 -0
- LOGS/Entity/EntityConnector.py +70 -0
- LOGS/Entity/EntityIterator.py +263 -0
- LOGS/Entity/EntityMinimal.py +141 -0
- LOGS/Entity/EntityMinimalWithIntId.py +36 -0
- LOGS/Entity/EntityMinimalWithStrId.py +36 -0
- LOGS/Entity/EntityMinimalWithType.py +47 -0
- LOGS/Entity/EntityRequestParameter.py +104 -0
- LOGS/Entity/EntitySortBy.py +69 -0
- LOGS/Entity/EntityWithIntId.py +26 -0
- LOGS/Entity/EntityWithStrId.py +26 -0
- LOGS/Entity/IGenericEntityOrderBy.py +55 -0
- LOGS/Entity/IdIterator.py +207 -0
- LOGS/Entity/SerializableContent.py +834 -0
- LOGS/Entity/__init__.py +23 -0
- LOGS/Interfaces/ICustomFieldValue.py +92 -0
- LOGS/Interfaces/ICustomSectionValue.py +161 -0
- LOGS/Interfaces/ICustomTypeValue.py +152 -0
- LOGS/Interfaces/ICustomValue.py +28 -0
- LOGS/Interfaces/IEntityInterface.py +7 -0
- LOGS/Interfaces/IEntryRecord.py +57 -0
- LOGS/Interfaces/IHierarchicalEntity.py +41 -0
- LOGS/Interfaces/IHierarchyType.py +63 -0
- LOGS/Interfaces/ILockableEntity.py +52 -0
- LOGS/Interfaces/IModificationRecord.py +56 -0
- LOGS/Interfaces/INamedEntity.py +25 -0
- LOGS/Interfaces/IOwnedEntity.py +27 -0
- LOGS/Interfaces/IPaginationRequest.py +11 -0
- LOGS/Interfaces/IPermissionedEntity.py +72 -0
- LOGS/Interfaces/IProjectBased.py +27 -0
- LOGS/Interfaces/ISessionedEntity.py +59 -0
- LOGS/Interfaces/ISignableEntity.py +49 -0
- LOGS/Interfaces/ISoftDeletable.py +28 -0
- LOGS/Interfaces/ITypedEntity.py +129 -0
- LOGS/Interfaces/IUniqueEntity.py +61 -0
- LOGS/Interfaces/IVersionedEntity.py +39 -0
- LOGS/Interfaces/__init__.py +7 -0
- LOGS/LOGS.py +1436 -0
- LOGS/LOGSConnection.py +647 -0
- LOGS/LOGSOptions.py +11 -0
- LOGS/Parameters/Color.py +92 -0
- LOGS/Parameters/ParameterBase.py +55 -0
- LOGS/Parameters/ParameterConverter.py +24 -0
- LOGS/Parameters/ParameterElement.py +99 -0
- LOGS/Parameters/ParameterList.py +52 -0
- LOGS/Parameters/ParameterTable.py +64 -0
- LOGS/Parameters/__init__.py +13 -0
- LOGS/ServerMetaData.py +120 -0
- LOGS/__init__.py +12 -0
- logs_py-4.0.7.dist-info/METADATA +51 -0
- logs_py-4.0.7.dist-info/RECORD +251 -0
- logs_py-4.0.7.dist-info/WHEEL +5 -0
- logs_py-4.0.7.dist-info/top_level.txt +1 -0
LOGS/Entity/__init__.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This package is written for the LOGS Repository.
|
|
3
|
+
|
|
4
|
+
It's objects can be used to write your own dataset parser.
|
|
5
|
+
|
|
6
|
+
License:
|
|
7
|
+
Permission to use this libraray and all of its contents is
|
|
8
|
+
strictly permitted to the Signals Company.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from ..Auxiliary.Exceptions import *
|
|
12
|
+
from .ConnectedEntity import *
|
|
13
|
+
from .Entity import *
|
|
14
|
+
from .EntityConnector import *
|
|
15
|
+
from .EntityIterator import *
|
|
16
|
+
from .EntityMinimal import *
|
|
17
|
+
from .EntityMinimalWithIntId import *
|
|
18
|
+
from .EntityMinimalWithStrId import *
|
|
19
|
+
from .EntityMinimalWithType import *
|
|
20
|
+
from .EntityRequestParameter import *
|
|
21
|
+
from .EntityWithIntId import *
|
|
22
|
+
from .EntityWithStrId import *
|
|
23
|
+
from .SerializableContent import *
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Optional, cast
|
|
3
|
+
|
|
4
|
+
from LOGS.Auxiliary.CustomFieldValueTypeChecker import CustomFieldValueTypeChecker
|
|
5
|
+
from LOGS.Auxiliary.Exceptions import EntityNotConnectedException
|
|
6
|
+
from LOGS.Auxiliary.Tools import Tools
|
|
7
|
+
from LOGS.Entities.CustomFieldModels import CustomFieldDataType, CustomFieldValueType
|
|
8
|
+
from LOGS.Interfaces.ICustomValue import ITypedCustomValue
|
|
9
|
+
from LOGS.LOGSConnection import LOGSConnection
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from LOGS.Entity.ConnectedEntity import ConnectedEntity
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ICustomFieldValue(ITypedCustomValue):
|
|
16
|
+
_type: CustomFieldValueType = CustomFieldValueType.CustomField
|
|
17
|
+
_valueTypeChecker: CustomFieldValueTypeChecker = cast(
|
|
18
|
+
CustomFieldValueTypeChecker, None
|
|
19
|
+
)
|
|
20
|
+
_newLineRe = re.compile(r"[\n\r\t\b\f]+")
|
|
21
|
+
_connection: Optional[LOGSConnection] = None
|
|
22
|
+
|
|
23
|
+
_id: Optional[int] = None
|
|
24
|
+
_dataType: CustomFieldDataType
|
|
25
|
+
_value: Optional[Any] = None
|
|
26
|
+
_name: Optional[str] = None
|
|
27
|
+
|
|
28
|
+
def __init__(self, ref=None, dataType: Optional[CustomFieldDataType] = None):
|
|
29
|
+
if not dataType:
|
|
30
|
+
raise Exception("Data type is not set")
|
|
31
|
+
self._dataType = dataType
|
|
32
|
+
self._setTypeChecker()
|
|
33
|
+
super().__init__(ref)
|
|
34
|
+
|
|
35
|
+
def _getConnection(self):
|
|
36
|
+
if not self._connection:
|
|
37
|
+
raise EntityNotConnectedException(cast("ConnectedEntity", self))
|
|
38
|
+
return self._connection
|
|
39
|
+
|
|
40
|
+
def _setTypeChecker(self):
|
|
41
|
+
self._valueTypeChecker = CustomFieldValueTypeChecker(
|
|
42
|
+
self._dataType, self._getConnection()
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def _contentToString(self) -> str:
|
|
46
|
+
if self._valueTypeChecker._isArrayType:
|
|
47
|
+
v = [str(f) for f in self.value] if self.value is not None else []
|
|
48
|
+
t = ", ".join(v)
|
|
49
|
+
else:
|
|
50
|
+
t = str(self.value) if self.value is not None else ""
|
|
51
|
+
t = self._newLineRe.sub(" ", t)
|
|
52
|
+
return Tools.truncString(t, 100)
|
|
53
|
+
|
|
54
|
+
def __str__(self):
|
|
55
|
+
id = f" [{'' + self._dataType.name + ']' if self._dataType else ''}{' ID:' + str(self.id) if self.id else ''}"
|
|
56
|
+
return f"<{type(self).__name__}{id}>"
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def identifier(self):
|
|
60
|
+
name = (
|
|
61
|
+
f" '{getattr(self, 'name')}'"
|
|
62
|
+
if hasattr(self, "name") and getattr(self, "name")
|
|
63
|
+
else ""
|
|
64
|
+
)
|
|
65
|
+
return "%s(id:%s)%s" % (
|
|
66
|
+
type(self).__name__,
|
|
67
|
+
str(self.id),
|
|
68
|
+
name,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def id(self) -> Optional[int]:
|
|
73
|
+
return self._id
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def dataType(self) -> Optional[CustomFieldDataType]:
|
|
77
|
+
return self._dataType
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def value(self) -> Optional[Any]:
|
|
81
|
+
return self._value
|
|
82
|
+
|
|
83
|
+
@value.setter
|
|
84
|
+
def value(self, value):
|
|
85
|
+
if not self._dataType:
|
|
86
|
+
raise Exception("Data type is not set")
|
|
87
|
+
|
|
88
|
+
self._value = self._valueTypeChecker.checkAndConvert(value, type(self).__name__)
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def name(self) -> Optional[str]:
|
|
92
|
+
return self._name
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union, cast
|
|
2
|
+
|
|
3
|
+
from LOGS.Auxiliary.Tools import Tools
|
|
4
|
+
from LOGS.Entities.CustomFieldModels import CustomFieldValueType
|
|
5
|
+
from LOGS.Interfaces.ICustomFieldValue import ICustomFieldValue
|
|
6
|
+
from LOGS.Interfaces.ICustomValue import ITypedCustomValue
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ICustomSectionValue(ITypedCustomValue):
|
|
13
|
+
_noSerialize: List[str] = ["fieldNames"]
|
|
14
|
+
|
|
15
|
+
_type: CustomFieldValueType = CustomFieldValueType.CustomTypeSection
|
|
16
|
+
_customTypeId: int = cast(int, None)
|
|
17
|
+
_sectionIndex: int = cast(int, None)
|
|
18
|
+
|
|
19
|
+
_fieldNames: List[str] = []
|
|
20
|
+
_fieldTypes: Dict[str, Type[ICustomFieldValue]] = {}
|
|
21
|
+
_fieldIds: Dict[int, str] = {}
|
|
22
|
+
_name: Optional[str] = None
|
|
23
|
+
|
|
24
|
+
def __init__(self, ref=None):
|
|
25
|
+
for fieldName in self._fieldNames:
|
|
26
|
+
setattr(self, "_" + fieldName, self._fieldTypes[fieldName]())
|
|
27
|
+
super().__init__(ref)
|
|
28
|
+
|
|
29
|
+
def fromDict(self, ref) -> None:
|
|
30
|
+
if isinstance(ref, dict) and "content" in ref:
|
|
31
|
+
content = ref["content"]
|
|
32
|
+
del ref["content"]
|
|
33
|
+
|
|
34
|
+
super().fromDict(ref)
|
|
35
|
+
|
|
36
|
+
if content is not None:
|
|
37
|
+
if not isinstance(content, list):
|
|
38
|
+
raise ValueError(
|
|
39
|
+
f"Invalid content format. (Expected a 'list' got '{type(content).__name__}')"
|
|
40
|
+
)
|
|
41
|
+
for i, c in enumerate(content):
|
|
42
|
+
if not isinstance(c, dict):
|
|
43
|
+
raise ValueError(
|
|
44
|
+
f"Invalid content item {i} format. (Expected a 'dict' got '{type(c).__name__}')"
|
|
45
|
+
)
|
|
46
|
+
if "value" not in c:
|
|
47
|
+
continue
|
|
48
|
+
if "id" not in c:
|
|
49
|
+
raise ValueError(f"Content item {i} is missing the 'id' field.")
|
|
50
|
+
fieldId = Tools.checkAndConvert(
|
|
51
|
+
c["id"], int, f"content[{i}].id", allowNone=False
|
|
52
|
+
)
|
|
53
|
+
self.setField(fieldId, c["value"])
|
|
54
|
+
|
|
55
|
+
def toDict(self) -> Dict[str, Any]:
|
|
56
|
+
result = super().toDict()
|
|
57
|
+
content = []
|
|
58
|
+
for name in self._fieldNames:
|
|
59
|
+
field = self.getCustomField(name)
|
|
60
|
+
if field is not None:
|
|
61
|
+
content.append(field.toDict() if hasattr(field, "toDict") else field)
|
|
62
|
+
result["content"] = content
|
|
63
|
+
return result
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def _generateId(cls, customTypeId: int, sectionIndex: int):
|
|
67
|
+
return f"{customTypeId}.{sectionIndex}"
|
|
68
|
+
|
|
69
|
+
def _getFieldNameFromId(self, fieldId: int) -> str:
|
|
70
|
+
if fieldId not in self._fieldIds:
|
|
71
|
+
raise AttributeError(f"Unknown field ID '{type(self).__name__}.{fieldId}'.")
|
|
72
|
+
return self._fieldIds[fieldId]
|
|
73
|
+
|
|
74
|
+
def setField(self, fieldNameOrId: Union[str, int], value):
|
|
75
|
+
fieldName = (
|
|
76
|
+
self._getFieldNameFromId(fieldNameOrId)
|
|
77
|
+
if isinstance(fieldNameOrId, int)
|
|
78
|
+
else fieldNameOrId
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
if fieldName not in self._fieldNames:
|
|
82
|
+
raise AttributeError(f"Unknown field '{type(self).__name__}.{fieldName}'.")
|
|
83
|
+
f = self.getCustomField(fieldName)
|
|
84
|
+
if f is not None:
|
|
85
|
+
f.value = value
|
|
86
|
+
|
|
87
|
+
def getField(self, fieldNameOrId: Union[str, int]):
|
|
88
|
+
fieldName = (
|
|
89
|
+
self._getFieldNameFromId(fieldNameOrId)
|
|
90
|
+
if isinstance(fieldNameOrId, int)
|
|
91
|
+
else fieldNameOrId
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if fieldName not in self._fieldNames:
|
|
95
|
+
raise AttributeError(f"Unknown field '{type(self).__name__}.{fieldName}'.")
|
|
96
|
+
f = self.getCustomField(fieldName)
|
|
97
|
+
return f.value if f is not None else None
|
|
98
|
+
|
|
99
|
+
def _getCustomFieldByName(self, fieldName: str) -> Optional[ICustomFieldValue]:
|
|
100
|
+
return getattr(self, "_" + fieldName)
|
|
101
|
+
|
|
102
|
+
def getCustomField(self, fieldName: str) -> Optional[ICustomFieldValue]:
|
|
103
|
+
if fieldName not in self._fieldNames:
|
|
104
|
+
raise AttributeError(
|
|
105
|
+
f"Unknown custom field '{type(self).__name__}.{fieldName}'."
|
|
106
|
+
)
|
|
107
|
+
return self._getCustomFieldByName(fieldName)
|
|
108
|
+
|
|
109
|
+
def _contentToString(self, indentation: int = 0, hideNone: bool = False) -> str:
|
|
110
|
+
s = ""
|
|
111
|
+
for name in self._fieldNames:
|
|
112
|
+
field = self.getCustomField(name)
|
|
113
|
+
if field is not None:
|
|
114
|
+
content = field._contentToString()
|
|
115
|
+
if not content and hideNone:
|
|
116
|
+
continue
|
|
117
|
+
s += f"{self._indentationString * indentation}{name} = {content}\n"
|
|
118
|
+
return s
|
|
119
|
+
|
|
120
|
+
def __str__(self):
|
|
121
|
+
id1 = f"typeID:{self._customTypeId}" if self._customTypeId is not None else ""
|
|
122
|
+
id2 = f"index:{self._sectionIndex}" if self._sectionIndex is not None else ""
|
|
123
|
+
id = f"{id1}{' ' if id2 else ''}{id2}; " if id1 or id2 else ""
|
|
124
|
+
return f"<{type(self).__name__} [{id}{Tools.numberPlural('field' , len(self._fieldNames))}]>"
|
|
125
|
+
|
|
126
|
+
def customField(self, nameOrId) -> Optional[ICustomFieldValue]:
|
|
127
|
+
for name in self._fieldNames:
|
|
128
|
+
value = self._getCustomFieldByName(name)
|
|
129
|
+
if isinstance(nameOrId, int):
|
|
130
|
+
if value is not None and value.id == nameOrId:
|
|
131
|
+
return value
|
|
132
|
+
else:
|
|
133
|
+
if value is not None and value.name == str(nameOrId):
|
|
134
|
+
return value
|
|
135
|
+
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
@classmethod
|
|
139
|
+
def getId(cls) -> str:
|
|
140
|
+
return cls._generateId(cls._customTypeId, cls._sectionIndex)
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def customFields(self) -> List[ICustomFieldValue]:
|
|
144
|
+
result = []
|
|
145
|
+
for name in self._fieldNames:
|
|
146
|
+
value = self._getCustomFieldByName(name)
|
|
147
|
+
if value is not None:
|
|
148
|
+
result.append(value)
|
|
149
|
+
return result
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def fieldNames(self) -> List[str]:
|
|
153
|
+
return self._fieldNames
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def name(self) -> Optional[str]:
|
|
157
|
+
return self._name
|
|
158
|
+
|
|
159
|
+
@name.setter
|
|
160
|
+
def name(self, value):
|
|
161
|
+
self._name = self.checkAndConvertNullable(value, str, "name")
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union, cast
|
|
2
|
+
|
|
3
|
+
from LOGS.Interfaces.ICustomFieldValue import ICustomFieldValue
|
|
4
|
+
from LOGS.Interfaces.ICustomSectionValue import ICustomSectionValue
|
|
5
|
+
from LOGS.Interfaces.ICustomValue import ICustomValue
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ICustomTypeValue(ICustomValue):
|
|
12
|
+
_id: Optional[int] = None
|
|
13
|
+
_name: Optional[str] = None
|
|
14
|
+
|
|
15
|
+
_fieldNames: List[str] = []
|
|
16
|
+
_fieldTypes: Dict[str, Type[ICustomFieldValue]] = {}
|
|
17
|
+
_fieldIds: Dict[int, str] = {}
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
ref=None,
|
|
22
|
+
):
|
|
23
|
+
for fieldName in self._fieldNames:
|
|
24
|
+
setattr(self, "_" + fieldName, self._fieldTypes[fieldName]())
|
|
25
|
+
if not isinstance(ref, dict):
|
|
26
|
+
ref = {"content": ref}
|
|
27
|
+
super().__init__(ref)
|
|
28
|
+
|
|
29
|
+
def fromDict(self, ref) -> None:
|
|
30
|
+
if isinstance(ref, dict) and "content" in ref:
|
|
31
|
+
content = ref["content"]
|
|
32
|
+
del ref["content"]
|
|
33
|
+
|
|
34
|
+
super().fromDict(ref)
|
|
35
|
+
|
|
36
|
+
if content is not None:
|
|
37
|
+
if not isinstance(content, list):
|
|
38
|
+
raise ValueError(
|
|
39
|
+
f"Invalid content format. (Expected a 'list' got '{type(content).__name__}')"
|
|
40
|
+
)
|
|
41
|
+
for i, c in enumerate(content):
|
|
42
|
+
if not isinstance(c, dict):
|
|
43
|
+
raise ValueError(
|
|
44
|
+
f"Invalid content item {i} format. (Expected a 'dict' got '{type(c).__name__}')"
|
|
45
|
+
)
|
|
46
|
+
if "type" not in c:
|
|
47
|
+
raise ValueError(f"Content item {i} is missing the 'type' field.")
|
|
48
|
+
if c["type"] != "CustomTypeSection" or "content" not in c:
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
s = self.getSection(i)
|
|
52
|
+
if s is not None:
|
|
53
|
+
s.override(c)
|
|
54
|
+
|
|
55
|
+
def toDict(self) -> Dict[str, Any]:
|
|
56
|
+
result = super().toDict()
|
|
57
|
+
content = []
|
|
58
|
+
for name in self._fieldNames:
|
|
59
|
+
field = self.getSection(name)
|
|
60
|
+
if field is not None:
|
|
61
|
+
content.append(field.toDict() if hasattr(field, "toDict") else field)
|
|
62
|
+
# print("content:", content)
|
|
63
|
+
return cast(Any, content)
|
|
64
|
+
|
|
65
|
+
def __str__(self):
|
|
66
|
+
id = f" [ID: {self.id}]" if self.id else ""
|
|
67
|
+
return f"<{type(self).__name__}{id}>"
|
|
68
|
+
|
|
69
|
+
def _contentToString(self, indentation: int = 0, hideNone: bool = False) -> str:
|
|
70
|
+
tab = self._indentationString * indentation
|
|
71
|
+
s = ""
|
|
72
|
+
for name in self._fieldNames:
|
|
73
|
+
section = self.getSection(name)
|
|
74
|
+
if not section and hideNone:
|
|
75
|
+
continue
|
|
76
|
+
content = ""
|
|
77
|
+
if section is not None:
|
|
78
|
+
content = section._contentToString(indentation + 1, hideNone=hideNone)
|
|
79
|
+
if not content and hideNone:
|
|
80
|
+
continue
|
|
81
|
+
s += f"{tab}{name}:\n{content}"
|
|
82
|
+
return s
|
|
83
|
+
|
|
84
|
+
def _getFieldNameFromId(self, fieldId: str) -> str:
|
|
85
|
+
if fieldId in self._fieldIds:
|
|
86
|
+
return self._fieldIds[fieldId]
|
|
87
|
+
return fieldId
|
|
88
|
+
|
|
89
|
+
def getField(self, fieldNameOrId: str):
|
|
90
|
+
fieldName = self._getFieldNameFromId(fieldNameOrId)
|
|
91
|
+
|
|
92
|
+
if fieldName not in self._fieldNames:
|
|
93
|
+
raise AttributeError(f"Unknown field '{type(self).__name__}.{fieldName}'.")
|
|
94
|
+
return self.getSection(fieldName)
|
|
95
|
+
|
|
96
|
+
def _getSectionByName(self, sectionName: str) -> Optional[ICustomSectionValue]:
|
|
97
|
+
return getattr(self, "_" + sectionName)
|
|
98
|
+
|
|
99
|
+
def getSection(
|
|
100
|
+
self, sectionIndexOrFieldId: Union[str, int]
|
|
101
|
+
) -> Optional[ICustomSectionValue]:
|
|
102
|
+
|
|
103
|
+
if isinstance(sectionIndexOrFieldId, int):
|
|
104
|
+
if self.id is None:
|
|
105
|
+
raise ValueError(f"Section with index {sectionIndexOrFieldId} unknown")
|
|
106
|
+
fieldId = ICustomSectionValue._generateId(self.id, sectionIndexOrFieldId)
|
|
107
|
+
else:
|
|
108
|
+
fieldId = sectionIndexOrFieldId
|
|
109
|
+
|
|
110
|
+
fieldName = self._getFieldNameFromId(fieldId)
|
|
111
|
+
if fieldName not in self._fieldNames:
|
|
112
|
+
raise AttributeError(
|
|
113
|
+
f"Section with index or name '{sectionIndexOrFieldId}' unknown."
|
|
114
|
+
)
|
|
115
|
+
return self._getSectionByName(fieldName)
|
|
116
|
+
|
|
117
|
+
def printFieldValues(self, hideNone: bool = False):
|
|
118
|
+
|
|
119
|
+
s = f"{type(self).__name__}"
|
|
120
|
+
|
|
121
|
+
customFields = self.customFields
|
|
122
|
+
for field in customFields:
|
|
123
|
+
if hideNone and (field.value is None or field.value == ""):
|
|
124
|
+
continue
|
|
125
|
+
s += f"\n{self._indentationString}{field.name} [{field.id}] = {field.value}"
|
|
126
|
+
print(s)
|
|
127
|
+
|
|
128
|
+
def customField(self, nameOrId) -> Optional[ICustomFieldValue]:
|
|
129
|
+
for name in self._fieldNames:
|
|
130
|
+
section = self._getSectionByName(name)
|
|
131
|
+
if section is not None:
|
|
132
|
+
field = section.customField(nameOrId)
|
|
133
|
+
if field is not None:
|
|
134
|
+
return field
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def customFields(self) -> List[ICustomFieldValue]:
|
|
139
|
+
result = []
|
|
140
|
+
for name in self._fieldNames:
|
|
141
|
+
section = self._getSectionByName(name)
|
|
142
|
+
if section is not None:
|
|
143
|
+
result.extend(section.customFields)
|
|
144
|
+
return result
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def id(self) -> Optional[int]:
|
|
148
|
+
return self._id
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def name(self) -> Optional[str]:
|
|
152
|
+
return self._name
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, cast
|
|
2
|
+
|
|
3
|
+
from LOGS.Auxiliary.Exceptions import IllegalFieldValueException
|
|
4
|
+
from LOGS.Entities.CustomFieldModels import CustomFieldValueType
|
|
5
|
+
from LOGS.Entity.SerializableContent import SerializableContent
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ICustomValue(SerializableContent):
|
|
12
|
+
_indentationString: str = " "
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ITypedCustomValue(ICustomValue):
|
|
16
|
+
_type: CustomFieldValueType = cast(CustomFieldValueType, None)
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def type(self) -> CustomFieldValueType:
|
|
20
|
+
return self._type
|
|
21
|
+
|
|
22
|
+
@type.setter
|
|
23
|
+
def type(self, value):
|
|
24
|
+
value = self.checkAndConvert(value, CustomFieldValueType, "type")
|
|
25
|
+
if value != self._type:
|
|
26
|
+
raise IllegalFieldValueException(
|
|
27
|
+
self, "type", value, f"Only value '{self._type}' allowed."
|
|
28
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
4
|
+
|
|
5
|
+
from LOGS.Auxiliary import Tools
|
|
6
|
+
from LOGS.Auxiliary.MinimalModelGenerator import MinimalModelGenerator
|
|
7
|
+
from LOGS.Interfaces.IEntityInterface import IEntityInterface
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from LOGS.Entities.PersonMinimal import PersonMinimal
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class IEnteredOnRequest:
|
|
15
|
+
enteredFrom: Optional[datetime] = None
|
|
16
|
+
enteredTo: Optional[datetime] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IEnteredByRequest:
|
|
20
|
+
createdByIds: Optional[List[int]]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class IEntryRecordRequest(IEnteredOnRequest, IEnteredByRequest):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class IEnteredOn(IEntityInterface):
|
|
29
|
+
_enteredOn: Optional[datetime] = None
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def enteredOn(self) -> Optional[datetime]:
|
|
33
|
+
return self._enteredOn
|
|
34
|
+
|
|
35
|
+
@enteredOn.setter
|
|
36
|
+
def enteredOn(self, value):
|
|
37
|
+
self._enteredOn = Tools.checkAndConvert(
|
|
38
|
+
value, datetime, "enteredOn", allowNone=True
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class IEnteredBy(IEntityInterface):
|
|
43
|
+
_enteredBy: Optional["PersonMinimal"] = None
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def enteredBy(self) -> Optional["PersonMinimal"]:
|
|
47
|
+
return self._enteredBy
|
|
48
|
+
|
|
49
|
+
@enteredBy.setter
|
|
50
|
+
def enteredBy(self, value):
|
|
51
|
+
self._enteredBy = MinimalModelGenerator.MinimalFromSingle(
|
|
52
|
+
value, "PersonMinimal", "enteredBy", connection=self._getEntityConnection()
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class IEntryRecord(IEnteredOn, IEnteredBy):
|
|
57
|
+
pass
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
3
|
+
|
|
4
|
+
from LOGS.Auxiliary.MinimalModelGenerator import MinimalModelGenerator
|
|
5
|
+
from LOGS.Interfaces.IEntityInterface import IEntityInterface
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from LOGS.Entities.InventoryItemMinimal import InventoryItemMinimal
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class IHierarchicalEntityRequest:
|
|
13
|
+
childrenOfParentIds: Optional[List[int]] = None
|
|
14
|
+
descendantsOfIds: Optional[List[int]] = None
|
|
15
|
+
excludeHierarchyChildren: Optional[bool] = None
|
|
16
|
+
isHierarchyRoot: Optional[bool] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IHierarchicalEntity(IEntityInterface):
|
|
20
|
+
_ancestors: Optional[List["InventoryItemMinimal"]] = None
|
|
21
|
+
_parent: Optional["InventoryItemMinimal"] = None
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def ancestors(self) -> Optional[List["InventoryItemMinimal"]]:
|
|
25
|
+
return self._ancestors
|
|
26
|
+
|
|
27
|
+
@ancestors.setter
|
|
28
|
+
def ancestors(self, value):
|
|
29
|
+
self._ancestors = MinimalModelGenerator.MinimalFromList(
|
|
30
|
+
value, "InventoryItemMinimal", "ancestors", self._getEntityConnection()
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def parent(self) -> Optional["InventoryItemMinimal"]:
|
|
35
|
+
return self._parent
|
|
36
|
+
|
|
37
|
+
@parent.setter
|
|
38
|
+
def parent(self, value):
|
|
39
|
+
self._parent = MinimalModelGenerator.MinimalFromSingle(
|
|
40
|
+
value, "InventoryItemMinimal", "parent", self._getEntityConnection()
|
|
41
|
+
)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
3
|
+
|
|
4
|
+
from LOGS.Auxiliary import Tools
|
|
5
|
+
from LOGS.Entity.EntityMinimalWithIntId import EntityMinimalWithIntId
|
|
6
|
+
from LOGS.Interfaces.IEntityInterface import IEntityInterface
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class IHierarchyTypeRequest:
|
|
14
|
+
childrenOfParentIds: Optional[List[int]] = None
|
|
15
|
+
descendantsOfIds: Optional[List[int]] = None
|
|
16
|
+
isRoot: Optional[List[bool]] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IHierarchyType(IEntityInterface):
|
|
20
|
+
_inventoryName: Optional[str]
|
|
21
|
+
_isHierarchyRoot: Optional[bool]
|
|
22
|
+
_rootHierarchy: Optional[EntityMinimalWithIntId]
|
|
23
|
+
_parentTypes: Optional[List[EntityMinimalWithIntId]]
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def inventoryName(self) -> Optional[str]:
|
|
27
|
+
return self._inventoryName
|
|
28
|
+
|
|
29
|
+
@inventoryName.setter
|
|
30
|
+
def inventoryName(self, value):
|
|
31
|
+
self._inventoryName = Tools.checkAndConvert(
|
|
32
|
+
value, str, "inventoryName", allowNone=True
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def isHierarchyRoot(self) -> Optional[bool]:
|
|
37
|
+
return self._isHierarchyRoot
|
|
38
|
+
|
|
39
|
+
@isHierarchyRoot.setter
|
|
40
|
+
def isHierarchyRoot(self, value):
|
|
41
|
+
self._isHierarchyRoot = Tools.checkAndConvert(
|
|
42
|
+
value, bool, "isHierarchyRoot", allowNone=True
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def rootHierarchy(self) -> Optional[EntityMinimalWithIntId]:
|
|
47
|
+
return self._rootHierarchy
|
|
48
|
+
|
|
49
|
+
@rootHierarchy.setter
|
|
50
|
+
def rootHierarchy(self, value):
|
|
51
|
+
self._rootHierarchy = Tools.checkAndConvert(
|
|
52
|
+
value, EntityMinimalWithIntId, "rootHierarchy", allowNone=True
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def parentTypes(self) -> Optional[List[EntityMinimalWithIntId]]:
|
|
57
|
+
return self._parentTypes
|
|
58
|
+
|
|
59
|
+
@parentTypes.setter
|
|
60
|
+
def parentTypes(self, value):
|
|
61
|
+
self._parentTypes = Tools.checkListAndConvert(
|
|
62
|
+
value, EntityMinimalWithIntId, "parentTypes", allowNone=True
|
|
63
|
+
)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import TYPE_CHECKING, List, Optional, Union
|
|
4
|
+
|
|
5
|
+
from LOGS.Auxiliary.MinimalModelGenerator import MinimalModelGenerator
|
|
6
|
+
from LOGS.Auxiliary.Tools import Tools
|
|
7
|
+
from LOGS.Interfaces.IEntityInterface import IEntityInterface
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from LOGS.Entities.PersonMinimal import PersonMinimal
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class ILockableEntityRequest:
|
|
15
|
+
lockedByIds: Optional[List[int]] = None
|
|
16
|
+
lockedFrom: Optional[datetime] = None
|
|
17
|
+
lockedTo: Optional[datetime] = None
|
|
18
|
+
isLocked: Optional[bool] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ILockableEntity(IEntityInterface):
|
|
22
|
+
_lockedBy: Optional["PersonMinimal"] = None
|
|
23
|
+
_lockedOn: Optional[datetime] = None
|
|
24
|
+
_isLocked: Optional[bool] = None
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def lockedBy(self) -> Optional["PersonMinimal"]:
|
|
28
|
+
return self._lockedBy
|
|
29
|
+
|
|
30
|
+
@lockedBy.setter
|
|
31
|
+
def lockedBy(self, value):
|
|
32
|
+
self._lockedBy = MinimalModelGenerator.MinimalFromSingle(
|
|
33
|
+
value, "PersonMinimal", "lockedBy", self._getEntityConnection()
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def lockedOn(self) -> Optional[datetime]:
|
|
38
|
+
return self._lockedOn
|
|
39
|
+
|
|
40
|
+
@lockedOn.setter
|
|
41
|
+
def lockedOn(self, value: Optional[Union[datetime, dict]]):
|
|
42
|
+
self._lockedOn = Tools.checkAndConvert(
|
|
43
|
+
value, datetime, "lockedOn", allowNone=True
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def isLocked(self) -> Optional[bool]:
|
|
48
|
+
return self._isLocked
|
|
49
|
+
|
|
50
|
+
@isLocked.setter
|
|
51
|
+
def isLocked(self, value: Optional[bool]):
|
|
52
|
+
self._isLocked = Tools.checkAndConvert(value, bool, "isLocked", allowNone=True)
|