From 6fa2c0f53101f05feb70c123ba6e148b194f8fdd Mon Sep 17 00:00:00 2001 From: "S.Listl" <S.Listl@SLISTL.aditosoftware.local> Date: Thu, 8 Aug 2019 18:38:00 +0200 Subject: [PATCH] Keyword main view removed --- entity/Attribute_entity/Attribute_entity.aod | 820 +++---- .../dropdowndefinition/dropDownProcess.js | 26 +- .../dropdowndefinition/placeholderProcess.js | 22 +- .../dropdowndefinition/titleProcess.js | 22 +- .../recordcontainers/jdito/contentProcess.js | 418 ++-- .../recordcontainers/jdito/onUpdate.js | 51 +- .../KeywordAttributeRelation_entity.aod | 343 ++- .../documentation.adoc | 0 .../KeywordAttribute_entity.aod | 256 +- .../recordcontainers/db/conditionProcess.js | 40 +- .../KeywordEntry_entity.aod | 1201 +++++---- .../keywordattributerelations/onValidation.js | 82 + .../keywordentryid_param/valueProcess.js | 4 - .../documentation.adoc | 2 - entity/KeywordEntry_entity/onValidation.js | 44 +- neonContext/KeywordEntry/KeywordEntry.aod | 9 - .../KeywordEntryMainSide_view.aod | 37 - .../KeywordEntryMain_view.aod | 23 - .../KeywordEntryPreview_view.aod | 90 +- process/Attribute_lib/process.js | 2170 ++++++++--------- 20 files changed, 2824 insertions(+), 2836 deletions(-) create mode 100644 entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/filteralreadyusedbyentryid_param/documentation.adoc create mode 100644 entity/KeywordEntry_entity/entityfields/keywordattributerelations/onValidation.js delete mode 100644 entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/children/keywordentryid_param/valueProcess.js delete mode 100644 entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/documentation.adoc delete mode 100644 neonView/KeywordEntryMainSide_view/KeywordEntryMainSide_view.aod delete mode 100644 neonView/KeywordEntryMain_view/KeywordEntryMain_view.aod diff --git a/entity/Attribute_entity/Attribute_entity.aod b/entity/Attribute_entity/Attribute_entity.aod index 0800311201e..c95832f4435 100644 --- a/entity/Attribute_entity/Attribute_entity.aod +++ b/entity/Attribute_entity/Attribute_entity.aod @@ -1,410 +1,410 @@ -<?xml version="1.0" encoding="UTF-8"?> -<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> - <name>Attribute_entity</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <documentation>%aditoprj%/entity/Attribute_entity/documentation.adoc</documentation> - <title>Attribute</title> - <contentTitleProcess>%aditoprj%/entity/Attribute_entity/contentTitleProcess.js</contentTitleProcess> - <afterUiInit>%aditoprj%/entity/Attribute_entity/afterUiInit.js</afterUiInit> - <onValidation>%aditoprj%/entity/Attribute_entity/onValidation.js</onValidation> - <iconId>VAADIN:TAG</iconId> - <titlePlural>Attributes</titlePlural> - <recordContainer>jdito</recordContainer> - <entityFields> - <entityProvider> - <name>#PROVIDER</name> - </entityProvider> - <entityField> - <name>ATTRIBUTE_NAME</name> - <title>Title (original language)</title> - <mandatory v="true" /> - <state>EDITABLE</state> - </entityField> - <entityField> - <name>ATTRIBUTE_TYPE</name> - <title>Type</title> - <consumer>KeywordAttributeTypes</consumer> - <mandatory v="true" /> - <state>READONLY</state> - <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js</stateProcess> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/valueProcess.js</valueProcess> - <displayValueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/displayValueProcess.js</displayValueProcess> - <onValueChange>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/onValueChange.js</onValueChange> - </entityField> - <entityField> - <name>ATTRIBUTE_PARENT_ID</name> - <title>Superordinate Attribute</title> - <consumer>AttributeGroup</consumer> - <linkedContext>Attribute</linkedContext> - <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/stateProcess.js</stateProcess> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/valueProcess.js</valueProcess> - <displayValueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/displayValueProcess.js</displayValueProcess> - <onValueChangeTypes> - <element>MASK</element> - <element>PROCESS</element> - <element>PROCESS_SETVALUE</element> - </onValueChangeTypes> - </entityField> - <entityConsumer> - <name>AttributeChildren</name> - <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributechildren/stateProcess.js</stateProcess> - <dependency> - <name>dependency</name> - <entityName>Attribute_entity</entityName> - <fieldName>AttributeParent</fieldName> - </dependency> - <children> - <entityParameter> - <name>AttrParentId_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/valueProcess.js</valueProcess> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>AttrParentType_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributechildren/children/attrparenttype_param/valueProcess.js</valueProcess> - <expose v="false" /> - </entityParameter> - </children> - </entityConsumer> - <entityProvider> - <name>AttributeParent</name> - <dependencies> - <entityDependency> - <name>18bd148d-bed3-429f-ba54-c5eac76c5083</name> - <entityName>Attribute_entity</entityName> - <fieldName>AttributeChildren</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>9fb3569c-7c75-48b1-9dc0-3f707940813a</name> - <entityName>Employee_entity</entityName> - <fieldName>Departments</fieldName> - <isConsumer v="false" /> - </entityDependency> - </dependencies> - <children> - <entityParameter> - <name>AttrParentType_param</name> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>AttrParentId_param</name> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>AttributeCount_param</name> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>ObjectType_param</name> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>GetGroups_param</name> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>AttributeTypes_param</name> - <expose v="false" /> - </entityParameter> - </children> - </entityProvider> - <entityParameter> - <name>AttrParentId_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityConsumer> - <name>AttributeUsages</name> - <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/stateProcess.js</stateProcess> - <dependency> - <name>dependency</name> - <entityName>AttributeUsage_entity</entityName> - <fieldName>SpecificAttribute</fieldName> - </dependency> - <children> - <entityParameter> - <name>AttributeId_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/children/attributeid_param/valueProcess.js</valueProcess> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>SingleSelection_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/children/singleselection_param/valueProcess.js</valueProcess> - </entityParameter> - <entityParameter> - <name>DisableMinCount_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/children/disablemincount_param/valueProcess.js</valueProcess> - </entityParameter> - </children> - </entityConsumer> - <entityField> - <name>ATTRIBUTE_ACTIVE</name> - <title>Active</title> - <contentType>BOOLEAN</contentType> - <groupable v="true" /> - <dropDownProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_active/dropDownProcess.js</dropDownProcess> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_active/valueProcess.js</valueProcess> - </entityField> - <entityConsumer> - <name>KeywordAttributeTypes</name> - <dependency> - <name>dependency</name> - <entityName>KeywordEntry_entity</entityName> - <fieldName>SpecificContainerKeywords</fieldName> - </dependency> - <children> - <entityParameter> - <name>ContainerName_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/keywordattributetypes/children/containername_param/valueProcess.js</valueProcess> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>WhitelistIds_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/keywordattributetypes/children/whitelistids_param/valueProcess.js</valueProcess> - </entityParameter> - </children> - </entityConsumer> - <entityField> - <name>DROPDOWNDEFINITION</name> - <title>Keyword</title> - <placeholderProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/placeholderProcess.js</placeholderProcess> - <dropDownProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/dropDownProcess.js</dropDownProcess> - <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/stateProcess.js</stateProcess> - <titleProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/titleProcess.js</titleProcess> - </entityField> - <entityParameter> - <name>AttrParentType_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityParameter> - <name>ObjectType_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityProvider> - <name>SpecificAttribute</name> - <lookupIdfield>UID</lookupIdfield> - <dependencies> - <entityDependency> - <name>ba3b4d47-7385-49df-bf61-54c99f5b2c81</name> - <entityName>AttributeRelation_entity</entityName> - <fieldName>SpecificAttribute</fieldName> - <isConsumer v="false" /> - </entityDependency> - </dependencies> - <children> - <entityParameter> - <name>ObjectType_param</name> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>FilteredAttributeIds_param</name> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>DisplaySimpleName_param</name> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>AttrParentId_param</name> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>AttrParentType_param</name> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>GetGroups_param</name> - <expose v="false" /> - </entityParameter> - </children> - </entityProvider> - <entityField> - <name>FULL_ATTRIBUTE_NAME</name> - <title>Title</title> - <state>READONLY</state> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/full_attribute_name/valueProcess.js</valueProcess> - </entityField> - <entityParameter> - <name>FilteredAttributeIds_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityActionGroup> - <name>AttributeActions</name> - <children> - <entityActionField> - <name>newChildAttribute</name> - <title>New attribute</title> - <onActionProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/onActionProcess.js</onActionProcess> - <isMenuAction v="true" /> - <isObjectAction v="false" /> - <isSelectionAction v="true" /> - <iconId>VAADIN:FILE_TREE_SMALL</iconId> - <tooltipProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/tooltipProcess.js</tooltipProcess> - </entityActionField> - </children> - </entityActionGroup> - <entityParameter> - <name>GetGroups_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityParameter> - <name>DisplaySimpleName_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityField> - <name>USAGELIST</name> - <title>Usage</title> - <state>READONLY</state> - </entityField> - <entityProvider> - <name>AttributeGroups</name> - <children> - <entityParameter> - <name>GetGroups_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributegroups/children/getgroups_param/valueProcess.js</valueProcess> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>AttrParentId_param</name> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>AttributeCount_param</name> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>ObjectType_param</name> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>AttributeTypes_param</name> - <expose v="false" /> - </entityParameter> - </children> - </entityProvider> - <entityConsumer> - <name>AttributeGroup</name> - <dependency> - <name>dependency</name> - <entityName>Attribute_entity</entityName> - <fieldName>AttributeGroups</fieldName> - </dependency> - <children> - <entityParameter> - <name>AttrParentId_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributegroup/children/attrparentid_param/valueProcess.js</valueProcess> - </entityParameter> - <entityParameter> - <name>AttrParentType_param</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributegroup/children/attrparenttype_param/valueProcess.js</valueProcess> - </entityParameter> - </children> - </entityConsumer> - <entityField> - <name>ICON</name> - <colorProcess>%aditoprj%/entity/Attribute_entity/entityfields/icon/colorProcess.js</colorProcess> - <contentType>IMAGE</contentType> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/icon/valueProcess.js</valueProcess> - </entityField> - <entityField> - <name>UID</name> - </entityField> - <entityField> - <name>SORTING</name> - <title>Sorting</title> - </entityField> - <entityParameter> - <name>AttributeCount_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityFieldGroup> - <name>attributeName</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributename/valueProcess.js</valueProcess> - <title>Name</title> - <fields> - <element>ATTRIBUTE_NAME</element> - </fields> - </entityFieldGroup> - <entityField> - <name>expanded</name> - <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/expanded/valueProcess.js</valueProcess> - </entityField> - <entityActionField> - <name>openAdminView</name> - <title>Open admin view</title> - <onActionProcess>%aditoprj%/entity/Attribute_entity/entityfields/openadminview/onActionProcess.js</onActionProcess> - <iconId>VAADIN:CURLY_BRACKETS</iconId> - <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/openadminview/stateProcess.js</stateProcess> - </entityActionField> - <entityField> - <name>DROPDOWNFILTER</name> - <title>Filter</title> - <contentType>FILTER_TREE</contentType> - </entityField> - <entityParameter> - <name>AttributeTypes_param</name> - <expose v="true" /> - </entityParameter> - </entityFields> - <recordContainers> - <jDitoRecordContainer> - <name>jdito</name> - <jDitoRecordAlias>Data_alias</jDitoRecordAlias> - <isFilterable v="true" /> - <isSortable v="true" /> - <contentProcess>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js</contentProcess> - <onInsert>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/onInsert.js</onInsert> - <onUpdate>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js</onUpdate> - <onDelete>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/onDelete.js</onDelete> - <recordFieldMappings> - <jDitoRecordFieldMapping> - <name>UID.value</name> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>ATTRIBUTE_PARENT_ID.value</name> - <isFilterable v="true" /> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>ATTRIBUTE_NAME.value</name> - <isFilterable v="true" /> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>ATTRIBUTE_ACTIVE.value</name> - <isFilterable v="true" /> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>DROPDOWNDEFINITION.value</name> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>DROPDOWNFILTER.value</name> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>SORTING.value</name> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>ATTRIBUTE_TYPE.value</name> - <isFilterable v="true" /> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>ATTRIBUTE_TYPE.displayValue</name> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>USAGELIST.value</name> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>ATTRIBUTE_PARENT_ID.displayValue</name> - </jDitoRecordFieldMapping> - <jDitoRecordFieldMapping> - <name>FULL_ATTRIBUTE_NAME.value</name> - </jDitoRecordFieldMapping> - </recordFieldMappings> - </jDitoRecordContainer> - </recordContainers> -</entity> +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> + <name>Attribute_entity</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <documentation>%aditoprj%/entity/Attribute_entity/documentation.adoc</documentation> + <title>Attribute</title> + <contentTitleProcess>%aditoprj%/entity/Attribute_entity/contentTitleProcess.js</contentTitleProcess> + <afterUiInit>%aditoprj%/entity/Attribute_entity/afterUiInit.js</afterUiInit> + <onValidation>%aditoprj%/entity/Attribute_entity/onValidation.js</onValidation> + <iconId>VAADIN:TAG</iconId> + <titlePlural>Attributes</titlePlural> + <recordContainer>jdito</recordContainer> + <entityFields> + <entityProvider> + <name>#PROVIDER</name> + </entityProvider> + <entityField> + <name>ATTRIBUTE_NAME</name> + <title>Title (original language)</title> + <mandatory v="true" /> + <state>EDITABLE</state> + </entityField> + <entityField> + <name>ATTRIBUTE_TYPE</name> + <title>Type</title> + <consumer>KeywordAttributeTypes</consumer> + <mandatory v="true" /> + <state>READONLY</state> + <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js</stateProcess> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/valueProcess.js</valueProcess> + <displayValueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/displayValueProcess.js</displayValueProcess> + <onValueChange>%aditoprj%/entity/Attribute_entity/entityfields/attribute_type/onValueChange.js</onValueChange> + </entityField> + <entityField> + <name>ATTRIBUTE_PARENT_ID</name> + <title>Superordinate Attribute</title> + <consumer>AttributeGroup</consumer> + <linkedContext>Attribute</linkedContext> + <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/stateProcess.js</stateProcess> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/valueProcess.js</valueProcess> + <displayValueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_parent_id/displayValueProcess.js</displayValueProcess> + <onValueChangeTypes> + <element>MASK</element> + <element>PROCESS</element> + <element>PROCESS_SETVALUE</element> + </onValueChangeTypes> + </entityField> + <entityConsumer> + <name>AttributeChildren</name> + <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributechildren/stateProcess.js</stateProcess> + <dependency> + <name>dependency</name> + <entityName>Attribute_entity</entityName> + <fieldName>AttributeParent</fieldName> + </dependency> + <children> + <entityParameter> + <name>AttrParentId_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributechildren/children/attrparentid_param/valueProcess.js</valueProcess> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>AttrParentType_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributechildren/children/attrparenttype_param/valueProcess.js</valueProcess> + <expose v="false" /> + </entityParameter> + </children> + </entityConsumer> + <entityProvider> + <name>AttributeParent</name> + <dependencies> + <entityDependency> + <name>18bd148d-bed3-429f-ba54-c5eac76c5083</name> + <entityName>Attribute_entity</entityName> + <fieldName>AttributeChildren</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>9fb3569c-7c75-48b1-9dc0-3f707940813a</name> + <entityName>Employee_entity</entityName> + <fieldName>Departments</fieldName> + <isConsumer v="false" /> + </entityDependency> + </dependencies> + <children> + <entityParameter> + <name>AttrParentType_param</name> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>AttrParentId_param</name> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>AttributeCount_param</name> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>ObjectType_param</name> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>GetGroups_param</name> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>AttributeTypes_param</name> + <expose v="false" /> + </entityParameter> + </children> + </entityProvider> + <entityParameter> + <name>AttrParentId_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityConsumer> + <name>AttributeUsages</name> + <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/stateProcess.js</stateProcess> + <dependency> + <name>dependency</name> + <entityName>AttributeUsage_entity</entityName> + <fieldName>SpecificAttribute</fieldName> + </dependency> + <children> + <entityParameter> + <name>AttributeId_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/children/attributeid_param/valueProcess.js</valueProcess> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>SingleSelection_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/children/singleselection_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>DisableMinCount_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeusages/children/disablemincount_param/valueProcess.js</valueProcess> + </entityParameter> + </children> + </entityConsumer> + <entityField> + <name>ATTRIBUTE_ACTIVE</name> + <title>Active</title> + <contentType>BOOLEAN</contentType> + <groupable v="true" /> + <dropDownProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_active/dropDownProcess.js</dropDownProcess> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attribute_active/valueProcess.js</valueProcess> + </entityField> + <entityConsumer> + <name>KeywordAttributeTypes</name> + <dependency> + <name>dependency</name> + <entityName>KeywordEntry_entity</entityName> + <fieldName>SpecificContainerKeywords</fieldName> + </dependency> + <children> + <entityParameter> + <name>ContainerName_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/keywordattributetypes/children/containername_param/valueProcess.js</valueProcess> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>WhitelistIds_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/keywordattributetypes/children/whitelistids_param/valueProcess.js</valueProcess> + </entityParameter> + </children> + </entityConsumer> + <entityField> + <name>DROPDOWNDEFINITION</name> + <title>Keyword</title> + <placeholderProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/placeholderProcess.js</placeholderProcess> + <dropDownProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/dropDownProcess.js</dropDownProcess> + <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/stateProcess.js</stateProcess> + <titleProcess>%aditoprj%/entity/Attribute_entity/entityfields/dropdowndefinition/titleProcess.js</titleProcess> + </entityField> + <entityParameter> + <name>AttrParentType_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityParameter> + <name>ObjectType_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityProvider> + <name>SpecificAttribute</name> + <lookupIdfield>UID</lookupIdfield> + <dependencies> + <entityDependency> + <name>ba3b4d47-7385-49df-bf61-54c99f5b2c81</name> + <entityName>AttributeRelation_entity</entityName> + <fieldName>SpecificAttribute</fieldName> + <isConsumer v="false" /> + </entityDependency> + </dependencies> + <children> + <entityParameter> + <name>ObjectType_param</name> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>FilteredAttributeIds_param</name> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>DisplaySimpleName_param</name> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>AttrParentId_param</name> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>AttrParentType_param</name> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>GetGroups_param</name> + <expose v="false" /> + </entityParameter> + </children> + </entityProvider> + <entityField> + <name>FULL_ATTRIBUTE_NAME</name> + <title>Title</title> + <state>READONLY</state> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/full_attribute_name/valueProcess.js</valueProcess> + </entityField> + <entityParameter> + <name>FilteredAttributeIds_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityActionGroup> + <name>AttributeActions</name> + <children> + <entityActionField> + <name>newChildAttribute</name> + <title>New attribute</title> + <onActionProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/onActionProcess.js</onActionProcess> + <isMenuAction v="true" /> + <isObjectAction v="false" /> + <isSelectionAction v="true" /> + <iconId>VAADIN:FILE_TREE_SMALL</iconId> + <tooltipProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributeactions/children/newchildattribute/tooltipProcess.js</tooltipProcess> + </entityActionField> + </children> + </entityActionGroup> + <entityParameter> + <name>GetGroups_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityParameter> + <name>DisplaySimpleName_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityField> + <name>USAGELIST</name> + <title>Usage</title> + <state>READONLY</state> + </entityField> + <entityProvider> + <name>AttributeGroups</name> + <children> + <entityParameter> + <name>GetGroups_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributegroups/children/getgroups_param/valueProcess.js</valueProcess> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>AttrParentId_param</name> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>AttributeCount_param</name> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>ObjectType_param</name> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>AttributeTypes_param</name> + <expose v="false" /> + </entityParameter> + </children> + </entityProvider> + <entityConsumer> + <name>AttributeGroup</name> + <dependency> + <name>dependency</name> + <entityName>Attribute_entity</entityName> + <fieldName>AttributeGroups</fieldName> + </dependency> + <children> + <entityParameter> + <name>AttrParentId_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributegroup/children/attrparentid_param/valueProcess.js</valueProcess> + </entityParameter> + <entityParameter> + <name>AttrParentType_param</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributegroup/children/attrparenttype_param/valueProcess.js</valueProcess> + </entityParameter> + </children> + </entityConsumer> + <entityField> + <name>ICON</name> + <colorProcess>%aditoprj%/entity/Attribute_entity/entityfields/icon/colorProcess.js</colorProcess> + <contentType>IMAGE</contentType> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/icon/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>UID</name> + </entityField> + <entityField> + <name>SORTING</name> + <title>Sorting</title> + </entityField> + <entityParameter> + <name>AttributeCount_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityFieldGroup> + <name>attributeName</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/attributename/valueProcess.js</valueProcess> + <title>Name</title> + <fields> + <element>ATTRIBUTE_NAME</element> + </fields> + </entityFieldGroup> + <entityField> + <name>expanded</name> + <valueProcess>%aditoprj%/entity/Attribute_entity/entityfields/expanded/valueProcess.js</valueProcess> + </entityField> + <entityActionField> + <name>openAdminView</name> + <title>Open admin view</title> + <onActionProcess>%aditoprj%/entity/Attribute_entity/entityfields/openadminview/onActionProcess.js</onActionProcess> + <iconId>VAADIN:CURLY_BRACKETS</iconId> + <stateProcess>%aditoprj%/entity/Attribute_entity/entityfields/openadminview/stateProcess.js</stateProcess> + </entityActionField> + <entityField> + <name>DROPDOWNFILTER</name> + <title>Filter</title> + <contentType>FILTER_TREE</contentType> + </entityField> + <entityParameter> + <name>AttributeTypes_param</name> + <expose v="true" /> + </entityParameter> + </entityFields> + <recordContainers> + <jDitoRecordContainer> + <name>jdito</name> + <jDitoRecordAlias>Data_alias</jDitoRecordAlias> + <isFilterable v="true" /> + <isSortable v="true" /> + <contentProcess>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js</contentProcess> + <onInsert>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/onInsert.js</onInsert> + <onUpdate>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js</onUpdate> + <onDelete>%aditoprj%/entity/Attribute_entity/recordcontainers/jdito/onDelete.js</onDelete> + <recordFieldMappings> + <jDitoRecordFieldMapping> + <name>UID.value</name> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>ATTRIBUTE_PARENT_ID.value</name> + <isFilterable v="true" /> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>ATTRIBUTE_NAME.value</name> + <isFilterable v="true" /> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>ATTRIBUTE_ACTIVE.value</name> + <isFilterable v="true" /> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>DROPDOWNDEFINITION.value</name> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>DROPDOWNFILTER.value</name> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>SORTING.value</name> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>ATTRIBUTE_TYPE.value</name> + <isFilterable v="true" /> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>ATTRIBUTE_TYPE.displayValue</name> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>USAGELIST.value</name> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>ATTRIBUTE_PARENT_ID.displayValue</name> + </jDitoRecordFieldMapping> + <jDitoRecordFieldMapping> + <name>FULL_ATTRIBUTE_NAME.value</name> + </jDitoRecordFieldMapping> + </recordFieldMappings> + </jDitoRecordContainer> + </recordContainers> +</entity> diff --git a/entity/Attribute_entity/entityfields/dropdowndefinition/dropDownProcess.js b/entity/Attribute_entity/entityfields/dropdowndefinition/dropDownProcess.js index 23c8a16fb6f..2ac4fdfe746 100644 --- a/entity/Attribute_entity/entityfields/dropdowndefinition/dropDownProcess.js +++ b/entity/Attribute_entity/entityfields/dropdowndefinition/dropDownProcess.js @@ -1,13 +1,13 @@ -import("system.translate"); -import("Context_lib"); -import("system.vars"); -import("system.result"); -import("Keyword_lib"); -import("Attribute_lib"); - -var res = []; -var type = vars.get("$field.ATTRIBUTE_TYPE").trim(); -var getDropDownFn = type && $AttributeTypes[type] && $AttributeTypes[type].getDropDownDefinitions; -if (getDropDownFn instanceof Function) - res = getDropDownFn.call(); -result.object(res); +import("system.translate"); +import("Context_lib"); +import("system.vars"); +import("system.result"); +import("Keyword_lib"); +import("Attribute_lib"); + +var res = []; +var type = vars.get("$field.ATTRIBUTE_TYPE").trim(); +var getDropDownFn = type && $AttributeTypes[type] && $AttributeTypes[type].getDropDownDefinitions; +if (getDropDownFn instanceof Function) + res = getDropDownFn.call(); +result.object(res); diff --git a/entity/Attribute_entity/entityfields/dropdowndefinition/placeholderProcess.js b/entity/Attribute_entity/entityfields/dropdowndefinition/placeholderProcess.js index f00cbd82e67..7ef97b2dfac 100644 --- a/entity/Attribute_entity/entityfields/dropdowndefinition/placeholderProcess.js +++ b/entity/Attribute_entity/entityfields/dropdowndefinition/placeholderProcess.js @@ -1,11 +1,11 @@ -import("system.translate"); -import("system.neon"); -import("system.vars"); -import("system.result"); -import("Attribute_lib"); - -var type = vars.get("$field.ATTRIBUTE_TYPE").trim(); -if (type == $AttributeTypes.KEYWORD) - result.string(translate.text("Keyword")); -else if (type == $AttributeTypes.OBJECTSELECTION) - result.string(translate.text("Module")); +import("system.translate"); +import("system.neon"); +import("system.vars"); +import("system.result"); +import("Attribute_lib"); + +var type = vars.get("$field.ATTRIBUTE_TYPE").trim(); +if (type == $AttributeTypes.KEYWORD) + result.string(translate.text("Keyword")); +else if (type == $AttributeTypes.OBJECTSELECTION) + result.string(translate.text("Module")); diff --git a/entity/Attribute_entity/entityfields/dropdowndefinition/titleProcess.js b/entity/Attribute_entity/entityfields/dropdowndefinition/titleProcess.js index f00cbd82e67..7ef97b2dfac 100644 --- a/entity/Attribute_entity/entityfields/dropdowndefinition/titleProcess.js +++ b/entity/Attribute_entity/entityfields/dropdowndefinition/titleProcess.js @@ -1,11 +1,11 @@ -import("system.translate"); -import("system.neon"); -import("system.vars"); -import("system.result"); -import("Attribute_lib"); - -var type = vars.get("$field.ATTRIBUTE_TYPE").trim(); -if (type == $AttributeTypes.KEYWORD) - result.string(translate.text("Keyword")); -else if (type == $AttributeTypes.OBJECTSELECTION) - result.string(translate.text("Module")); +import("system.translate"); +import("system.neon"); +import("system.vars"); +import("system.result"); +import("Attribute_lib"); + +var type = vars.get("$field.ATTRIBUTE_TYPE").trim(); +if (type == $AttributeTypes.KEYWORD) + result.string(translate.text("Keyword")); +else if (type == $AttributeTypes.OBJECTSELECTION) + result.string(translate.text("Module")); diff --git a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js index 4cd396cf519..e4fd9e63f9a 100644 --- a/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js +++ b/entity/Attribute_entity/recordcontainers/jdito/contentProcess.js @@ -1,209 +1,209 @@ -import("system.translate"); -import("Util_lib"); -import("JditoFilter_lib"); -import("KeywordRegistry_basic"); -import("Keyword_lib"); -import("system.db"); -import("system.vars"); -import("system.result"); -import("Sql_lib"); -import("Attribute_lib"); - -var getGroups = vars.exists("$param.GetGroups_param") && vars.get("$param.GetGroups_param"); -var objectType = vars.exists("$param.ObjectType_param") && vars.get("$param.ObjectType_param"); -var parentType = vars.exists("$param.AttrParentType_param") && vars.get("$param.AttrParentType_param"); -var fetchUsages = true; -var translateName = false; - -var sqlSelect = "select AB_ATTRIBUTEID, ATTRIBUTE_PARENT_ID, ATTRIBUTE_NAME, ATTRIBUTE_ACTIVE, DROPDOWNDEFINITION, DROPDOWNFILTER, SORTING, ATTRIBUTE_TYPE, " - + KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.attributeType(), "ATTRIBUTE_TYPE") //3 - + ", '', '', '' from AB_ATTRIBUTE"; - -var sqlOrder = " order by ATTRIBUTE_PARENT_ID asc, SORTING asc"; - -var condition = SqlCondition.begin(); - -if (vars.exists("$local.idvalues") && vars.get("$local.idvalues")) -{ - condition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", vars.get("$local.idvalues")); -} -else if (getGroups) //if getGroups == true, it is the lookup for selecting the superordinate attribute -{ - //this condition filters out the own id and the children to prevent loops - - var isGroupCondition = SqlCondition.begin(); - for (let type in $AttributeTypes) - if ($AttributeTypes[type].isGroup) - { - isGroupCondition.orPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes[type]); - } - - condition.andSqlCondition(SqlCondition.begin() - .andSqlCondition(isGroupCondition) - .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$param.AttrParentId_param", "# != ?") - .andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", AttributeUtil.getAllChildren(vars.getString("$param.AttrParentId_param")), null, true) - ); -} -else if (objectType) //if there's an objectType, it comes from the AttributeRelation entity (lookup for the attribute selection) -{ - var filteredAttributes = null; - - if (vars.exists("$param.AttributeTypes_param") && vars.getString("$param.AttributeTypes_param")) - condition.andIn("AB_ATTRIBUTE.ATTRIBUTE_TYPE", JSON.parse(vars.getString("$param.AttributeTypes_param"))); - - if (vars.exists("$param.FilteredAttributeIds_param") && vars.getString("$param.FilteredAttributeIds_param")) - filteredAttributes = JSON.parse(vars.getString("$param.FilteredAttributeIds_param")); - - var attributeCount; - if (vars.exists("$param.AttributeCount_param") && vars.get("$param.AttributeCount_param")) - attributeCount = JSON.parse(vars.getString("$param.AttributeCount_param")); - var ids = AttributeUtil.getPossibleAttributes(objectType, false, filteredAttributes, attributeCount); - - if (ids.length > 0) - condition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", ids); - else // do not return anything, if parameter is there but an empty array - condition.and("1=2"); - - fetchUsages = false; - translateName = true; -} -else if (parentType) //condition for all subordinate attributes of an attribute (for the tree of subordinate attributes in an attribute) -{ - if (AttributeTypeUtil.isGroupType(parentType)) - { - var parentId = vars.exists("$param.AttrParentId_param") && vars.get("$param.AttrParentId_param"); - if (parentId) - condition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", AttributeUtil.getAllChildren(vars.getString("$param.AttrParentId_param"))); - } - else - condition.and("1=2"); - - translateName = true; -} - -//when there are filters selected, add them to the conditon -if (vars.exists("$local.filter") && vars.get("$local.filter")) -{ - var filter = vars.get("$local.filter"); - if (filter.filter) - condition.andSqlCondition(JditoFilterUtils.getSqlCondition(filter.filter, "AB_ATTRIBUTE")); -} - -var usages; -if (fetchUsages) //this query is only necessary in Attribute, not in AttributeRelation -{ - var usagesSelect = "select AB_ATTRIBUTE_ID, OBJECT_TYPE from AB_ATTRIBUTEUSAGE \n\ - join AB_ATTRIBUTE on AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID"; - var usageTbl = db.table(condition.buildSql(usagesSelect, "1=1")); - usages = {}; - for (let i = 0, l = usageTbl.length; i < l; i++) - { - let attrId = usageTbl[i][0]; - if (attrId in usages) - usages[attrId].push(usageTbl[i][1]); - else - usages[attrId] = [usageTbl[i][1]]; - } -} - -var attributes = db.table(condition.buildSql(sqlSelect, "1=1", sqlOrder)); - -var allNames = db.table("select AB_ATTRIBUTEID, ATTRIBUTE_PARENT_ID, ATTRIBUTE_NAME from AB_ATTRIBUTE"); -var attrNameData = {}; -for (let i = 0, l = allNames.length; i < l; i++) -{ - attrNameData[allNames[i][0]] = [ - allNames[i][1], - translateName - ? translate.text(allNames[i][2]) - : allNames[i][2] - ]; -} -var nameCache = {}; - -result.object(_buildAttributeTable(attributes, usages)); - -//sorts the records in a way that a tree can be built and adds values -function _buildAttributeTable (pAttributes, pUsages) -{ - var rows = {}; - var allIds = {}; - - //fills the allIds object, the object is used for checking if a parent exists in the array - for (let i = 0, l = pAttributes.length; i < l; i++) - allIds[pAttributes[i][0]] = true; - - var arrayIndex = 0; - - do { - var oldIndex = arrayIndex; - pAttributes.forEach(function (row) - { - //item will be added if the id is not already in the object and - //the parent is already added (or the parent is not in the array) - if (!(row[0] in this) && (row[1] in this || !allIds[row[1]])) - this[row[0]] = { - data : row, - index : arrayIndex++ - }; - }, rows); - } while (oldIndex != arrayIndex); //stops the loop when no new items were added so that recursive relations between attributes don't cause an infinite loop - - var displaySimpleName = vars.exists("$param.DisplaySimpleName_param") && vars.get("$param.DisplaySimpleName_param"); - var sortedArray = new Array(Object.keys(rows).length); - for (let i in rows) - { - let rowData = rows[i].data; - if (pUsages && rowData[7].trim() != $AttributeTypes.COMBOVALUE && i in pUsages) - { - rowData[9] = pUsages[i].map(function (usage) - { - return translate.text(usage); - }).join(", "); - } - rowData[10] = _getFullName(rowData[1]); //parent full name - rowData[11] = _getFullName(rowData[0], displaySimpleName); - sortedArray[rows[i].index] = rowData; - } - - return sortedArray; - - - /** - * builds the full attribute name from the pre-loaded parent names and adds all parent names - * if required - */ - function _getFullName (pAttributeId, pSimpleName) - { - if (!pAttributeId) - return ""; - var attrId = pAttributeId; - var fullName = []; - - while (attrId) - { - let name = null; - if (attrId in nameCache) - { - name = nameCache[attrId]; - attrId = null; - } - else if (attrId in attrNameData) - { - name = attrNameData[attrId][1]; - attrId = attrNameData[attrId][0]; //next parent - } - else - attrId = null; - if (name) - fullName.unshift(name); - if (pSimpleName) - break; - } - - fullName = fullName.join(" / "); - nameCache[pAttributeId] = fullName; - - return fullName; - } -} +import("system.translate"); +import("Util_lib"); +import("JditoFilter_lib"); +import("KeywordRegistry_basic"); +import("Keyword_lib"); +import("system.db"); +import("system.vars"); +import("system.result"); +import("Sql_lib"); +import("Attribute_lib"); + +var getGroups = vars.exists("$param.GetGroups_param") && vars.get("$param.GetGroups_param"); +var objectType = vars.exists("$param.ObjectType_param") && vars.get("$param.ObjectType_param"); +var parentType = vars.exists("$param.AttrParentType_param") && vars.get("$param.AttrParentType_param"); +var fetchUsages = true; +var translateName = false; + +var sqlSelect = "select AB_ATTRIBUTEID, ATTRIBUTE_PARENT_ID, ATTRIBUTE_NAME, ATTRIBUTE_ACTIVE, DROPDOWNDEFINITION, DROPDOWNFILTER, SORTING, ATTRIBUTE_TYPE, " + + KeywordUtils.getResolvedTitleSqlPart($KeywordRegistry.attributeType(), "ATTRIBUTE_TYPE") //3 + + ", '', '', '' from AB_ATTRIBUTE"; + +var sqlOrder = " order by ATTRIBUTE_PARENT_ID asc, SORTING asc"; + +var condition = SqlCondition.begin(); + +if (vars.exists("$local.idvalues") && vars.get("$local.idvalues")) +{ + condition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", vars.get("$local.idvalues")); +} +else if (getGroups) //if getGroups == true, it is the lookup for selecting the superordinate attribute +{ + //this condition filters out the own id and the children to prevent loops + + var isGroupCondition = SqlCondition.begin(); + for (let type in $AttributeTypes) + if ($AttributeTypes[type].isGroup) + { + isGroupCondition.orPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes[type]); + } + + condition.andSqlCondition(SqlCondition.begin() + .andSqlCondition(isGroupCondition) + .andPrepareVars("AB_ATTRIBUTE.AB_ATTRIBUTEID", "$param.AttrParentId_param", "# != ?") + .andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", AttributeUtil.getAllChildren(vars.getString("$param.AttrParentId_param")), null, true) + ); +} +else if (objectType) //if there's an objectType, it comes from the AttributeRelation entity (lookup for the attribute selection) +{ + var filteredAttributes = null; + + if (vars.exists("$param.AttributeTypes_param") && vars.getString("$param.AttributeTypes_param")) + condition.andIn("AB_ATTRIBUTE.ATTRIBUTE_TYPE", JSON.parse(vars.getString("$param.AttributeTypes_param"))); + + if (vars.exists("$param.FilteredAttributeIds_param") && vars.getString("$param.FilteredAttributeIds_param")) + filteredAttributes = JSON.parse(vars.getString("$param.FilteredAttributeIds_param")); + + var attributeCount; + if (vars.exists("$param.AttributeCount_param") && vars.get("$param.AttributeCount_param")) + attributeCount = JSON.parse(vars.getString("$param.AttributeCount_param")); + var ids = AttributeUtil.getPossibleAttributes(objectType, false, filteredAttributes, attributeCount); + + if (ids.length > 0) + condition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", ids); + else // do not return anything, if parameter is there but an empty array + condition.and("1=2"); + + fetchUsages = false; + translateName = true; +} +else if (parentType) //condition for all subordinate attributes of an attribute (for the tree of subordinate attributes in an attribute) +{ + if (AttributeTypeUtil.isGroupType(parentType)) + { + var parentId = vars.exists("$param.AttrParentId_param") && vars.get("$param.AttrParentId_param"); + if (parentId) + condition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", AttributeUtil.getAllChildren(vars.getString("$param.AttrParentId_param"))); + } + else + condition.and("1=2"); + + translateName = true; +} + +//when there are filters selected, add them to the conditon +if (vars.exists("$local.filter") && vars.get("$local.filter")) +{ + var filter = vars.get("$local.filter"); + if (filter.filter) + condition.andSqlCondition(JditoFilterUtils.getSqlCondition(filter.filter, "AB_ATTRIBUTE")); +} + +var usages; +if (fetchUsages) //this query is only necessary in Attribute, not in AttributeRelation +{ + var usagesSelect = "select AB_ATTRIBUTE_ID, OBJECT_TYPE from AB_ATTRIBUTEUSAGE \n\ + join AB_ATTRIBUTE on AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID"; + var usageTbl = db.table(condition.buildSql(usagesSelect, "1=1")); + usages = {}; + for (let i = 0, l = usageTbl.length; i < l; i++) + { + let attrId = usageTbl[i][0]; + if (attrId in usages) + usages[attrId].push(usageTbl[i][1]); + else + usages[attrId] = [usageTbl[i][1]]; + } +} + +var attributes = db.table(condition.buildSql(sqlSelect, "1=1", sqlOrder)); + +var allNames = db.table("select AB_ATTRIBUTEID, ATTRIBUTE_PARENT_ID, ATTRIBUTE_NAME from AB_ATTRIBUTE"); +var attrNameData = {}; +for (let i = 0, l = allNames.length; i < l; i++) +{ + attrNameData[allNames[i][0]] = [ + allNames[i][1], + translateName + ? translate.text(allNames[i][2]) + : allNames[i][2] + ]; +} +var nameCache = {}; + +result.object(_buildAttributeTable(attributes, usages)); + +//sorts the records in a way that a tree can be built and adds values +function _buildAttributeTable (pAttributes, pUsages) +{ + var rows = {}; + var allIds = {}; + + //fills the allIds object, the object is used for checking if a parent exists in the array + for (let i = 0, l = pAttributes.length; i < l; i++) + allIds[pAttributes[i][0]] = true; + + var arrayIndex = 0; + + do { + var oldIndex = arrayIndex; + pAttributes.forEach(function (row) + { + //item will be added if the id is not already in the object and + //the parent is already added (or the parent is not in the array) + if (!(row[0] in this) && (row[1] in this || !allIds[row[1]])) + this[row[0]] = { + data : row, + index : arrayIndex++ + }; + }, rows); + } while (oldIndex != arrayIndex); //stops the loop when no new items were added so that recursive relations between attributes don't cause an infinite loop + + var displaySimpleName = vars.exists("$param.DisplaySimpleName_param") && vars.get("$param.DisplaySimpleName_param"); + var sortedArray = new Array(Object.keys(rows).length); + for (let i in rows) + { + let rowData = rows[i].data; + if (pUsages && rowData[7].trim() != $AttributeTypes.COMBOVALUE && i in pUsages) + { + rowData[9] = pUsages[i].map(function (usage) + { + return translate.text(usage); + }).join(", "); + } + rowData[10] = _getFullName(rowData[1]); //parent full name + rowData[11] = _getFullName(rowData[0], displaySimpleName); + sortedArray[rows[i].index] = rowData; + } + + return sortedArray; + + + /** + * builds the full attribute name from the pre-loaded parent names and adds all parent names + * if required + */ + function _getFullName (pAttributeId, pSimpleName) + { + if (!pAttributeId) + return ""; + var attrId = pAttributeId; + var fullName = []; + + while (attrId) + { + let name = null; + if (attrId in nameCache) + { + name = nameCache[attrId]; + attrId = null; + } + else if (attrId in attrNameData) + { + name = attrNameData[attrId][1]; + attrId = attrNameData[attrId][0]; //next parent + } + else + attrId = null; + if (name) + fullName.unshift(name); + if (pSimpleName) + break; + } + + fullName = fullName.join(" / "); + nameCache[pAttributeId] = fullName; + + return fullName; + } +} diff --git a/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js b/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js index 12ab6ce802c..cc709a73a61 100644 --- a/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js +++ b/entity/Attribute_entity/recordcontainers/jdito/onUpdate.js @@ -1,26 +1,27 @@ -import("Sql_lib"); -import("system.db"); -import("system.vars"); - -var rowdata = vars.get("$local.rowdata"); -var columns = [ - "ATTRIBUTE_ACTIVE", - "ATTRIBUTE_NAME", - "ATTRIBUTE_PARENT_ID", - "ATTRIBUTE_TYPE", - "DROPDOWNDEFINITION", - "DROPDOWNFILTER", - "SORTING" -]; -var values = [ - rowdata["ATTRIBUTE_ACTIVE.value"] || "", - rowdata["ATTRIBUTE_NAME.value"] || "", - rowdata["ATTRIBUTE_PARENT_ID.value"] || "", - rowdata["ATTRIBUTE_TYPE.value"] || "", - rowdata["DROPDOWNDEFINITION.value"] || "", - rowdata["DROPDOWNFILTER.value"] || "", - rowdata["SORTING.value"] || "" -]; - -db.updateData("AB_ATTRIBUTE", columns, null, values, +import("system.logging"); +import("Sql_lib"); +import("system.db"); +import("system.vars"); + +var rowdata = vars.get("$local.rowdata"); +var columns = [ + "ATTRIBUTE_ACTIVE", + "ATTRIBUTE_NAME", + "ATTRIBUTE_PARENT_ID", + "ATTRIBUTE_TYPE", + "DROPDOWNDEFINITION", + "DROPDOWNFILTER", + "SORTING" +]; +var values = [ + rowdata["ATTRIBUTE_ACTIVE.value"] || "", + rowdata["ATTRIBUTE_NAME.value"] || "", + rowdata["ATTRIBUTE_PARENT_ID.value"] || "", + rowdata["ATTRIBUTE_TYPE.value"] || "", + rowdata["DROPDOWNDEFINITION.value"] || "", + rowdata["DROPDOWNFILTER.value"] || "", + rowdata["SORTING.value"] || "" +]; +logging.log(JSON.stringify(values, null, "\t")) +db.updateData("AB_ATTRIBUTE", columns, null, values, SqlCondition.equals("AB_ATTRIBUTE.AB_ATTRIBUTEID", vars.get("$field.UID"), "1=2")); \ No newline at end of file diff --git a/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod b/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod index 4078a79be26..7874f23b68b 100644 --- a/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod +++ b/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod @@ -1,174 +1,169 @@ -<?xml version="1.0" encoding="UTF-8"?> -<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> - <name>KeywordAttributeRelation_entity</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/documentation.adoc</documentation> - <title>Keyword Attribute Values</title> - <titlePlural>Keyword Attribute Values</titlePlural> - <recordContainer>db</recordContainer> - <entityFields> - <entityProvider> - <name>#PROVIDER</name> - </entityProvider> - <entityField> - <name>AB_KEYWORD_ATTRIBUTERELATIONID</name> - <mandatory v="true" /> - <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attributerelationid/valueProcess.js</valueProcess> - </entityField> - <entityField> - <name>CHAR_VALUE</name> - <title>CHAR_VALUE</title> - </entityField> - <entityField> - <name>NUMBER_VALUE</name> - <contentType>NUMBER</contentType> - </entityField> - <entityField> - <name>BOOL_VALUE</name> - <contentType>BOOLEAN</contentType> - </entityField> - <entityField> - <name>AB_KEYWORD_ATTRIBUTE_ID</name> - <title>Keyword Attribute</title> - <consumer>KeywordAttributes</consumer> - <mandatory v="true" /> - <displayValueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/displayValueProcess.js</displayValueProcess> - <onValueChange>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/onValueChange.js</onValueChange> - <onValueChangeTypes> - <element>MASK</element> - <element>PROCESS_SETVALUE</element> - </onValueChangeTypes> - </entityField> - <entityField> - <name>AB_KEYWORD_ENTRY_ID</name> - <mandatory v="true" /> - <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_entry_id/valueProcess.js</valueProcess> - </entityField> - <entityProvider> - <name>AttributesForKeywordEntry</name> - <titlePlural></titlePlural> - <recordContainer>db</recordContainer> - <dependencies> - <entityDependency> - <name>490d12c0-6ace-42e5-89e1-d40b25322161</name> - <entityName>KeywordEntry_entity</entityName> - <fieldName>KeywordAttributeRelations</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>53b35858-7c81-429c-9e06-0362f567ad42</name> - <entityName>KeywordEntry_entity</entityName> - <fieldName>KeywordAttributeRelationsReadOnly</fieldName> - <isConsumer v="false" /> - </entityDependency> - </dependencies> - <children> - <entityParameter> - <name>KeywordEntryId_param</name> - <expose v="true" /> - <mandatory v="false" /> - </entityParameter> - </children> - </entityProvider> - <entityParameter> - <name>ContainerName_param</name> - <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/containername_param/valueProcess.js</valueProcess> - <mandatory v="false" /> - <description>PARAMETER</description> - </entityParameter> - <entityConsumer> - <name>KeywordAttributes</name> - <dependency> - <name>dependency</name> - <entityName>KeywordAttribute_entity</entityName> - <fieldName>SpecificContainerKeyword</fieldName> - </dependency> - <children> - <entityParameter> - <name>ContainerName_param</name> - <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/containername_param/valueProcess.js</valueProcess> - <expose v="false" /> - </entityParameter> - <entityParameter> - <name>FilterAlreadyUsedByEntryId_param</name> - <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/filteralreadyusedbyentryid_param/valueProcess.js</valueProcess> - <expose v="false" /> - </entityParameter> - </children> - </entityConsumer> - <entityParameter> - <name>KeywordEntryId_param</name> - <expose v="true" /> - <mandatory v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityField> - <name>valueProxy</name> - <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/documentation.adoc</documentation> - <title>Value</title> - <contentTypeProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/contentTypeProcess.js</contentTypeProcess> - <mandatory v="true" /> - <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/valueProcess.js</valueProcess> - <onValueChange>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/onValueChange.js</onValueChange> - </entityField> - <entityField> - <name>attributeType</name> - <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/attributetype/valueProcess.js</valueProcess> - </entityField> - <entityField> - <name>LONG_CHAR_VALUE</name> - </entityField> - </entityFields> - <recordContainers> - <dbRecordContainer> - <name>db</name> - <alias>Data_alias</alias> - <isPageable v="false" /> - <isRequireContainerFiltering v="false" /> - <conditionProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/recordcontainers/db/conditionProcess.js</conditionProcess> - <linkInformation> - <linkInformation> - <name>8e2938d2-e14b-403b-8ae5-875f70bc3f85</name> - <tableName>AB_KEYWORD_ATTRIBUTERELATION</tableName> - <primaryKey>AB_KEYWORD_ATTRIBUTERELATIONID</primaryKey> - <isUIDTable v="true" /> - <readonly v="false" /> - </linkInformation> - </linkInformation> - <recordFieldMappings> - <dbRecordFieldMapping> - <name>AB_KEYWORD_ATTRIBUTERELATIONID.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTERELATIONID</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>BOOL_VALUE.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTERELATION.BOOL_VALUE</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>CHAR_VALUE.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTERELATION.CHAR_VALUE</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>NUMBER_VALUE.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTERELATION.NUMBER_VALUE</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>AB_KEYWORD_ATTRIBUTE_ID.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>AB_KEYWORD_ENTRY_ID.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>AB_KEYWORD_ATTRIBUTE_ID.displayValue</name> - <expression>%aditoprj%/entity/KeywordAttributeRelation_entity/recordcontainers/db/recordfieldmappings/ab_keyword_attribute_id.displayvalue/expression.js</expression> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>LONG_CHAR_VALUE.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTERELATION.LONG_CHAR_VALUE</recordfield> - </dbRecordFieldMapping> - </recordFieldMappings> - </dbRecordContainer> - </recordContainers> -</entity> +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> + <name>KeywordAttributeRelation_entity</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/documentation.adoc</documentation> + <title>Keyword Attribute Values</title> + <titlePlural>Keyword Attribute Values</titlePlural> + <recordContainer>db</recordContainer> + <entityFields> + <entityProvider> + <name>#PROVIDER</name> + </entityProvider> + <entityField> + <name>AB_KEYWORD_ATTRIBUTERELATIONID</name> + <mandatory v="true" /> + <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attributerelationid/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>CHAR_VALUE</name> + <title>CHAR_VALUE</title> + </entityField> + <entityField> + <name>NUMBER_VALUE</name> + <contentType>NUMBER</contentType> + </entityField> + <entityField> + <name>BOOL_VALUE</name> + <contentType>BOOLEAN</contentType> + </entityField> + <entityField> + <name>AB_KEYWORD_ATTRIBUTE_ID</name> + <title>Keyword Attribute</title> + <consumer>KeywordAttributes</consumer> + <mandatory v="true" /> + <displayValueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/displayValueProcess.js</displayValueProcess> + <onValueChange>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_attribute_id/onValueChange.js</onValueChange> + <onValueChangeTypes> + <element>MASK</element> + <element>PROCESS_SETVALUE</element> + </onValueChangeTypes> + </entityField> + <entityField> + <name>AB_KEYWORD_ENTRY_ID</name> + <mandatory v="true" /> + <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/ab_keyword_entry_id/valueProcess.js</valueProcess> + </entityField> + <entityProvider> + <name>AttributesForKeywordEntry</name> + <titlePlural></titlePlural> + <recordContainer>db</recordContainer> + <dependencies> + <entityDependency> + <name>490d12c0-6ace-42e5-89e1-d40b25322161</name> + <entityName>KeywordEntry_entity</entityName> + <fieldName>KeywordAttributeRelations</fieldName> + <isConsumer v="false" /> + </entityDependency> + </dependencies> + <children> + <entityParameter> + <name>KeywordEntryId_param</name> + <expose v="true" /> + <mandatory v="false" /> + </entityParameter> + </children> + </entityProvider> + <entityParameter> + <name>ContainerName_param</name> + <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/containername_param/valueProcess.js</valueProcess> + <mandatory v="false" /> + <description>PARAMETER</description> + </entityParameter> + <entityConsumer> + <name>KeywordAttributes</name> + <dependency> + <name>dependency</name> + <entityName>KeywordAttribute_entity</entityName> + <fieldName>SpecificContainerKeyword</fieldName> + </dependency> + <children> + <entityParameter> + <name>ContainerName_param</name> + <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/containername_param/valueProcess.js</valueProcess> + <expose v="false" /> + </entityParameter> + <entityParameter> + <name>FilterAlreadyUsedByEntryId_param</name> + <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/filteralreadyusedbyentryid_param/valueProcess.js</valueProcess> + <expose v="false" /> + <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/filteralreadyusedbyentryid_param/documentation.adoc</documentation> + </entityParameter> + </children> + </entityConsumer> + <entityParameter> + <name>KeywordEntryId_param</name> + <expose v="true" /> + <mandatory v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityField> + <name>valueProxy</name> + <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/documentation.adoc</documentation> + <title>Value</title> + <contentTypeProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/contentTypeProcess.js</contentTypeProcess> + <mandatory v="true" /> + <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/valueProcess.js</valueProcess> + <onValueChange>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/valueproxy/onValueChange.js</onValueChange> + </entityField> + <entityField> + <name>attributeType</name> + <valueProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/entityfields/attributetype/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>LONG_CHAR_VALUE</name> + </entityField> + </entityFields> + <recordContainers> + <dbRecordContainer> + <name>db</name> + <alias>Data_alias</alias> + <isPageable v="false" /> + <isRequireContainerFiltering v="false" /> + <conditionProcess>%aditoprj%/entity/KeywordAttributeRelation_entity/recordcontainers/db/conditionProcess.js</conditionProcess> + <linkInformation> + <linkInformation> + <name>8e2938d2-e14b-403b-8ae5-875f70bc3f85</name> + <tableName>AB_KEYWORD_ATTRIBUTERELATION</tableName> + <primaryKey>AB_KEYWORD_ATTRIBUTERELATIONID</primaryKey> + <isUIDTable v="true" /> + <readonly v="false" /> + </linkInformation> + </linkInformation> + <recordFieldMappings> + <dbRecordFieldMapping> + <name>AB_KEYWORD_ATTRIBUTERELATIONID.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTERELATIONID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>BOOL_VALUE.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTERELATION.BOOL_VALUE</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>CHAR_VALUE.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTERELATION.CHAR_VALUE</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>NUMBER_VALUE.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTERELATION.NUMBER_VALUE</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>AB_KEYWORD_ATTRIBUTE_ID.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>AB_KEYWORD_ENTRY_ID.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>AB_KEYWORD_ATTRIBUTE_ID.displayValue</name> + <expression>%aditoprj%/entity/KeywordAttributeRelation_entity/recordcontainers/db/recordfieldmappings/ab_keyword_attribute_id.displayvalue/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>LONG_CHAR_VALUE.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTERELATION.LONG_CHAR_VALUE</recordfield> + </dbRecordFieldMapping> + </recordFieldMappings> + </dbRecordContainer> + </recordContainers> +</entity> diff --git a/entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/filteralreadyusedbyentryid_param/documentation.adoc b/entity/KeywordAttributeRelation_entity/entityfields/keywordattributes/children/filteralreadyusedbyentryid_param/documentation.adoc new file mode 100644 index 00000000000..e69de29bb2d diff --git a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod index 51527c153e0..6fee4eb699f 100644 --- a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod +++ b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod @@ -1,128 +1,128 @@ -<?xml version="1.0" encoding="UTF-8"?> -<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> - <name>KeywordAttribute_entity</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <documentation>%aditoprj%/entity/KeywordAttribute_entity/documentation.adoc</documentation> - <title>Keyword Attribute</title> - <contentTitleProcess>%aditoprj%/entity/KeywordAttribute_entity/contentTitleProcess.js</contentTitleProcess> - <iconId>VAADIN:KEY_O</iconId> - <iconIdProcess>%aditoprj%/entity/KeywordAttribute_entity/iconIdProcess.js</iconIdProcess> - <titlePlural>Keyword Attributes</titlePlural> - <recordContainer>db</recordContainer> - <entityFields> - <entityProvider> - <name>#PROVIDER</name> - </entityProvider> - <entityField> - <name>AB_KEYWORD_ATTRIBUTEID</name> - <valueProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/ab_keyword_attributeid/valueProcess.js</valueProcess> - </entityField> - <entityField> - <name>CONTAINER</name> - <title>Container</title> - <mandatory v="true" /> - <dropDownProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/container/dropDownProcess.js</dropDownProcess> - </entityField> - <entityField> - <name>NAME</name> - <title>Name</title> - <mandatory v="true" /> - <onValidation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/name/onValidation.js</onValidation> - </entityField> - <entityField> - <name>TYPE</name> - <title>Type</title> - <consumer>KeywordAttributeTypes</consumer> - <mandatory v="true" /> - <displayValueProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/type/displayValueProcess.js</displayValueProcess> - </entityField> - <entityProvider> - <name>SpecificContainerKeyword</name> - <documentation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/specificcontainerkeyword/documentation.adoc</documentation> - <dependencies> - <entityDependency> - <name>1d11c064-1cf2-4f08-b842-9fa941ad3157</name> - <entityName>KeywordAttributeRelation_entity</entityName> - <fieldName>KeywordAttributes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>684a3e60-00ad-4d46-8c98-6559e485a729</name> - <entityName>CommRestriction_Entity</entityName> - <fieldName>MediumKeywordAttribute</fieldName> - <isConsumer v="false" /> - </entityDependency> - </dependencies> - </entityProvider> - <entityParameter> - <name>ContainerName_param</name> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityParameter> - <name>FilterAlreadyUsedByEntryId_param</name> - <expose v="true" /> - <mandatory v="false" /> - <documentation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/filteralreadyusedbyentryid_param/documentation.adoc</documentation> - <description>PARAMETER</description> - </entityParameter> - <entityConsumer> - <name>KeywordAttributeTypes</name> - <dependency> - <name>dependency</name> - <entityName>KeywordEntry_entity</entityName> - <fieldName>SpecificContainerKeywords</fieldName> - </dependency> - <children> - <entityParameter> - <name>ContainerName_param</name> - <valueProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/keywordattributetypes/children/containername_param/valueProcess.js</valueProcess> - <expose v="false" /> - </entityParameter> - </children> - </entityConsumer> - </entityFields> - <recordContainers> - <dbRecordContainer> - <name>db</name> - <alias>Data_alias</alias> - <isPageable v="false" /> - <conditionProcess>%aditoprj%/entity/KeywordAttribute_entity/recordcontainers/db/conditionProcess.js</conditionProcess> - <onDBDelete>%aditoprj%/entity/KeywordAttribute_entity/recordcontainers/db/onDBDelete.js</onDBDelete> - <linkInformation> - <linkInformation> - <name>bd113d67-34ab-4708-b0e5-60a44332e6b8</name> - <tableName>AB_KEYWORD_ATTRIBUTE</tableName> - <primaryKey>AB_KEYWORD_ATTRIBUTEID</primaryKey> - <isUIDTable v="true" /> - <readonly v="false" /> - </linkInformation> - </linkInformation> - <recordFieldMappings> - <dbRecordFieldMapping> - <name>AB_KEYWORD_ATTRIBUTEID.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>CONTAINER.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTE.CONTAINER</recordfield> - <isFilterable v="true" /> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>NAME.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTE.NAME</recordfield> - <isFilterable v="true" /> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>TYPE.value</name> - <recordfield>AB_KEYWORD_ATTRIBUTE.KIND</recordfield> - <isFilterable v="true" /> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>TYPE.displayValue</name> - <expression>%aditoprj%/entity/KeywordAttribute_entity/recordcontainers/db/recordfieldmappings/type.displayvalue/expression.js</expression> - </dbRecordFieldMapping> - </recordFieldMappings> - </dbRecordContainer> - </recordContainers> -</entity> +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> + <name>KeywordAttribute_entity</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <documentation>%aditoprj%/entity/KeywordAttribute_entity/documentation.adoc</documentation> + <title>Keyword Attribute</title> + <contentTitleProcess>%aditoprj%/entity/KeywordAttribute_entity/contentTitleProcess.js</contentTitleProcess> + <iconId>VAADIN:KEY_O</iconId> + <iconIdProcess>%aditoprj%/entity/KeywordAttribute_entity/iconIdProcess.js</iconIdProcess> + <titlePlural>Keyword Attributes</titlePlural> + <recordContainer>db</recordContainer> + <entityFields> + <entityProvider> + <name>#PROVIDER</name> + </entityProvider> + <entityField> + <name>AB_KEYWORD_ATTRIBUTEID</name> + <valueProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/ab_keyword_attributeid/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>CONTAINER</name> + <title>Container</title> + <mandatory v="true" /> + <dropDownProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/container/dropDownProcess.js</dropDownProcess> + </entityField> + <entityField> + <name>NAME</name> + <title>Name</title> + <mandatory v="true" /> + <onValidation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/name/onValidation.js</onValidation> + </entityField> + <entityField> + <name>TYPE</name> + <title>Type</title> + <consumer>KeywordAttributeTypes</consumer> + <mandatory v="true" /> + <displayValueProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/type/displayValueProcess.js</displayValueProcess> + </entityField> + <entityProvider> + <name>SpecificContainerKeyword</name> + <documentation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/specificcontainerkeyword/documentation.adoc</documentation> + <dependencies> + <entityDependency> + <name>1d11c064-1cf2-4f08-b842-9fa941ad3157</name> + <entityName>KeywordAttributeRelation_entity</entityName> + <fieldName>KeywordAttributes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>684a3e60-00ad-4d46-8c98-6559e485a729</name> + <entityName>CommRestriction_Entity</entityName> + <fieldName>MediumKeywordAttribute</fieldName> + <isConsumer v="false" /> + </entityDependency> + </dependencies> + </entityProvider> + <entityParameter> + <name>ContainerName_param</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityParameter> + <name>FilterAlreadyUsedByEntryId_param</name> + <expose v="true" /> + <mandatory v="false" /> + <documentation>%aditoprj%/entity/KeywordAttribute_entity/entityfields/filteralreadyusedbyentryid_param/documentation.adoc</documentation> + <description>PARAMETER</description> + </entityParameter> + <entityConsumer> + <name>KeywordAttributeTypes</name> + <dependency> + <name>dependency</name> + <entityName>KeywordEntry_entity</entityName> + <fieldName>SpecificContainerKeywords</fieldName> + </dependency> + <children> + <entityParameter> + <name>ContainerName_param</name> + <valueProcess>%aditoprj%/entity/KeywordAttribute_entity/entityfields/keywordattributetypes/children/containername_param/valueProcess.js</valueProcess> + <expose v="false" /> + </entityParameter> + </children> + </entityConsumer> + </entityFields> + <recordContainers> + <dbRecordContainer> + <name>db</name> + <alias>Data_alias</alias> + <isPageable v="false" /> + <conditionProcess>%aditoprj%/entity/KeywordAttribute_entity/recordcontainers/db/conditionProcess.js</conditionProcess> + <onDBDelete>%aditoprj%/entity/KeywordAttribute_entity/recordcontainers/db/onDBDelete.js</onDBDelete> + <linkInformation> + <linkInformation> + <name>bd113d67-34ab-4708-b0e5-60a44332e6b8</name> + <tableName>AB_KEYWORD_ATTRIBUTE</tableName> + <primaryKey>AB_KEYWORD_ATTRIBUTEID</primaryKey> + <isUIDTable v="true" /> + <readonly v="false" /> + </linkInformation> + </linkInformation> + <recordFieldMappings> + <dbRecordFieldMapping> + <name>AB_KEYWORD_ATTRIBUTEID.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>CONTAINER.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTE.CONTAINER</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>NAME.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTE.NAME</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>TYPE.value</name> + <recordfield>AB_KEYWORD_ATTRIBUTE.KIND</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>TYPE.displayValue</name> + <expression>%aditoprj%/entity/KeywordAttribute_entity/recordcontainers/db/recordfieldmappings/type.displayvalue/expression.js</expression> + </dbRecordFieldMapping> + </recordFieldMappings> + </dbRecordContainer> + </recordContainers> +</entity> diff --git a/entity/KeywordAttribute_entity/recordcontainers/db/conditionProcess.js b/entity/KeywordAttribute_entity/recordcontainers/db/conditionProcess.js index 02735856728..5df041cf417 100644 --- a/entity/KeywordAttribute_entity/recordcontainers/db/conditionProcess.js +++ b/entity/KeywordAttribute_entity/recordcontainers/db/conditionProcess.js @@ -1,21 +1,21 @@ -import("system.vars"); -import("system.db"); -import("system.result"); -import("Sql_lib"); - -var cond = SqlCondition.begin().andPrepareVars("AB_KEYWORD_ATTRIBUTE.CONTAINER", "$param.ContainerName_param"); - -//filter for entries that are already used by entry_id -var entryIdForFilter = vars.get("$param.FilterAlreadyUsedByEntryId_param"); -if (entryIdForFilter) -{ - var exclusiveFilterCondition = SqlCondition.begin() - .andPrepare("AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID", entryIdForFilter) - .buildSql("AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID not in (\n\ - select AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID \n\ - from AB_KEYWORD_ATTRIBUTERELATION ", null, ")"); - cond.andAttachPrepared(exclusiveFilterCondition); -} - -var condStr = db.translateCondition(cond.build("1 = 1")); +import("system.vars"); +import("system.db"); +import("system.result"); +import("Sql_lib"); + +var cond = SqlCondition.begin().andPrepareVars("AB_KEYWORD_ATTRIBUTE.CONTAINER", "$param.ContainerName_param"); + +//filter for entries that are already used by entry_id +var entryIdForFilter = vars.get("$param.FilterAlreadyUsedByEntryId_param"); +if (entryIdForFilter) +{ + var exclusiveFilterCondition = SqlCondition.begin() + .andPrepare("AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID", entryIdForFilter) + .buildSql("AB_KEYWORD_ATTRIBUTE.AB_KEYWORD_ATTRIBUTEID not in (\n\ + select AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ATTRIBUTE_ID \n\ + from AB_KEYWORD_ATTRIBUTERELATION ", null, ")"); + cond.andAttachPrepared(exclusiveFilterCondition); +} + +var condStr = db.translateCondition(cond.build("1 = 1")); result.string(condStr); \ No newline at end of file diff --git a/entity/KeywordEntry_entity/KeywordEntry_entity.aod b/entity/KeywordEntry_entity/KeywordEntry_entity.aod index 3576059f493..cfd5ab30257 100644 --- a/entity/KeywordEntry_entity/KeywordEntry_entity.aod +++ b/entity/KeywordEntry_entity/KeywordEntry_entity.aod @@ -1,608 +1,593 @@ -<?xml version="1.0" encoding="UTF-8"?> -<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> - <name>KeywordEntry_entity</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <documentation>%aditoprj%/entity/KeywordEntry_entity/documentation.adoc</documentation> - <title>Keyword</title> - <siblings /> - <grantDelete v="false" /> - <grantDeleteProcess>%aditoprj%/entity/KeywordEntry_entity/grantDeleteProcess.js</grantDeleteProcess> - <contentTitleProcess>%aditoprj%/entity/KeywordEntry_entity/contentTitleProcess.js</contentTitleProcess> - <onValidation>%aditoprj%/entity/KeywordEntry_entity/onValidation.js</onValidation> - <iconId>VAADIN:KEY</iconId> - <iconIdProcess>%aditoprj%/entity/KeywordEntry_entity/iconIdProcess.js</iconIdProcess> - <titlePlural>Keywords</titlePlural> - <recordContainer>db</recordContainer> - <entityFields> - <entityProvider> - <name>#PROVIDER</name> - <lookupIdfield>KEYID</lookupIdfield> - <recordContainer>db</recordContainer> - <dependencies> - <entityDependency> - <name>ce10e4d3-7799-4473-a681-a3c6d9f93b02</name> - <entityName>Notification_entity</entityName> - <fieldName>StateKeywords</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>0015f4fa-9f54-4d99-8e23-92e36a614d7a</name> - <entityName>Notification_entity</entityName> - <fieldName>PrioKeywords</fieldName> - <isConsumer v="false" /> - </entityDependency> - </dependencies> - </entityProvider> - <entityField> - <name>CONTAINER</name> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/container/documentation.adoc</documentation> - <title>Container</title> - <groupable v="true" /> - <mandatory v="true" /> - <dropDownProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/container/dropDownProcess.js</dropDownProcess> - <textInputAllowed v="true" /> - <state>READONLY</state> - <stateProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/container/stateProcess.js</stateProcess> - </entityField> - <entityField> - <name>AB_KEYWORD_ENTRYID</name> - <title>AB_KEYWORD_ENTRYID (UID)</title> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/ab_keyword_entryid/valueProcess.js</valueProcess> - </entityField> - <entityField> - <name>KEYID</name> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/documentation.adoc</documentation> - <title>Key</title> - <mandatory v="true" /> - <state>READONLY</state> - <stateProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/stateProcess.js</stateProcess> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/valueProcess.js</valueProcess> - <onValidation>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/onValidation.js</onValidation> - </entityField> - <entityField> - <name>TITLE</name> - <title>Title (original language)</title> - <mandatory v="true" /> - </entityField> - <entityField> - <name>SORTING</name> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/sorting/documentation.adoc</documentation> - <title>Sorting</title> - <mandatory v="false" /> - <state>AUTO</state> - </entityField> - <entityField> - <name>ISACTIVE</name> - <title>Active</title> - <contentType>BOOLEAN</contentType> - <dropDownProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isactive/dropDownProcess.js</dropDownProcess> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isactive/valueProcess.js</valueProcess> - </entityField> - <entityField> - <name>ISESSENTIAL</name> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/isessential/documentation.adoc</documentation> - <title>Relational</title> - <contentType>BOOLEAN</contentType> - <dropDownProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isessential/dropDownProcess.js</dropDownProcess> - <state>READONLY</state> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isessential/valueProcess.js</valueProcess> - </entityField> - <entityParameter> - <name>ContainerName_param</name> - <expose v="true" /> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/containername_param/documentation.adoc</documentation> - </entityParameter> - <entityProvider> - <name>SpecificContainerKeywords</name> - <lookupIdfield>KEYID</lookupIdfield> - <recordContainer>db</recordContainer> - <dependencies> - <entityDependency> - <name>bb48a3ee-f340-4fd4-8c80-ef73b765ab58</name> - <entityName>Organisation_entity</entityName> - <fieldName>KeywordContactStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>4b1d1def-36d3-45e9-9ed5-eaef12d1ec82</name> - <entityName>Activity_entity</entityName> - <fieldName>KeywordDirections</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>42219987-4eff-4429-a22c-93e8a9c55c45</name> - <entityName>Contract_entity</entityName> - <fieldName>ContractPayments</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>2712e2b3-f17f-4a9c-9752-2383f62eb2b8</name> - <entityName>Contract_entity</entityName> - <fieldName>ContractStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>bd68f269-457c-487d-a1b2-e045d98f74b7</name> - <entityName>Contract_entity</entityName> - <fieldName>ContractTypes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>b88b5cc8-c29e-4110-b86e-d1d0050460e5</name> - <entityName>Offer_entity</entityName> - <fieldName>KeywordCurrencies</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>57c746ee-a8c0-484a-8c73-6301609b76b1</name> - <entityName>Order_entity</entityName> - <fieldName>KeywordCurrencies</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>bf014596-954b-4c7d-9304-8283c9bcc7ae</name> - <entityName>Productprice_entity</entityName> - <fieldName>KeywordCurrencies</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>f5dcbf08-3765-4a9d-8b42-cb1219c87f57</name> - <entityName>Offeritem_entity</entityName> - <fieldName>KeywordProductGroupcodes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>53bcaa07-94eb-4e81-9e9e-c5748156dad5</name> - <entityName>Orderitem_entity</entityName> - <fieldName>KeywordProductGroupcodes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>c404b010-1634-4160-adca-7edf1535ee26</name> - <entityName>Product_entity</entityName> - <fieldName>KeywordProductGroupcodes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>3575fdd7-3dd6-4318-b0d2-32d1df821076</name> - <entityName>Forecast_entity</entityName> - <fieldName>KeywordProductGroupcodes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>5a21cbe2-4eb0-4968-80fa-b98a64599230</name> - <entityName>Offer_entity</entityName> - <fieldName>KeywordOfferStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>8696e561-b263-4c7c-b753-c5da44b48055</name> - <entityName>Organisation_entity</entityName> - <fieldName>KeywordOrganisationTypes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>0d54d283-f158-4b91-8f6d-026954ed9c50</name> - <entityName>Person_entity</entityName> - <fieldName>KeywordGenders</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>8d28f08b-675d-4bcf-9318-a508d45ca69e</name> - <entityName>Task_entity</entityName> - <fieldName>KeywordStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>b069ef7d-07a0-460c-a8e7-cde5861c96c2</name> - <entityName>Productprice_entity</entityName> - <fieldName>KeywordPricelists</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>7f134ef1-cff5-4cf4-9d2a-e288c7904c28</name> - <entityName>Offeritem_entity</entityName> - <fieldName>KeywordQuantityUnits</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>c3c3b430-a14f-46b4-909a-9b53cef35413</name> - <entityName>Orderitem_entity</entityName> - <fieldName>KeywordQuantityUnits</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>a1983efd-92f9-4a6b-8805-d2977fcde0c8</name> - <entityName>Product_entity</entityName> - <fieldName>KeywordQuantityUnits</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>026021cd-cd64-400d-8bd5-f6d044af1ad8</name> - <entityName>Member_entity</entityName> - <fieldName>KeywordMemberRoles</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>356e23f9-eb05-4e18-b0b5-cbc7c8716dba</name> - <entityName>SalesprojectSource_entity</entityName> - <fieldName>KeywordSources</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>36a72192-902f-431b-8f43-0bef311678f7</name> - <entityName>Order_entity</entityName> - <fieldName>KeywordStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>e2041dea-8647-49e9-aacf-4481b75b76ff</name> - <entityName>Stock_entity</entityName> - <fieldName>KeywordWarehouses</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>403c40a4-f747-4e47-ad60-07334724d6fb</name> - <entityName>KeywordAttribute_entity</entityName> - <fieldName>KeywordAttributeTypes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>078bbd52-87fa-44cc-9902-04af935b5fbc</name> - <entityName>Attribute_entity</entityName> - <fieldName>KeywordAttributeTypes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>718fe5a2-c75f-49ed-b67e-fc4fbf63ff1d</name> - <entityName>Salesproject_entity</entityName> - <fieldName>KeywordProbabilties</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>a44375e9-917c-4db8-9aa8-de0625caf78f</name> - <entityName>Activity_entity</entityName> - <fieldName>KeywordCategories</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>f442a641-4dff-4860-bf4c-cfddc054e075</name> - <entityName>Offer_entity</entityName> - <fieldName>KeywordProbabilities</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>fa831dac-3287-422a-8f28-504fc525876a</name> - <entityName>Communication_entity</entityName> - <fieldName>KeywordMediums</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>04b28ce6-a144-4c19-ac2d-4cfbc3568700</name> - <entityName>Organisation_entity</entityName> - <fieldName>KeywordPricePolitics</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>f024df05-2faf-4447-9eed-ae31b329d542</name> - <entityName>Competition_entity</entityName> - <fieldName>KeywordPricePolitics</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>60840c28-9875-4e3e-8099-5ca208d58bbe</name> - <entityName>Organisation_entity</entityName> - <fieldName>KeywordWeaknesses</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>854148e2-2532-4562-b393-832819e8d462</name> - <entityName>Organisation_entity</entityName> - <fieldName>KeywordStrenghts</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>613d5861-0494-45f9-a839-a705347a68da</name> - <entityName>Competition_entity</entityName> - <fieldName>KeywordWeaknesses</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>119d79d0-9e04-4dd0-80bb-0bc32eaae775</name> - <entityName>Competition_entity</entityName> - <fieldName>KeywordStrenghts</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>6e2d164c-1ac7-4ed0-ad8f-7bfda1328493</name> - <entityName>Salesproject_entity</entityName> - <fieldName>KeywordStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>3ca6d3c7-83d2-4761-bab4-50d2baecdbd6</name> - <entityName>Competition_entity</entityName> - <fieldName>KeywordPhases</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>1053a90d-574a-4ca2-b41d-42b513db0fd2</name> - <entityName>Task_entity</entityName> - <fieldName>KeywordPriorities</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>bf9f7a07-dfb9-44d0-8f9b-d3814053683e</name> - <entityName>Competition_entity</entityName> - <fieldName>KeywordStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>ef8b9397-6292-42de-806e-5aaf3e3db5f3</name> - <entityName>Salesproject_entity</entityName> - <fieldName>KeywordWonLost</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>5d9e0e48-ece8-4b8e-ab72-beef77b5dcc3</name> - <entityName>Task_entity</entityName> - <fieldName>KeywordProgress</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>36aa04c1-5361-4e40-a036-0546db596973</name> - <entityName>Offer_entity</entityName> - <fieldName>KeywordDeliveryTerm</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>7e12cbd6-3a2c-4bd8-bc66-5001c282b690</name> - <entityName>Offer_entity</entityName> - <fieldName>KeywordPaymentTerm</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>77be3cca-8b50-4810-9549-3fd3e6fdf220</name> - <entityName>Person_entity</entityName> - <fieldName>KeywordContactStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>7945545b-f1e6-446d-84c3-ef68486652f4</name> - <entityName>Contact_entity</entityName> - <fieldName>KeywordContactStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>740a9696-d394-48ea-bcbf-a5484a093bde</name> - <entityName>SalesprojectMilestone_entity</entityName> - <fieldName>Keywords</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>b5c39776-509e-4758-8d05-a64eac4e7f38</name> - <entityName>CampaignStep_entity</entityName> - <fieldName>KeywordStates</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>13d739cb-2b97-44a0-bed0-b6868b0e579e</name> - <entityName>CampaignCost_entity</entityName> - <fieldName>KeywordCampaignManagementCostCategory</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>63bd7284-e9a0-4576-afe8-299d412e8def</name> - <entityName>ClassificationAdmin_entity</entityName> - <fieldName>KeywordClassificationTypes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>3a81e886-0d83-47f0-9ec7-c864ffc57cda</name> - <entityName>Classification_entity</entityName> - <fieldName>KeywordClassificationTypes</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>995646a8-ccec-4962-8c81-05a54903c433</name> - <entityName>CommRestriction_Entity</entityName> - <fieldName>CommRestrictionMedium</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>eb7c17de-3057-45c5-96c0-f863551cc049</name> - <entityName>BulkMailRecipient_entity</entityName> - <fieldName>StatusKeyword</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>3ab18dc8-b702-49d9-9cbc-4b8d8ffaea2e</name> - <entityName>DSGVO_entity</entityName> - <fieldName>KeywordDSGVOPurpose</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>86501073-4e62-42ef-ba15-e9f6a2eb3495</name> - <entityName>DSGVO_entity</entityName> - <fieldName>KeywordDSGVOStatuoritysource</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>ae2c4712-5513-4c0d-911a-532f50483c76</name> - <entityName>DSGVO_entity</entityName> - <fieldName>KeywordDSGVOType</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>44f84932-2a27-4e11-833b-def950c064d9</name> - <entityName>SupportTicket_entity</entityName> - <fieldName>KeywordTickettype</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>10ba6c44-779c-4ba8-9277-e9583af03ed5</name> - <entityName>SupportTicket_entity</entityName> - <fieldName>KeywordTaskState</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>e1b87370-aa15-4540-99c1-7bd63f0f3263</name> - <entityName>SupportTicket_entity</entityName> - <fieldName>KeywordTaskPriority</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>d8c587cc-47db-4e08-a6ac-92ec1d91acb5</name> - <entityName>BulkMail_entity</entityName> - <fieldName>StatusKeyword</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>41fd8fd4-7285-4493-9a56-cc0c44353057</name> - <entityName>DSGVOInfo_entity</entityName> - <fieldName>KeywordDeadline</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>1cbfe51f-43c3-4e99-895f-673097915249</name> - <entityName>DSGVOInfo_entity</entityName> - <fieldName>KeywordTransmission</fieldName> - <isConsumer v="false" /> - </entityDependency> - <entityDependency> - <name>718da6a7-229b-4075-a8ff-b0458c770e7b</name> - <entityName>DSGVOInfo_entity</entityName> - <fieldName>KeywordGuarantee</fieldName> - <isConsumer v="false" /> - </entityDependency> - </dependencies> - <children> - <entityParameter> - <name>OnlyActives_param</name> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/specificcontainerkeywords/children/onlyactives_param/valueProcess.js</valueProcess> - <expose v="true" /> - </entityParameter> - <entityParameter> - <name>ContainerName_param</name> - <expose v="true" /> - </entityParameter> - </children> - </entityProvider> - <entityField> - <name>TITLE_TRANSLATED</name> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/title_translated/valueProcess.js</valueProcess> - </entityField> - <entityParameter> - <name>OnlyActives_param</name> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/onlyactives_param/valueProcess.js</valueProcess> - <expose v="true" /> - <description>PARAMETER</description> - </entityParameter> - <entityConsumer> - <name>KeywordAttributeRelations</name> - <dependency> - <name>dependency</name> - <entityName>KeywordAttributeRelation_entity</entityName> - <fieldName>AttributesForKeywordEntry</fieldName> - </dependency> - <children> - <entityParameter> - <name>KeywordEntryId_param</name> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/keywordattributerelations/children/keywordentryid_param/valueProcess.js</valueProcess> - <expose v="true" /> - </entityParameter> - </children> - </entityConsumer> - <entityConsumer> - <name>KeywordAttributeRelationsReadOnly</name> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/documentation.adoc</documentation> - <state>READONLY</state> - <dependency> - <name>dependency</name> - <entityName>KeywordAttributeRelation_entity</entityName> - <fieldName>AttributesForKeywordEntry</fieldName> - </dependency> - <children> - <entityParameter> - <name>KeywordEntryId_param</name> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/children/keywordentryid_param/valueProcess.js</valueProcess> - </entityParameter> - </children> - </entityConsumer> - <entityParameter> - <name>ExcludedKeyIdsSubquery_param</name> - <expose v="true" /> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/excludedkeyidssubquery_param/documentation.adoc</documentation> - <description>PARAMETER</description> - </entityParameter> - <entityParameter> - <name>WhitelistIds_param</name> - <expose v="true" /> - <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/whitelistids_param/documentation.adoc</documentation> - </entityParameter> - <entityField> - <name>expanded</name> - <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/expanded/valueProcess.js</valueProcess> - </entityField> - <entityActionField> - <name>openAdminView</name> - <title>Open admin view</title> - <onActionProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/openadminview/onActionProcess.js</onActionProcess> - <iconId>VAADIN:CURLY_BRACKETS</iconId> - <stateProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/openadminview/stateProcess.js</stateProcess> - </entityActionField> - </entityFields> - <recordContainers> - <dbRecordContainer> - <name>db</name> - <alias>Data_alias</alias> - <isPageable v="false" /> - <conditionProcess>%aditoprj%/entity/KeywordEntry_entity/recordcontainers/db/conditionProcess.js</conditionProcess> - <orderClauseProcess>%aditoprj%/entity/KeywordEntry_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess> - <onDBDelete>%aditoprj%/entity/KeywordEntry_entity/recordcontainers/db/onDBDelete.js</onDBDelete> - <linkInformation> - <linkInformation> - <name>52acbfe0-57f4-4614-83af-9882e168f431</name> - <tableName>AB_KEYWORD_ENTRY</tableName> - <primaryKey>AB_KEYWORD_ENTRYID</primaryKey> - <isUIDTable v="true" /> - <readonly v="false" /> - </linkInformation> - </linkInformation> - <recordFieldMappings> - <dbRecordFieldMapping> - <name>TITLE.value</name> - <recordfield>AB_KEYWORD_ENTRY.TITLE</recordfield> - <isFilterable v="true" /> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>SORTING.value</name> - <recordfield>AB_KEYWORD_ENTRY.SORTING</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>ISESSENTIAL.value</name> - <recordfield>AB_KEYWORD_ENTRY.ISESSENTIAL</recordfield> - <isFilterable v="true" /> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>ISACTIVE.value</name> - <recordfield>AB_KEYWORD_ENTRY.ISACTIVE</recordfield> - <isFilterable v="true" /> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>AB_KEYWORD_ENTRYID.value</name> - <recordfield>AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>KEYID.value</name> - <recordfield>AB_KEYWORD_ENTRY.KEYID</recordfield> - </dbRecordFieldMapping> - <dbRecordFieldMapping> - <name>CONTAINER.value</name> - <recordfield>AB_KEYWORD_ENTRY.CONTAINER</recordfield> - <isFilterable v="true" /> - </dbRecordFieldMapping> - </recordFieldMappings> - </dbRecordContainer> - </recordContainers> -</entity> +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.11" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.11"> + <name>KeywordEntry_entity</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <documentation>%aditoprj%/entity/KeywordEntry_entity/documentation.adoc</documentation> + <title>Keyword</title> + <siblings /> + <grantDelete v="false" /> + <grantDeleteProcess>%aditoprj%/entity/KeywordEntry_entity/grantDeleteProcess.js</grantDeleteProcess> + <contentTitleProcess>%aditoprj%/entity/KeywordEntry_entity/contentTitleProcess.js</contentTitleProcess> + <onValidation>%aditoprj%/entity/KeywordEntry_entity/onValidation.js</onValidation> + <iconId>VAADIN:KEY</iconId> + <iconIdProcess>%aditoprj%/entity/KeywordEntry_entity/iconIdProcess.js</iconIdProcess> + <titlePlural>Keywords</titlePlural> + <recordContainer>db</recordContainer> + <entityFields> + <entityProvider> + <name>#PROVIDER</name> + <lookupIdfield>KEYID</lookupIdfield> + <recordContainer>db</recordContainer> + <dependencies> + <entityDependency> + <name>ce10e4d3-7799-4473-a681-a3c6d9f93b02</name> + <entityName>Notification_entity</entityName> + <fieldName>StateKeywords</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>0015f4fa-9f54-4d99-8e23-92e36a614d7a</name> + <entityName>Notification_entity</entityName> + <fieldName>PrioKeywords</fieldName> + <isConsumer v="false" /> + </entityDependency> + </dependencies> + </entityProvider> + <entityField> + <name>CONTAINER</name> + <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/container/documentation.adoc</documentation> + <title>Container</title> + <groupable v="true" /> + <mandatory v="true" /> + <dropDownProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/container/dropDownProcess.js</dropDownProcess> + <textInputAllowed v="true" /> + <state>READONLY</state> + <stateProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/container/stateProcess.js</stateProcess> + </entityField> + <entityField> + <name>AB_KEYWORD_ENTRYID</name> + <title>AB_KEYWORD_ENTRYID (UID)</title> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/ab_keyword_entryid/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>KEYID</name> + <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/documentation.adoc</documentation> + <title>Key</title> + <mandatory v="true" /> + <state>READONLY</state> + <stateProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/stateProcess.js</stateProcess> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/valueProcess.js</valueProcess> + <onValidation>%aditoprj%/entity/KeywordEntry_entity/entityfields/keyid/onValidation.js</onValidation> + </entityField> + <entityField> + <name>TITLE</name> + <title>Title (original language)</title> + <mandatory v="true" /> + </entityField> + <entityField> + <name>SORTING</name> + <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/sorting/documentation.adoc</documentation> + <title>Sorting</title> + <mandatory v="false" /> + <state>AUTO</state> + </entityField> + <entityField> + <name>ISACTIVE</name> + <title>Active</title> + <contentType>BOOLEAN</contentType> + <dropDownProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isactive/dropDownProcess.js</dropDownProcess> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isactive/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>ISESSENTIAL</name> + <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/isessential/documentation.adoc</documentation> + <title>Relational</title> + <contentType>BOOLEAN</contentType> + <dropDownProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isessential/dropDownProcess.js</dropDownProcess> + <state>READONLY</state> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/isessential/valueProcess.js</valueProcess> + </entityField> + <entityParameter> + <name>ContainerName_param</name> + <expose v="true" /> + <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/containername_param/documentation.adoc</documentation> + </entityParameter> + <entityProvider> + <name>SpecificContainerKeywords</name> + <lookupIdfield>KEYID</lookupIdfield> + <recordContainer>db</recordContainer> + <dependencies> + <entityDependency> + <name>bb48a3ee-f340-4fd4-8c80-ef73b765ab58</name> + <entityName>Organisation_entity</entityName> + <fieldName>KeywordContactStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>4b1d1def-36d3-45e9-9ed5-eaef12d1ec82</name> + <entityName>Activity_entity</entityName> + <fieldName>KeywordDirections</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>42219987-4eff-4429-a22c-93e8a9c55c45</name> + <entityName>Contract_entity</entityName> + <fieldName>ContractPayments</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>2712e2b3-f17f-4a9c-9752-2383f62eb2b8</name> + <entityName>Contract_entity</entityName> + <fieldName>ContractStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>bd68f269-457c-487d-a1b2-e045d98f74b7</name> + <entityName>Contract_entity</entityName> + <fieldName>ContractTypes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>b88b5cc8-c29e-4110-b86e-d1d0050460e5</name> + <entityName>Offer_entity</entityName> + <fieldName>KeywordCurrencies</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>57c746ee-a8c0-484a-8c73-6301609b76b1</name> + <entityName>Order_entity</entityName> + <fieldName>KeywordCurrencies</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>bf014596-954b-4c7d-9304-8283c9bcc7ae</name> + <entityName>Productprice_entity</entityName> + <fieldName>KeywordCurrencies</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>f5dcbf08-3765-4a9d-8b42-cb1219c87f57</name> + <entityName>Offeritem_entity</entityName> + <fieldName>KeywordProductGroupcodes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>53bcaa07-94eb-4e81-9e9e-c5748156dad5</name> + <entityName>Orderitem_entity</entityName> + <fieldName>KeywordProductGroupcodes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>c404b010-1634-4160-adca-7edf1535ee26</name> + <entityName>Product_entity</entityName> + <fieldName>KeywordProductGroupcodes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>3575fdd7-3dd6-4318-b0d2-32d1df821076</name> + <entityName>Forecast_entity</entityName> + <fieldName>KeywordProductGroupcodes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>5a21cbe2-4eb0-4968-80fa-b98a64599230</name> + <entityName>Offer_entity</entityName> + <fieldName>KeywordOfferStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>8696e561-b263-4c7c-b753-c5da44b48055</name> + <entityName>Organisation_entity</entityName> + <fieldName>KeywordOrganisationTypes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>0d54d283-f158-4b91-8f6d-026954ed9c50</name> + <entityName>Person_entity</entityName> + <fieldName>KeywordGenders</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>8d28f08b-675d-4bcf-9318-a508d45ca69e</name> + <entityName>Task_entity</entityName> + <fieldName>KeywordStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>b069ef7d-07a0-460c-a8e7-cde5861c96c2</name> + <entityName>Productprice_entity</entityName> + <fieldName>KeywordPricelists</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>7f134ef1-cff5-4cf4-9d2a-e288c7904c28</name> + <entityName>Offeritem_entity</entityName> + <fieldName>KeywordQuantityUnits</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>c3c3b430-a14f-46b4-909a-9b53cef35413</name> + <entityName>Orderitem_entity</entityName> + <fieldName>KeywordQuantityUnits</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>a1983efd-92f9-4a6b-8805-d2977fcde0c8</name> + <entityName>Product_entity</entityName> + <fieldName>KeywordQuantityUnits</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>026021cd-cd64-400d-8bd5-f6d044af1ad8</name> + <entityName>Member_entity</entityName> + <fieldName>KeywordMemberRoles</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>356e23f9-eb05-4e18-b0b5-cbc7c8716dba</name> + <entityName>SalesprojectSource_entity</entityName> + <fieldName>KeywordSources</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>36a72192-902f-431b-8f43-0bef311678f7</name> + <entityName>Order_entity</entityName> + <fieldName>KeywordStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>e2041dea-8647-49e9-aacf-4481b75b76ff</name> + <entityName>Stock_entity</entityName> + <fieldName>KeywordWarehouses</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>403c40a4-f747-4e47-ad60-07334724d6fb</name> + <entityName>KeywordAttribute_entity</entityName> + <fieldName>KeywordAttributeTypes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>078bbd52-87fa-44cc-9902-04af935b5fbc</name> + <entityName>Attribute_entity</entityName> + <fieldName>KeywordAttributeTypes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>718fe5a2-c75f-49ed-b67e-fc4fbf63ff1d</name> + <entityName>Salesproject_entity</entityName> + <fieldName>KeywordProbabilties</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>a44375e9-917c-4db8-9aa8-de0625caf78f</name> + <entityName>Activity_entity</entityName> + <fieldName>KeywordCategories</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>f442a641-4dff-4860-bf4c-cfddc054e075</name> + <entityName>Offer_entity</entityName> + <fieldName>KeywordProbabilities</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>fa831dac-3287-422a-8f28-504fc525876a</name> + <entityName>Communication_entity</entityName> + <fieldName>KeywordMediums</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>04b28ce6-a144-4c19-ac2d-4cfbc3568700</name> + <entityName>Organisation_entity</entityName> + <fieldName>KeywordPricePolitics</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>f024df05-2faf-4447-9eed-ae31b329d542</name> + <entityName>Competition_entity</entityName> + <fieldName>KeywordPricePolitics</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>60840c28-9875-4e3e-8099-5ca208d58bbe</name> + <entityName>Organisation_entity</entityName> + <fieldName>KeywordWeaknesses</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>854148e2-2532-4562-b393-832819e8d462</name> + <entityName>Organisation_entity</entityName> + <fieldName>KeywordStrenghts</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>613d5861-0494-45f9-a839-a705347a68da</name> + <entityName>Competition_entity</entityName> + <fieldName>KeywordWeaknesses</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>119d79d0-9e04-4dd0-80bb-0bc32eaae775</name> + <entityName>Competition_entity</entityName> + <fieldName>KeywordStrenghts</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>6e2d164c-1ac7-4ed0-ad8f-7bfda1328493</name> + <entityName>Salesproject_entity</entityName> + <fieldName>KeywordStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>3ca6d3c7-83d2-4761-bab4-50d2baecdbd6</name> + <entityName>Competition_entity</entityName> + <fieldName>KeywordPhases</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>1053a90d-574a-4ca2-b41d-42b513db0fd2</name> + <entityName>Task_entity</entityName> + <fieldName>KeywordPriorities</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>bf9f7a07-dfb9-44d0-8f9b-d3814053683e</name> + <entityName>Competition_entity</entityName> + <fieldName>KeywordStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>ef8b9397-6292-42de-806e-5aaf3e3db5f3</name> + <entityName>Salesproject_entity</entityName> + <fieldName>KeywordWonLost</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>5d9e0e48-ece8-4b8e-ab72-beef77b5dcc3</name> + <entityName>Task_entity</entityName> + <fieldName>KeywordProgress</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>36aa04c1-5361-4e40-a036-0546db596973</name> + <entityName>Offer_entity</entityName> + <fieldName>KeywordDeliveryTerm</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>7e12cbd6-3a2c-4bd8-bc66-5001c282b690</name> + <entityName>Offer_entity</entityName> + <fieldName>KeywordPaymentTerm</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>77be3cca-8b50-4810-9549-3fd3e6fdf220</name> + <entityName>Person_entity</entityName> + <fieldName>KeywordContactStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>7945545b-f1e6-446d-84c3-ef68486652f4</name> + <entityName>Contact_entity</entityName> + <fieldName>KeywordContactStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>740a9696-d394-48ea-bcbf-a5484a093bde</name> + <entityName>SalesprojectMilestone_entity</entityName> + <fieldName>Keywords</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>b5c39776-509e-4758-8d05-a64eac4e7f38</name> + <entityName>CampaignStep_entity</entityName> + <fieldName>KeywordStates</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>13d739cb-2b97-44a0-bed0-b6868b0e579e</name> + <entityName>CampaignCost_entity</entityName> + <fieldName>KeywordCampaignManagementCostCategory</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>63bd7284-e9a0-4576-afe8-299d412e8def</name> + <entityName>ClassificationAdmin_entity</entityName> + <fieldName>KeywordClassificationTypes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>3a81e886-0d83-47f0-9ec7-c864ffc57cda</name> + <entityName>Classification_entity</entityName> + <fieldName>KeywordClassificationTypes</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>995646a8-ccec-4962-8c81-05a54903c433</name> + <entityName>CommRestriction_Entity</entityName> + <fieldName>CommRestrictionMedium</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>eb7c17de-3057-45c5-96c0-f863551cc049</name> + <entityName>BulkMailRecipient_entity</entityName> + <fieldName>StatusKeyword</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>3ab18dc8-b702-49d9-9cbc-4b8d8ffaea2e</name> + <entityName>DSGVO_entity</entityName> + <fieldName>KeywordDSGVOPurpose</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>86501073-4e62-42ef-ba15-e9f6a2eb3495</name> + <entityName>DSGVO_entity</entityName> + <fieldName>KeywordDSGVOStatuoritysource</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>ae2c4712-5513-4c0d-911a-532f50483c76</name> + <entityName>DSGVO_entity</entityName> + <fieldName>KeywordDSGVOType</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>44f84932-2a27-4e11-833b-def950c064d9</name> + <entityName>SupportTicket_entity</entityName> + <fieldName>KeywordTickettype</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>10ba6c44-779c-4ba8-9277-e9583af03ed5</name> + <entityName>SupportTicket_entity</entityName> + <fieldName>KeywordTaskState</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>e1b87370-aa15-4540-99c1-7bd63f0f3263</name> + <entityName>SupportTicket_entity</entityName> + <fieldName>KeywordTaskPriority</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>d8c587cc-47db-4e08-a6ac-92ec1d91acb5</name> + <entityName>BulkMail_entity</entityName> + <fieldName>StatusKeyword</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>41fd8fd4-7285-4493-9a56-cc0c44353057</name> + <entityName>DSGVOInfo_entity</entityName> + <fieldName>KeywordDeadline</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>1cbfe51f-43c3-4e99-895f-673097915249</name> + <entityName>DSGVOInfo_entity</entityName> + <fieldName>KeywordTransmission</fieldName> + <isConsumer v="false" /> + </entityDependency> + <entityDependency> + <name>718da6a7-229b-4075-a8ff-b0458c770e7b</name> + <entityName>DSGVOInfo_entity</entityName> + <fieldName>KeywordGuarantee</fieldName> + <isConsumer v="false" /> + </entityDependency> + </dependencies> + <children> + <entityParameter> + <name>OnlyActives_param</name> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/specificcontainerkeywords/children/onlyactives_param/valueProcess.js</valueProcess> + <expose v="true" /> + </entityParameter> + <entityParameter> + <name>ContainerName_param</name> + <expose v="true" /> + </entityParameter> + </children> + </entityProvider> + <entityField> + <name>TITLE_TRANSLATED</name> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/title_translated/valueProcess.js</valueProcess> + </entityField> + <entityParameter> + <name>OnlyActives_param</name> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/onlyactives_param/valueProcess.js</valueProcess> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityConsumer> + <name>KeywordAttributeRelations</name> + <onValidation>%aditoprj%/entity/KeywordEntry_entity/entityfields/keywordattributerelations/onValidation.js</onValidation> + <dependency> + <name>dependency</name> + <entityName>KeywordAttributeRelation_entity</entityName> + <fieldName>AttributesForKeywordEntry</fieldName> + </dependency> + <children> + <entityParameter> + <name>KeywordEntryId_param</name> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/keywordattributerelations/children/keywordentryid_param/valueProcess.js</valueProcess> + <expose v="true" /> + </entityParameter> + </children> + </entityConsumer> + <entityParameter> + <name>ExcludedKeyIdsSubquery_param</name> + <expose v="true" /> + <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/excludedkeyidssubquery_param/documentation.adoc</documentation> + <description>PARAMETER</description> + </entityParameter> + <entityParameter> + <name>WhitelistIds_param</name> + <expose v="true" /> + <documentation>%aditoprj%/entity/KeywordEntry_entity/entityfields/whitelistids_param/documentation.adoc</documentation> + </entityParameter> + <entityField> + <name>expanded</name> + <valueProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/expanded/valueProcess.js</valueProcess> + </entityField> + <entityActionField> + <name>openAdminView</name> + <title>Open admin view</title> + <onActionProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/openadminview/onActionProcess.js</onActionProcess> + <iconId>VAADIN:CURLY_BRACKETS</iconId> + <stateProcess>%aditoprj%/entity/KeywordEntry_entity/entityfields/openadminview/stateProcess.js</stateProcess> + </entityActionField> + </entityFields> + <recordContainers> + <dbRecordContainer> + <name>db</name> + <alias>Data_alias</alias> + <isPageable v="false" /> + <conditionProcess>%aditoprj%/entity/KeywordEntry_entity/recordcontainers/db/conditionProcess.js</conditionProcess> + <orderClauseProcess>%aditoprj%/entity/KeywordEntry_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess> + <onDBDelete>%aditoprj%/entity/KeywordEntry_entity/recordcontainers/db/onDBDelete.js</onDBDelete> + <linkInformation> + <linkInformation> + <name>52acbfe0-57f4-4614-83af-9882e168f431</name> + <tableName>AB_KEYWORD_ENTRY</tableName> + <primaryKey>AB_KEYWORD_ENTRYID</primaryKey> + <isUIDTable v="true" /> + <readonly v="false" /> + </linkInformation> + </linkInformation> + <recordFieldMappings> + <dbRecordFieldMapping> + <name>TITLE.value</name> + <recordfield>AB_KEYWORD_ENTRY.TITLE</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>SORTING.value</name> + <recordfield>AB_KEYWORD_ENTRY.SORTING</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>ISESSENTIAL.value</name> + <recordfield>AB_KEYWORD_ENTRY.ISESSENTIAL</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>ISACTIVE.value</name> + <recordfield>AB_KEYWORD_ENTRY.ISACTIVE</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>AB_KEYWORD_ENTRYID.value</name> + <recordfield>AB_KEYWORD_ENTRY.AB_KEYWORD_ENTRYID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>KEYID.value</name> + <recordfield>AB_KEYWORD_ENTRY.KEYID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>CONTAINER.value</name> + <recordfield>AB_KEYWORD_ENTRY.CONTAINER</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + </recordFieldMappings> + </dbRecordContainer> + </recordContainers> +</entity> diff --git a/entity/KeywordEntry_entity/entityfields/keywordattributerelations/onValidation.js b/entity/KeywordEntry_entity/entityfields/keywordattributerelations/onValidation.js new file mode 100644 index 00000000000..e2a0b150abd --- /dev/null +++ b/entity/KeywordEntry_entity/entityfields/keywordattributerelations/onValidation.js @@ -0,0 +1,82 @@ +import("system.translate"); +import("system.result"); +import("system.vars"); +import("Sql_lib"); +import("system.db"); + +if (!_areUnique()) + result.string(translate.text("Attributes must be unique!")); + +function _areUnique () +{ + var insertedRows = vars.get("$field.KeywordAttributeRelations.insertedRows"); + var changedRows = vars.get("$field.KeywordAttributeRelations.changedRows"); + var deletedRows = vars.get("$field.KeywordAttributeRelations.deletedRows"); + + var storedRows = db.table(SqlCondition.begin() + .andPrepare("AB_KEYWORD_ATTRIBUTERELATION.AB_KEYWORD_ENTRY_ID", vars.get("$field.AB_KEYWORD_ENTRYID")) + .buildSql("select AB_KEYWORD_ATTRIBUTERELATIONID, AB_KEYWORD_ATTRIBUTE_ID from AB_KEYWORD_ATTRIBUTERELATION")); + + var attributeChanges = {}; + + if (deletedRows) + deletedRows.forEach(function (row) + { + this[row.AB_KEYWORD_ATTRIBUTERELATIONID] = ""; + }, attributeChanges); + + if (changedRows) + changedRows.forEach(function (row) + { + this[row.AB_KEYWORD_ATTRIBUTERELATIONID] = row.AB_KEYWORD_ATTRIBUTE_ID; + }, attributeChanges); + + var countObj = {}; + + storedRows.forEach(function ([storedAttrRelationId, storedAttributeId]) { + var currentAttributeId = storedAttributeId; + //merging the data that is stored in the DB and the provided changes + if (attributeChanges && storedAttrRelationId in attributeChanges) + currentAttributeId = attributeChanges[storedAttrRelationId]; + + // it doesn't matter if a row has been deleted or if the attribute has been set to "nothing" + if (currentAttributeId == "") + _decrCount(storedAttributeId); + else + { + _incrCount(currentAttributeId); + if (currentAttributeId != storedAttributeId) + _decrCount(storedAttributeId); + } + }); + + if (insertedRows) //append the new rows + { + insertedRows.forEach(function (row) + { + this[row.AB_KEYWORD_ATTRIBUTE_ID] = (this[row.AB_KEYWORD_ATTRIBUTE_ID] || 0) + 1; + }, countObj); + } + + for (let id in countObj) + if (countObj[id] > 1) + return false; + + return true; + + function _incrCount (pAttributeId) + { + if (countObj[pAttributeId]) + countObj[pAttributeId]++; + else + countObj[pAttributeId] = 1; + } + + function _decrCount (pAttributeId) + { + if (countObj[pAttributeId]) + countObj[pAttributeId]--; + else + countObj[pAttributeId] = 0; + } +} \ No newline at end of file diff --git a/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/children/keywordentryid_param/valueProcess.js b/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/children/keywordentryid_param/valueProcess.js deleted file mode 100644 index 53afbdfbbfe..00000000000 --- a/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/children/keywordentryid_param/valueProcess.js +++ /dev/null @@ -1,4 +0,0 @@ -import("system.vars"); -import("system.result"); - -result.string(vars.get("$field.AB_KEYWORD_ENTRYID")); \ No newline at end of file diff --git a/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/documentation.adoc b/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/documentation.adoc deleted file mode 100644 index 99874edc30d..00000000000 --- a/entity/KeywordEntry_entity/entityfields/keywordattributerelationsreadonly/documentation.adoc +++ /dev/null @@ -1,2 +0,0 @@ -Since it's not possible to limit the keywordAttributeRelation to a distinctive list (use a KeywordAttributeRelation "category" only once per keyowrd-entry) within the generic-multiple-template / titledList-template use this readonly consumer there. -For editing use the not-read-only consumer in a list-template. In a list-template only one row can be changed (and stored) which means we can exlucde already stored entries. \ No newline at end of file diff --git a/entity/KeywordEntry_entity/onValidation.js b/entity/KeywordEntry_entity/onValidation.js index f1f568a35c0..c2eb1f2b717 100644 --- a/entity/KeywordEntry_entity/onValidation.js +++ b/entity/KeywordEntry_entity/onValidation.js @@ -1,22 +1,22 @@ -import("system.translate"); -import("system.db"); -import("system.vars"); -import("system.text"); -import("system.neon"); -import("Sql_lib"); - -//TODO: this should no happen in onValidation; waiting for #1032668 -if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) -{ - var keyContainer = vars.get("$field.CONTAINER"); - if (keyContainer) - { - var cond = SqlCondition.begin().andPrepare("AB_KEYWORD_ENTRY.CONTAINER", keyContainer); - var maskingHelper = new SqlMaskingUtils(); - var newCodeNumber = db.cell(cond.buildSql("select " + maskingHelper.max("AB_KEYWORD_ENTRY.SORTING") + " from AB_KEYWORD_ENTRY", "1 = 2")); - newCodeNumber = Number(newCodeNumber);//if no number exists till no, start value will be 1 (due to: ++0) - if (isNaN(newCodeNumber)) - throw new TypeError(translate.text("The code number is not a valid number.")); - neon.setFieldValue("$field.SORTING", ++newCodeNumber); - } -} \ No newline at end of file +import("system.translate"); +import("system.db"); +import("system.vars"); +import("system.text"); +import("system.neon"); +import("Sql_lib"); + +//TODO: this should no happen in onValidation; waiting for #1032668 +if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW) +{ + var keyContainer = vars.get("$field.CONTAINER"); + if (keyContainer) + { + var cond = SqlCondition.begin().andPrepare("AB_KEYWORD_ENTRY.CONTAINER", keyContainer); + var maskingHelper = new SqlMaskingUtils(); + var newCodeNumber = db.cell(cond.buildSql("select " + maskingHelper.max("AB_KEYWORD_ENTRY.SORTING") + " from AB_KEYWORD_ENTRY", "1 = 2")); + newCodeNumber = Number(newCodeNumber);//if no number exists till no, start value will be 1 (due to: ++0) + if (isNaN(newCodeNumber)) + throw new TypeError(translate.text("The code number is not a valid number.")); + neon.setFieldValue("$field.SORTING", ++newCodeNumber); + } +} diff --git a/neonContext/KeywordEntry/KeywordEntry.aod b/neonContext/KeywordEntry/KeywordEntry.aod index 9c8eee02ee3..a42880585c7 100644 --- a/neonContext/KeywordEntry/KeywordEntry.aod +++ b/neonContext/KeywordEntry/KeywordEntry.aod @@ -4,7 +4,6 @@ <title>Keyword</title> <description><null value></description> <majorModelMode>DISTRIBUTED</majorModelMode> - <mainview>KeywordEntryMain_view</mainview> <filterview>KeywordEntryFilter_view</filterview> <editview>KeywordEntryEdit_view</editview> <preview>KeywordEntryPreview_view</preview> @@ -22,13 +21,5 @@ <name>9bb352b9-5a8c-41ac-9c42-7f4f7f4827f3</name> <view>KeywordEntryPreview_view</view> </neonViewReference> - <neonViewReference> - <name>bba3520e-3e12-44e9-89dc-b42183e332ec</name> - <view>KeywordEntryMain_view</view> - </neonViewReference> - <neonViewReference> - <name>fb697cca-5e7d-4814-a6ed-09f32f9f60fd</name> - <view>KeywordEntryMainSide_view</view> - </neonViewReference> </references> </neonContext> diff --git a/neonView/KeywordEntryMainSide_view/KeywordEntryMainSide_view.aod b/neonView/KeywordEntryMainSide_view/KeywordEntryMainSide_view.aod deleted file mode 100644 index ba521d29a3b..00000000000 --- a/neonView/KeywordEntryMainSide_view/KeywordEntryMainSide_view.aod +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> - <name>KeywordEntryMainSide_view</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <layout> - <boxLayout> - <name>layout</name> - </boxLayout> - </layout> - <children> - <cardViewTemplate> - <name>Header</name> - <titleField>TITLE</titleField> - <subtitleField>CONTAINER</subtitleField> - <descriptionField>KEYID</descriptionField> - <entityField>#ENTITY</entityField> - </cardViewTemplate> - <genericViewTemplate> - <name>Info</name> - <entityField>#ENTITY</entityField> - <fields> - <entityFieldLink> - <name>12e16874-32ee-47d7-b9d7-acaa32ca0402</name> - <entityField>ISACTIVE</entityField> - </entityFieldLink> - <entityFieldLink> - <name>74f8f491-43e2-4de5-b1c6-c83055b4ffa1</name> - <entityField>ISESSENTIAL</entityField> - </entityFieldLink> - <entityFieldLink> - <name>5608493f-90b5-4baf-9114-63cb6a2e85bf</name> - <entityField>SORTING</entityField> - </entityFieldLink> - </fields> - </genericViewTemplate> - </children> -</neonView> diff --git a/neonView/KeywordEntryMain_view/KeywordEntryMain_view.aod b/neonView/KeywordEntryMain_view/KeywordEntryMain_view.aod deleted file mode 100644 index b69aaabd14c..00000000000 --- a/neonView/KeywordEntryMain_view/KeywordEntryMain_view.aod +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> - <name>KeywordEntryMain_view</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <layout> - <masterSlaveLayout> - <name>layout</name> - <master>267eb426-08d6-4699-9b9f-743c9c071463</master> - </masterSlaveLayout> - </layout> - <children> - <neonViewReference> - <name>267eb426-08d6-4699-9b9f-743c9c071463</name> - <entityField>#ENTITY</entityField> - <view>KeywordEntryMainSide_view</view> - </neonViewReference> - <neonViewReference> - <name>e722eb4b-5737-4801-b6e4-550fca43963a</name> - <entityField>KeywordAttributeRelations</entityField> - <view>KeywordAttributeRelationRows_view</view> - </neonViewReference> - </children> -</neonView> diff --git a/neonView/KeywordEntryPreview_view/KeywordEntryPreview_view.aod b/neonView/KeywordEntryPreview_view/KeywordEntryPreview_view.aod index d37f7f0daca..c169f747098 100644 --- a/neonView/KeywordEntryPreview_view/KeywordEntryPreview_view.aod +++ b/neonView/KeywordEntryPreview_view/KeywordEntryPreview_view.aod @@ -1,45 +1,45 @@ -<?xml version="1.0" encoding="UTF-8"?> -<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> - <name>KeywordEntryPreview_view</name> - <majorModelMode>DISTRIBUTED</majorModelMode> - <layout> - <headerFooterLayout> - <name>layout</name> - <header>Header</header> - </headerFooterLayout> - </layout> - <children> - <cardViewTemplate> - <name>Header</name> - <titleField>TITLE</titleField> - <subtitleField>CONTAINER</subtitleField> - <descriptionField>KEYID</descriptionField> - <entityField>#ENTITY</entityField> - </cardViewTemplate> - <genericViewTemplate> - <name>Info</name> - <showDrawer v="true" /> - <entityField>#ENTITY</entityField> - <title></title> - <fields> - <entityFieldLink> - <name>8455ebce-3bc2-4b0c-8e80-ec3795202d0e</name> - <entityField>ISACTIVE</entityField> - </entityFieldLink> - <entityFieldLink> - <name>4b0bb3a6-5457-4eee-b0d8-6ec4b23c0aa7</name> - <entityField>ISESSENTIAL</entityField> - </entityFieldLink> - <entityFieldLink> - <name>30d80ba1-235e-4b4a-9e9c-2b63f70f87b5</name> - <entityField>SORTING</entityField> - </entityFieldLink> - </fields> - </genericViewTemplate> - <neonViewReference> - <name>31f3e341-19b3-452e-a381-942c9860f696</name> - <entityField>KeywordAttributeRelationsReadOnly</entityField> - <view>KeywordAttriubteRelationTitled_view</view> - </neonViewReference> - </children> -</neonView> +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.2"> + <name>KeywordEntryPreview_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <headerFooterLayout> + <name>layout</name> + <header>Header</header> + </headerFooterLayout> + </layout> + <children> + <cardViewTemplate> + <name>Header</name> + <titleField>TITLE</titleField> + <subtitleField>CONTAINER</subtitleField> + <descriptionField>KEYID</descriptionField> + <entityField>#ENTITY</entityField> + </cardViewTemplate> + <genericViewTemplate> + <name>Info</name> + <showDrawer v="true" /> + <entityField>#ENTITY</entityField> + <title></title> + <fields> + <entityFieldLink> + <name>8455ebce-3bc2-4b0c-8e80-ec3795202d0e</name> + <entityField>ISACTIVE</entityField> + </entityFieldLink> + <entityFieldLink> + <name>4b0bb3a6-5457-4eee-b0d8-6ec4b23c0aa7</name> + <entityField>ISESSENTIAL</entityField> + </entityFieldLink> + <entityFieldLink> + <name>30d80ba1-235e-4b4a-9e9c-2b63f70f87b5</name> + <entityField>SORTING</entityField> + </entityFieldLink> + </fields> + </genericViewTemplate> + <neonViewReference> + <name>31f3e341-19b3-452e-a381-942c9860f696</name> + <entityField>KeywordAttributeRelations</entityField> + <view>KeywordAttriubteRelationTitled_view</view> + </neonViewReference> + </children> +</neonView> diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js index bf397d874cb..0a3b7af1fcc 100644 --- a/process/Attribute_lib/process.js +++ b/process/Attribute_lib/process.js @@ -1,1086 +1,1086 @@ -import("KeywordData_lib"); -import("Context_lib"); -import("system.util"); -import("system.datetime"); -import("system.translate"); -import("system.neon"); -import("system.vars"); -import("system.db"); -import("system.project"); -import("system.entities"); -import("Sql_lib"); -import("Keyword_lib"); - -/** - * Provides functions for the work with attributes, like - * listing the available attributes for a context. - * Don't instanciate this! - * - * @class - */ -function AttributeUtil () {} - -/** - * Gives an array of all available attributes for a context. This is used in the possibleItems - * process for the attribute id in AttributeRelation - * - * @param {String} pObjectType the object type (= context) - * @param {boolean} [pIncludeGroups=false] - * @param {String[]} [pFilteredAttributeIds=[]] Whitleist of attribute ids - * @param {Object} [pAttributeCount=null] Object with attribute ids and their count - * - * @return {String[]} array of attributeIds - */ -AttributeUtil.getPossibleAttributes = function (pObjectType, pIncludeGroups, pFilteredAttributeIds, pAttributeCount) -{ - if (pObjectType == null || (pFilteredAttributeIds && pFilteredAttributeIds.length == 0)) - return []; - - var attrSql = "select AB_ATTRIBUTEID from AB_ATTRIBUTE" - + " join AB_ATTRIBUTEUSAGE on AB_ATTRIBUTEID = AB_ATTRIBUTE_ID"; - var attrCond = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") - .and("ATTRIBUTE_ACTIVE = 1"); - - if (pAttributeCount) - { - for (let attributeId in pAttributeCount) - { - attrCond.andSqlCondition( - SqlCondition.begin() - .orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", attributeId, "# != ?") - .orPrepare("AB_ATTRIBUTEUSAGE.MAX_COUNT", pAttributeCount[attributeId], "# > ?") - .or("AB_ATTRIBUTEUSAGE.MAX_COUNT is null") - ); - } - } - - if (pFilteredAttributeIds) - { - var filteredIdsCondition = new SqlCondition(); - var filteredIdChildren = AttributeUtil.getAllChildren(pFilteredAttributeIds); - pFilteredAttributeIds.concat(filteredIdChildren).forEach(function(id) - { - this.orPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", id); - }, filteredIdsCondition); - - attrCond.andSqlCondition(filteredIdsCondition); - } - - if (!pIncludeGroups) - attrCond.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP, "# != ?"); - - var attributes = db.array(db.COLUMN, attrCond.buildSql(attrSql)); - - return attributes; -} - -/** - * searches for possiblevalues for a atttribute and returns these. The values depend on the attributeType - * - * @param {String} pAttributeId the id of the attribute - * @param {Boolean} pAttributeType type of the attribute that is specified with pAttributeId; - * The type needs to be passed to the function for better performance - * (loading the type via attribute several times would be too slow) - * @param {Boolean} [pIncludeInactives=false] specifies if only active attributevalues or actives + inactives shall be returned, - * this is important when you want to search for attributevalues - * - * @return {Array} 2D-array with [ID, value] als elements if the given attributeType has possible items. if not null is returned - */ -AttributeUtil.getPossibleListValues = function (pAttributeId, pAttributeType, pIncludeInactives) -{ - var attributeId = pAttributeId; - var attrType = pAttributeType.trim(); - var onlyActives = (pIncludeInactives == undefined ? false : pIncludeInactives); - if (attrType == $AttributeTypes.COMBO.toString()) - { - var valueSql = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", attributeId) - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE); - - if (onlyActives) - valueSql.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_ACTIVE", "1"); - - valueSql = valueSql.buildSql("select AB_ATTRIBUTEID, ATTRIBUTE_NAME from AB_ATTRIBUTE", "1=2", "order by SORTING asc"); - var valueList = db.table(valueSql); - for (let i = 0; i < valueList.length; i++) - { - valueList[i][1] = translate.text(valueList[i][1]); - } - return valueList; - } - else if (attrType == $AttributeTypes.BOOLEAN.toString()) - { - return [ - ["1", translate.text("Yes")], - ["0", translate.text("No")] - ]; - } - else if (attrType == $AttributeTypes.KEYWORD.toString()) - { - var attrKeywordSelect = "select DROPDOWNDEFINITION from AB_ATTRIBUTE"; - attrKeywordSelect = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", attributeId) - .buildSql(attrKeywordSelect); - var attrKeyword = db.cell(attrKeywordSelect); - var keywords = KeywordData.getSimpleData(attrKeyword, null, onlyActives); - return keywords; - } - else if (attrType == $AttributeTypes.OBJECTSELECTION) - { - var [module, filter] = db.array(db.ROW, SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", attributeId) - .buildSql("select DROPDOWNDEFINITION, DROPDOWNFILTER from AB_ATTRIBUTE") - ); - var objects = []; - if (module) - { - var uid = "#UID"; - var title = "#CONTENTTITLE"; - var config = entities.createConfigForLoadingRows() - .entity(module) - .fields([uid, title]); - if (filter) - config.filter(filter); - var rows = entities.getRows(config); - for (let i = 0, l = rows.length; i < l; i++) - objects.push([rows[i][uid], rows[i][title]]) - } - return objects; - } - else - return null; -} - -/** - * returns the name of an attribute with all parent attribute names - * - * @param {String} pAttributeId the id of the attribute - * @param {Boolean} [pSimpleName=false] Use only the name of the attribute and not the names of the parents. - * @param {Boolean} [pTranslate=true] translate the name - * - * @return {String} the name of the attribute - */ -AttributeUtil.getFullAttributeName = function (pAttributeId, pSimpleName, pTranslate) -{ - if (pSimpleName === undefined) - pSimpleName = false; - if (pTranslate === undefined) - pTranslate = true; - - if (!pAttributeId) - return ""; - if (pSimpleName) - return AttributeUtil.getSimpleAttributeName(pAttributeId, pTranslate); - var attributeNames = []; - var attribute; - do { - attribute = db.array(db.ROW, SqlCondition.begin() - .andPrepare(["AB_ATTRIBUTE", "AB_ATTRIBUTEID", "ATTRIBUTE"], pAttributeId) - .buildSql("select ATTRIBUTE.ATTRIBUTE_NAME, PARENT1.ATTRIBUTE_NAME, PARENT2.ATTRIBUTE_NAME, PARENT2.ATTRIBUTE_PARENT_ID \n\ - from AB_ATTRIBUTE ATTRIBUTE \n\ - left join AB_ATTRIBUTE PARENT1 on ATTRIBUTE.ATTRIBUTE_PARENT_ID = PARENT1.AB_ATTRIBUTEID \n\ - left join AB_ATTRIBUTE PARENT2 on PARENT1.ATTRIBUTE_PARENT_ID = PARENT2.AB_ATTRIBUTEID") - ); - if (attribute.length > 0) - { - attributeNames.push(attribute[0]); - if (attribute[1]) - attributeNames.push(attribute[1]); - if (attribute[2]) - attributeNames.push(attribute[2]); - pAttributeId = attribute[3]; - } - else - pAttributeId = ""; - } while (pAttributeId); - - if (pTranslate) - { - for (let i = 0; i < attributeNames.length; i++) - { - attributeNames[i] = translate.text(attributeNames[i]); - } - } - return attributeNames.reverse().join(" / "); -} - -/** - * returns the name of an attribute - * - * @param {String} pAttributeId the id of the attribute - * @param {boolean} [pTranslate] if the name should be translated - * - * @return {String} the name of the attribute - */ -AttributeUtil.getSimpleAttributeName = function (pAttributeId, pTranslate) -{ - var attributeName = db.cell(SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId) - .buildSql("select ATTRIBUTE_NAME from AB_ATTRIBUTE") - ); - if (pTranslate) - attributeName = translate.text(attributeName); - return attributeName; -} - -/** - * returns the ids of all subordinated attributes of an attribute - * - * @param {String|Array} pAttributeIds the id(s) of the attribute(s) - * - * @result {String[]} array with the ids of every subordinated attribute - */ -AttributeUtil.getAllChildren = function (pAttributeIds) -{ - var childIds = []; - if (typeof(pAttributeIds) == "string") - pAttributeIds = [pAttributeIds]; - - while (pAttributeIds.length > 0) - { - pAttributeIds = db.array(db.COLUMN, SqlCondition.begin() - .andIn("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeIds) - .buildSql("select AB_ATTRIBUTEID from AB_ATTRIBUTE") - ); - if (pAttributeIds.length > 0) - childIds = childIds.concat(pAttributeIds); - } - return childIds; -} - -/** - * checks if an attribute has attribute relations - * - * @param {String} pAttributeId the id of the attribute - * - * @result {boolean} true if it has relations - */ -AttributeUtil.hasRelations = function (pAttributeId) -{ - if (!pAttributeId) - return false; - return db.cell(SqlCondition.begin() - .andPrepare("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId) - .buildSql( - "select count(*) from AB_ATTRIBUTERELATION", "1=2" //TODO: is there a way exists could be used? - ) - ) != "0"; -} - -/** - * returns the type of an attribute - * - * @param {String} pAttributeId the id of the attribute - * - * @result {String} attribute type - */ -AttributeUtil.getAttributeType = function (pAttributeId) -{ - if (!pAttributeId) - return ""; - var attrTypeSelect = "select ATTRIBUTE_TYPE from AB_ATTRIBUTE"; - attrTypeSelect = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId) - .buildSql(attrTypeSelect); - return db.cell(attrTypeSelect).trim(); -} - -AttributeUtil.hasAttributes = function (pObjectType) -{ - if (!pObjectType) - return false; - return db.cell(SqlCondition.begin() - .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_ACTIVE", "1") - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP, "# != ?") - .buildSql( - "select count(*) from AB_ATTRIBUTEUSAGE \n\ - join AB_ATTRIBUTE on AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID", "1=2" - ) - ) != "0"; //TODO: is there a way exists could be used? -} - -/*********************************************************************************************************************/ - -/** - * Provides functions for the work with attributeRelations, getting the value of an attributeRelation for an object. - * Don't instanciate this! - * - * @class - */ -function AttributeRelationUtils () {} - -/** - * gets the value of an attributeRelation for one dataset (e. g. a person) - * - * @param {String} pAttributeId attribute-id - * @param {String} pObjectRowId row-id of the dataset - * @param {String} [pObjectType=null] object-type - * @param {String} [pGetViewValue=false] if true the values are resolved and formatted - * @param {String} [pGetAttrname=false] if true the attributename is also returned - * - * @return {String|String[]|null} the value of the attribute or an array of attrname and value [attrname, value] (if pGetAttrname is true) - */ -AttributeRelationUtils.getAttribute = function (pAttributeId, pObjectRowId, pObjectType, pGetViewValue, pGetAttrname) -{ - var attrCond = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", pObjectRowId) - .andPrepare("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId); - if (pObjectType != null) - attrCond.andPrepare("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType); - - var defaultFields = [ - "AB_ATTRIBUTE.ATTRIBUTE_TYPE", - "AB_ATTRIBUTE.DROPDOWNDEFINITION", - "COMBOVAL.ATTRIBUTE_NAME" - ]; - - if (pGetAttrname) - defaultFields.push("AB_ATTRIBUTE.ATTRIBUTE_NAME"); - - var valueFields = AttributeTypeUtil.getAllDatabaseFields(); - var attributeSql = attrCond.buildSql("select " + defaultFields.join(", ") + ", " + valueFields.join(", ") - + " from AB_ATTRIBUTERELATION join AB_ATTRIBUTE on AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID" - + " left join AB_ATTRIBUTE COMBOVAL on " + $AttributeTypes.COMBO.databaseField + " = COMBOVAL.AB_ATTRIBUTEID"); - - var attributeValues = db.array(db.ROW, attributeSql); - if (!attributeValues.length) - return null; - - let value = attributeValues[AttributeTypeUtil.getTypeColumnIndex(attributeValues[0]) + defaultFields.length]; - if (pGetViewValue && attributeValues[1].trim() == $AttributeTypes.COMBO) - value = attributeValues[2]; - else if (pGetViewValue) - value = AttributeTypeUtil.getAttributeViewValue(attributeValues[0].trim(), value, attributeValues[1]); - - if (pGetAttrname) - value = [attributeValues[3], value]; - - return value; -} - -/** - * gets all attributes for a dataset - * - * @param {String} pObjectRowId object rowid - * @param {String} [pObjectType=null] object-type - * @param {String} [pUseAttributeIds=0] if 0 the full attribute names are returned - * if 1 the ids are used instead of the full attribute names - * if 2 the ids AND the full attribute name is returned - * @param {String} [pUseIdValues=false] if true the values are not resolved or formatted [attributeId, attributeName, value] - * - * @return {String[][]} two-dimensional array a row is [attributeId|attributeName, value] (or [attributeId, attributeName, value]) - */ -AttributeRelationUtils.getAllAttributes = function (pObjectRowId, pObjectType, pUseAttributeIds, pUseIdValues) -{ - var attrCond = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", pObjectRowId); - if (pObjectType != null) - attrCond.andPrepare("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType); - - var defaultFields = [ - "AB_ATTRIBUTE_ID", - "AB_ATTRIBUTE.ATTRIBUTE_TYPE", - "AB_ATTRIBUTE.DROPDOWNDEFINITION", - "COMBOVAL.ATTRIBUTE_NAME" - ]; - var valueFields = AttributeTypeUtil.getAllDatabaseFields(); - var attributeSql = attrCond.buildSql("select " + defaultFields.join(", ") + ", " + valueFields.join(", ") - + " from AB_ATTRIBUTERELATION join AB_ATTRIBUTE on AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID" - + " left join AB_ATTRIBUTE COMBOVAL on " + $AttributeTypes.COMBO.databaseField + " = COMBOVAL.AB_ATTRIBUTEID"); - - var attributeNameMap = {}; - var attributeValues = db.table(attributeSql).map(function (row) - { - let attribute = row[0]; - let attrname; - if (pUseAttributeIds == 0 || pUseAttributeIds == 2) - { - var tmpAttrname = ""; - if (!(attribute in attributeNameMap)) - attributeNameMap[attribute] = AttributeUtil.getFullAttributeName(attribute); - tmpAttrname = attributeNameMap[attribute]; - - // if mode 0, return only the name - if (pUseAttributeIds == 0) - attribute = tmpAttrname - - // if mode 2 return both - if (pUseAttributeIds == 2) - attrname = tmpAttrname - } - let value = row[AttributeTypeUtil.getTypeColumnIndex(row[1]) + defaultFields.length]; - if (!pUseIdValues && row[1].trim() == $AttributeTypes.COMBO) - value = row[3]; - else if (!pUseIdValues) - value = AttributeTypeUtil.getAttributeViewValue(row[1].trim(), value, row[2]); - - // add attrname only if id AND attrname is needed - var data = []; - - data.push(attribute); - - if (attrname) - data.push(attrname); - - data.push(value); - return data; - }); - - return attributeValues; -} - -/** - * gets the correct attribute value from a map with values depending on the attribute id - * - * @param {String} pAttributeId the attribute id - * @param {Object} pValueMap a map with the attribute values and the db fields as keys - * @param {Boolean} [pGetViewValue=false] if true, get the view value - * - * @return {String|null} the value of the attribute or null if the attribute doesn't exist - */ -AttributeRelationUtils.selectAttributeValue = function (pAttributeId, pValueMap, pGetViewValue) -{ - var sqlSelect = "select ATTRIBUTE_TYPE, DROPDOWNDEFINITION from AB_ATTRIBUTE"; - var type = db.array(db.ROW, SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId) - .buildSql(sqlSelect) - ); - if (!type.length) - return null; - - type[0] = type[0].trim(); - var field = AttributeTypeUtil.getDatabaseField(type[0]); - var value = pValueMap[field]; - if (pGetViewValue && type[0] == $AttributeTypes.COMBO) - { - value = db.cell(SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", value) - .buildSql("select ATTRIBUTE_NAME from AB_ATTRIBUTE") - ); - } - else if (pGetViewValue) - value = AttributeTypeUtil.getAttributeViewValue(type[0], value, type[1]); - - return value; -} - -AttributeRelationUtils.getAttributes = function () -{ - //TODO: implement maybe -} - -/** - * sets the value of an attribute for one dataset (e. g. a person) - */ -AttributeRelationUtils.setAttribute = function () -{ - //TODO: implement -} - -/** - * adds rows for attributes with min_count > 0 - * - * @param {String} pObjectType the object type - * @param {String} pConsumer the name of the attribute relation consumer - */ -AttributeRelationUtils.presetMandatoryAttributes = function (pObjectType, pConsumer) -{ - var mandatoryAttributes = db.table( - SqlCondition.begin() - .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# <> ?") - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP, "# <> ?") - .and("ATTRIBUTE_ACTIVE = 1") - .and("MIN_COUNT > 0") - .buildSql("select AB_ATTRIBUTE_ID, MIN_COUNT from AB_ATTRIBUTEUSAGE " - + "join AB_ATTRIBUTE on AB_ATTRIBUTE_ID = AB_ATTRIBUTEID") - ); - mandatoryAttributes.forEach(function (usage) - { - //adding an attribute more than 20 times would be too much (having a min_count > 20 is very unlikely) - for (let i = 0; i < usage[1] && i < 20; i++) - neon.addRecord(pConsumer, { - "AB_ATTRIBUTE_ID" : usage[0] - }); - }); -} - -/** - * Checks if the count of the used attributes is valid and returns a message if it's not. - * - * @param {String} pRowId the row id of the entity - * @param {String} [pObjectType=null] the object type - * @param {String} pConsumerField the name of the attribute relation consumer - * - * @return {String} the validation message or an empty string if everything is ok - */ -AttributeRelationUtils.validateAttributeCount = function (pRowId, pObjectType, pConsumerField) -{ - var attributeChanges = {}; - var deletedRows = vars.get("$field." + pConsumerField + ".deletedRows"); - var changedRows = vars.get("$field." + pConsumerField + ".changedRows"); - var insertedRows = vars.get("$field." + pConsumerField + ".insertedRows"); - - if (deletedRows) - { - deletedRows.forEach(function (row) - { - this[row.UID] = ""; - }, attributeChanges); - } - - if (changedRows) - { - changedRows.forEach(function (row) - { - this[row.UID] = row.AB_ATTRIBUTE_ID; - }, attributeChanges); - } - - //get the current count of usages considering the changes - //this will merge the counts of attributeChanges and the already stored attributerelations - var countObj = AttributeRelationUtils.countAttributeRelations(pRowId, pObjectType, attributeChanges); - - if (insertedRows) //append the new rows - { - insertedRows.forEach(function (row) - { - this[row.AB_ATTRIBUTE_ID] = (this[row.AB_ATTRIBUTE_ID] || 0) + 1; - }, countObj); - } - var attributeCondition = SqlCondition.begin(); - AttributeUtil.getPossibleAttributes(pObjectType).forEach(function (attributeId) - { - this.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", attributeId); - }, attributeCondition); - - var usageCondition = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) - .andSqlCondition(attributeCondition, "1=2"); - - //retrieve all min/max counts of the possible attributes - var minMaxCounts = db.table(usageCondition.buildSql( - "select AB_ATTRIBUTEID, ATTRIBUTE_NAME, MIN_COUNT, MAX_COUNT from AB_ATTRIBUTEUSAGE \ - join AB_ATTRIBUTE on AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID", "1=2" - )); - - var validationMessage = []; - minMaxCounts.forEach(function ([attributeId, name, minCount, maxCount]) - { - let count = this[attributeId] || 0; - //compares the actual usage with the min and max count and generates a message if the usage is too low or too high - if (count < minCount) - validationMessage.push(translate.withArguments("Attribute \"%0\" has to be used at least %1.", [name, _getTranslatedCount(minCount)])); - if (maxCount && count > maxCount) - validationMessage.push(translate.withArguments("Attribute \"%0\" can't be used more than %1.", [name, _getTranslatedCount(maxCount)])); - }, countObj); - - return validationMessage.join("\n"); - - //returns the correct count expression by choosing either singular (1 time) or plural (2 times) - function _getTranslatedCount (pCount) - { - if (pCount == 1) - return pCount + " " + translate.text("${COUNT_PREPOSITION_SINGLE}"); - return pCount + " " + translate.text("${COUNT_PREPOSITION_MULTIPLE}"); - } -} - -/** - * counts attribute relations - * - * @param {String} pRowId the row id of the entity - * @param {String} [pObjectType=null] the object type - * @param {Object} [pAttributeChanges=null] object containing changes and deletions of attributes - * structure = {attributeRelationId : new attributeId or "" when deleted} - * - * @return {Object} object with attribute ids and the count of the usage (without new rows) - */ -AttributeRelationUtils.countAttributeRelations = function (pRowId, pObjectType, pAttributeChanges) -{ - //use cases: - //complete new row ==> increase count by 1 for that attribute [this is done in another function] - //row removed ==> decrease count by 1 - //row edit: replace one attribute by another attribute ==> increase the new attribute count and decrease the old attribute count - //row edit: replace attribute with no new value ==> decrease count for the old attribute - //unchanged (already stored) row ==> increase count - var countObj = {}; - - var condition = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", pRowId) - .andPrepareIfSet("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType); - - var storedAttributeRelations = db.table(condition.buildSql( - "select AB_ATTRIBUTERELATIONID, AB_ATTRIBUTE_ID from AB_ATTRIBUTERELATION", - "1=2" - )); - - storedAttributeRelations.forEach(function ([storedAttrRelationId, storedAttributeId]) { - var currentAttributeId = storedAttributeId; - //merging the data that is stored in the DB and the provided changes - if (pAttributeChanges && storedAttrRelationId in pAttributeChanges) - currentAttributeId = pAttributeChanges[storedAttrRelationId]; - - // it doesn't matter if a row has been deleted or if the attribute has been set to "nothing" - if (currentAttributeId == "") - _decrCount(storedAttributeId); - else - { - _incrCount(currentAttributeId); - if (currentAttributeId != storedAttributeId) - _decrCount(storedAttributeId); - } - }); - - function _incrCount(pAttributeId) - { - if (countObj[pAttributeId]) - countObj[pAttributeId]++; - else - countObj[pAttributeId] = 1; - } - - function _decrCount(pAttributeId) - { - if (countObj[pAttributeId]) - countObj[pAttributeId]--; - else - countObj[pAttributeId] = 0; - } - - return countObj; -} - -/*********************************************************************************************************************/ - - -/** - * Object for the enumeration and management of all attribute types. - * This Object is only for the general definition of attribute types and for getting - * data about every type, anything that has to do with a specific attribute (= the function requires an attribute id) - * should be done in AttributeUtils. - * The required values and methods for each type are: - * - * toString = function that should return a unique name - * contentType = the value that is returned in the contentType process for the attribute - * databaseField = the database field that holds values of attributes with the type - * - * optional: - * getViewValue = function that gets the display value for a given value - * isGroup = if true, the attribute can have children - * getDropDownDefinitions = function that returns an array of possible values - * for DROPDOWNDEFINITION - * - * The display name is controlled by the keyword 'AttributeType' - */ -function $AttributeTypes () {} - -$AttributeTypes.TEXT = { - toString : function () {return "TEXT";}, - contentType : "TEXT", - databaseField : "CHAR_VALUE" -}; -$AttributeTypes.DATE = { - toString : function () {return "DATE";}, - contentType : "DATE", - databaseField : "DATE_VALUE", - getViewValue : function (pValue) - { - return datetime.toDate(pValue, translate.text("dd.MM.yyyy")); - } -}; -$AttributeTypes.NUMBER = { - toString : function () {return "NUMBER";}, - contentType : "NUMBER", - databaseField : "NUMBER_VALUE" -}; -$AttributeTypes.BOOLEAN = { - toString : function () {return "BOOLEAN";}, - contentType : "BOOLEAN", - databaseField : "INT_VALUE", - getViewValue : function (pValue) - { - return pValue == "1" ? translate.text("Yes") : translate.text("No"); - } -}; -$AttributeTypes.COMBO = { - toString : function () {return "COMBO";}, - contentType : "UNKNOWN", - databaseField : "ID_VALUE", - isGroup : true, - possibleChildren : ["COMBOVALUE"] -}; -$AttributeTypes.COMBOVALUE = { - toString : function () {return "COMBOVALUE";}, - contentType : null, - databaseField : null -}; -$AttributeTypes.GROUP = { - toString : function () {return "GROUP";}, - contentType : null, - databaseField : null, - isGroup : true -}; -$AttributeTypes.KEYWORD = { - toString : function () {return "KEYWORD";}, - contentType : "UNKNOWN", - databaseField : "ID_VALUE", - getViewValue : function (pValue, pKeyword) - { - return KeywordUtils.getViewValue(pKeyword, pValue); - }, - getDropDownDefinitions : function () - { - return KeywordUtils.getContainerNames().map(function (e) - { - return [e, e];//currently the first column is ID, second view value - which is the same because there is no ID for keyword-containers - }); - } -}; -$AttributeTypes.VOID = { - toString : function () {return "VOID";}, - contentType : null, - databaseField : null, - isGroup : true, - possibleChildren : ["VOID"] -}; -$AttributeTypes.MEMO = { - toString : function () {return "MEMO";}, - contentType : "LONG_TEXT", - databaseField : "CHAR_VALUE" -}; -$AttributeTypes.OBJECTSELECTION = { - toString : function () {return "OBJECTSELECTION";}, - contentType : "UNKNOWN", - databaseField : "ID_VALUE", - getViewValue : function (pValue, pModule) - { - if (pValue) - { - var title = "#CONTENTTITLE"; - var config = entities.createConfigForLoadingRows() - .entity(pModule) - .fields([title]) - .uid(pValue); - var rows = entities.getRow(config); - pValue = rows ? rows[title] : pValue; - } - return pValue; - }, - getDropDownDefinitions : function () - { - var dropDownList = []; - //TODO filter entities - project.getDataModels(project.DATAMODEL_KIND_ENTITY).forEach( - function (entity) - { - if (entity[1]) - dropDownList.push([entity[0], translate.text(entity[1])]); - } - ); - return dropDownList; - } -}; -$AttributeTypes.THEME = { - toString : function () {return "THEME";}, - contentType : "LONG_TEXT", - databaseField : "CHAR_VALUE", - isGroup : true, - possibleChildren : ["THEME"] -}; - -function AttributeTypeUtil () {} - -/** - * returns the required contentType for the given attribute type - * - * @param {String} pAttributeType the attribute type - * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) - * @return {String} the contentType for the attribute - */ -AttributeTypeUtil.getContentType = function (pAttributeType) -{ - if (pAttributeType) - { - pAttributeType = pAttributeType.trim(); - - if (pAttributeType in $AttributeTypes) - return $AttributeTypes[pAttributeType].contentType; - } - return null; -} - -/** - * returns if the type is a group type - * - * @param {String} pAttributeType the attribute type - * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) - * @return {Boolean} if the type is a group type - */ -AttributeTypeUtil.isGroupType = function (pAttributeType) -{ - if (pAttributeType) - { - pAttributeType = pAttributeType.trim(); - if (pAttributeType in $AttributeTypes) - return $AttributeTypes[pAttributeType].isGroup || false; - } - return null; -} - -/** - * returns the database field for the given attribute type that holds the value of the attribute - * - * @param {String} pAttributeType the attribute type - * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) - * @return {String} the database field for the attribute - */ -AttributeTypeUtil.getDatabaseField = function (pAttributeType) -{ - if (pAttributeType) - { - pAttributeType = pAttributeType.trim(); - if (pAttributeType in $AttributeTypes) - return $AttributeTypes[pAttributeType].databaseField; - } - return null; -} - -/** - * returns the possible children types for the given attribute type - * - * @param {String} pAttributeType the attribute type - * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) - * @return {String[]} the possible children types - */ -AttributeTypeUtil.getPossibleChildren = function (pAttributeType) -{ - if (pAttributeType) - { - pAttributeType = pAttributeType.trim(); - if (pAttributeType in $AttributeTypes) - return $AttributeTypes[pAttributeType].possibleChildren; - } - return null; -} - -AttributeTypeUtil.getAttributeViewValue = function (pAttributeType, pValue, pKeyword) -{ - if (pAttributeType in $AttributeTypes && $AttributeTypes[pAttributeType].getViewValue) - return $AttributeTypes[pAttributeType].getViewValue(pValue, pKeyword); - return pValue; -} - -AttributeTypeUtil._initTypeColumnData = function () -{ - var columns = []; - var typeColumnMap = {}; - for (let type in $AttributeTypes) - { - type = $AttributeTypes[type]; - if (type.databaseField) - { - var typeKey = type.toString(); - var colIndex = columns.indexOf(type.databaseField); - if (colIndex == -1) - { - colIndex = columns.length; - columns.push(type.databaseField); - } - typeColumnMap[typeKey] = colIndex; - } - } - this._allDBColumns = columns; - this._typeColumnMap = typeColumnMap; -} - -AttributeTypeUtil.getAllDatabaseFields = function () -{ - if (this._allDBColumns == undefined) - AttributeTypeUtil._initTypeColumnData(); - return this._allDBColumns; -} - -AttributeTypeUtil.getTypeColumnIndex = function (pAttributeType) -{ - if (this._typeColumnMap == undefined) - AttributeTypeUtil._initTypeColumnData(); - return this._typeColumnMap[pAttributeType.trim()]; -} - -/*********************************************************************************************************************/ - -/** - * Functions for AttributeUsages. - * Do not instanciate this! - */ -function AttributeUsageUtil () {} - -/** - * Creates AttributeUsages for all subordinate attributes of an attribute. - * This is required when an usage is added to a superordinate attribute. - * - * @param {String} pAttributeId the id of the superordinate attribute - * @param {String} pObjectType the context - */ -AttributeUsageUtil.insertChildrenUsages = function (pAttributeId, pObjectType) -{ - if (!pAttributeId) - return; - var table = "AB_ATTRIBUTEUSAGE"; - var columns = ["AB_ATTRIBUTEUSAGEID", "AB_ATTRIBUTE_ID", "OBJECT_TYPE"]; - var types = db.getColumnTypes(table, columns); - - var sqlSelect = "select AB_ATTRIBUTEID, " - + " (select count(*) from AB_ATTRIBUTEUSAGE where AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID and OBJECT_TYPE = '" - + pObjectType + "') = 0 from AB_ATTRIBUTE"; - - var inserts = []; - _addInserts(pAttributeId, pObjectType); - db.inserts(inserts); - - function _addInserts (pAttributeId, pObjectType) - { - var condition = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeId); - var attributes = db.table(condition.buildSql(sqlSelect)); - - attributes.forEach(function (row) - { - if (row[1] == "true") - { - let values = [util.getNewUUID(), row[0], pObjectType]; - inserts.push([table, columns, types, values]); - } - _addInserts(row[0], pObjectType); - }); - } -} - -/** - * Updates AttributeUsages for all subordinate attributes of an attribute. - * This is required when an usage of a superordinate attribute is changed. - * - * @param {String} pAttributeId the id of the superordinate attribute - * @param {String} pOldObjectType ye olde context - * @param {String} pNewObjectType the new context - */ -AttributeUsageUtil.updateChildrenUsages = function (pAttributeId, pOldObjectType, pNewObjectType) -{ - if (!pNewObjectType || !pAttributeId) - return; - - var table = "AB_ATTRIBUTEUSAGE"; - - var countSubQuery = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pNewObjectType) - .and("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID") - .buildSql("select count(*) from AB_ATTRIBUTEUSAGE"); - - var sqlSelect = SqlBuilder.begin() - .select(["AB_ATTRIBUTEID", "AB_ATTRIBUTEUSAGEID", countSubQuery]) - .from("AB_ATTRIBUTE") - .leftJoin("AB_ATTRIBUTEUSAGE", SqlCondition.begin() - .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pOldObjectType) - .and("AB_ATTRIBUTEID = AB_ATTRIBUTE_ID")); - - var updateCond = SqlCondition.begin(); - - //it is possible that the new objectType is already in a subordinate attribute - //and an update could cause a duplicate entry so one has to be deleted - var deleteCond = SqlCondition.begin(); - - _addUpdateIds(pAttributeId, pOldObjectType); - - if (updateCond.isSet()) - db.updateData(table, ["OBJECT_TYPE"], null, [pNewObjectType], updateCond.build("1=2")); - if (deleteCond.isSet()) - db.deleteData(table, deleteCond.build("1=2")); - - function _addUpdateIds (pAttributeId) - { - var condition = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeId); - var query = sqlSelect.where(condition); - var attributes = db.table(query.build()); - - attributes.forEach(function (row) - { - if (row[1] && row[2] != "0") - deleteCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]); - else if (row[1]) - updateCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]); - _addUpdateIds(row[0]); - }); - } -} - -/** - * Deletes AttributeUsages for all subordinate attributes of an attribute. - * This is required when an usage is removed from a superordinate attribute. - * - * @param {String} pAttributeId the id of the superordinate attribute - * @param {String} pObjectType the context - */ -AttributeUsageUtil.deleteChildrenUsages = function (pAttributeId, pObjectType) -{ - var table = "AB_ATTRIBUTEUSAGE"; - - var sqlSelect = "select AB_ATTRIBUTEID, AB_ATTRIBUTEUSAGEID " - + " from AB_ATTRIBUTE left join AB_ATTRIBUTEUSAGE on AB_ATTRIBUTEID = AB_ATTRIBUTE_ID and OBJECT_TYPE = '" + pObjectType + "'"; - - var deleteCond = SqlCondition.begin(); - _addDeleteIds(pAttributeId, pObjectType); - if (deleteCond.isSet()) - db.deleteData(table, deleteCond.build("1=2")); - - function _addDeleteIds (pAttributeId) - { - var condition = SqlCondition.begin() - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") - .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeId); - var attributes = db.table(condition.buildSql(sqlSelect)); - - attributes.forEach(function (row) - { - if (row[1]) - deleteCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]) - _addDeleteIds(row[0]); - }); - } -} - -/** - * Deletes duplicate attribute usages. - * - * @param {String} [pAttributeId=null] attribute id, if omitted, all duplicates will be deleted - */ -AttributeUsageUtil.removeDuplicates = function (pAttributeId) -{ - var condition = SqlCondition.begin() - .and("exists (select AB_ATTRIBUTEUSAGEID from AB_ATTRIBUTEUSAGE AU where AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AU.AB_ATTRIBUTE_ID " - + "and AB_ATTRIBUTEUSAGE.OBJECT_TYPE = AU.OBJECT_TYPE and AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID != AU.AB_ATTRIBUTEUSAGEID)"); - if (pAttributeId) - condition.andPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", pAttributeId); - - var duplicates = db.table(condition.buildSql("select AB_ATTRIBUTEUSAGEID, AB_ATTRIBUTE_ID, OBJECT_TYPE from AB_ATTRIBUTEUSAGE")); - var usageObj = {}; - var deleteCond = SqlCondition.begin(); - - duplicates.forEach(function (row) - { - if (!(row[1] in this)) - this[row[1]] = {}; - if (row[2] in this[row[1]]) - deleteCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[0]); - this[row[1]][row[2]] = true; - }, usageObj); - if (deleteCond.isSet()) - db.deleteData("AB_ATTRIBUTEUSAGE", deleteCond.build("1=2")); +import("KeywordData_lib"); +import("Context_lib"); +import("system.util"); +import("system.datetime"); +import("system.translate"); +import("system.neon"); +import("system.vars"); +import("system.db"); +import("system.project"); +import("system.entities"); +import("Sql_lib"); +import("Keyword_lib"); + +/** + * Provides functions for the work with attributes, like + * listing the available attributes for a context. + * Don't instanciate this! + * + * @class + */ +function AttributeUtil () {} + +/** + * Gives an array of all available attributes for a context. This is used in the possibleItems + * process for the attribute id in AttributeRelation + * + * @param {String} pObjectType the object type (= context) + * @param {boolean} [pIncludeGroups=false] + * @param {String[]} [pFilteredAttributeIds=[]] Whitleist of attribute ids + * @param {Object} [pAttributeCount=null] Object with attribute ids and their count + * + * @return {String[]} array of attributeIds + */ +AttributeUtil.getPossibleAttributes = function (pObjectType, pIncludeGroups, pFilteredAttributeIds, pAttributeCount) +{ + if (pObjectType == null || (pFilteredAttributeIds && pFilteredAttributeIds.length == 0)) + return []; + + var attrSql = "select AB_ATTRIBUTEID from AB_ATTRIBUTE" + + " join AB_ATTRIBUTEUSAGE on AB_ATTRIBUTEID = AB_ATTRIBUTE_ID"; + var attrCond = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") + .and("ATTRIBUTE_ACTIVE = 1"); + + if (pAttributeCount) + { + for (let attributeId in pAttributeCount) + { + attrCond.andSqlCondition( + SqlCondition.begin() + .orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", attributeId, "# != ?") + .orPrepare("AB_ATTRIBUTEUSAGE.MAX_COUNT", pAttributeCount[attributeId], "# > ?") + .or("AB_ATTRIBUTEUSAGE.MAX_COUNT is null") + ); + } + } + + if (pFilteredAttributeIds) + { + var filteredIdsCondition = new SqlCondition(); + var filteredIdChildren = AttributeUtil.getAllChildren(pFilteredAttributeIds); + pFilteredAttributeIds.concat(filteredIdChildren).forEach(function(id) + { + this.orPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", id); + }, filteredIdsCondition); + + attrCond.andSqlCondition(filteredIdsCondition); + } + + if (!pIncludeGroups) + attrCond.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP, "# != ?"); + + var attributes = db.array(db.COLUMN, attrCond.buildSql(attrSql)); + + return attributes; +} + +/** + * searches for possiblevalues for a atttribute and returns these. The values depend on the attributeType + * + * @param {String} pAttributeId the id of the attribute + * @param {Boolean} pAttributeType type of the attribute that is specified with pAttributeId; + * The type needs to be passed to the function for better performance + * (loading the type via attribute several times would be too slow) + * @param {Boolean} [pIncludeInactives=false] specifies if only active attributevalues or actives + inactives shall be returned, + * this is important when you want to search for attributevalues + * + * @return {Array} 2D-array with [ID, value] als elements if the given attributeType has possible items. if not null is returned + */ +AttributeUtil.getPossibleListValues = function (pAttributeId, pAttributeType, pIncludeInactives) +{ + var attributeId = pAttributeId; + var attrType = pAttributeType.trim(); + var onlyActives = (pIncludeInactives == undefined ? false : pIncludeInactives); + if (attrType == $AttributeTypes.COMBO.toString()) + { + var valueSql = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", attributeId) + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE); + + if (onlyActives) + valueSql.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_ACTIVE", "1"); + + valueSql = valueSql.buildSql("select AB_ATTRIBUTEID, ATTRIBUTE_NAME from AB_ATTRIBUTE", "1=2", "order by SORTING asc"); + var valueList = db.table(valueSql); + for (let i = 0; i < valueList.length; i++) + { + valueList[i][1] = translate.text(valueList[i][1]); + } + return valueList; + } + else if (attrType == $AttributeTypes.BOOLEAN.toString()) + { + return [ + ["1", translate.text("Yes")], + ["0", translate.text("No")] + ]; + } + else if (attrType == $AttributeTypes.KEYWORD.toString()) + { + var attrKeywordSelect = "select DROPDOWNDEFINITION from AB_ATTRIBUTE"; + attrKeywordSelect = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", attributeId) + .buildSql(attrKeywordSelect); + var attrKeyword = db.cell(attrKeywordSelect); + var keywords = KeywordData.getSimpleData(attrKeyword, null, onlyActives); + return keywords; + } + else if (attrType == $AttributeTypes.OBJECTSELECTION) + { + var [module, filter] = db.array(db.ROW, SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", attributeId) + .buildSql("select DROPDOWNDEFINITION, DROPDOWNFILTER from AB_ATTRIBUTE") + ); + var objects = []; + if (module) + { + var uid = "#UID"; + var title = "#CONTENTTITLE"; + var config = entities.createConfigForLoadingRows() + .entity(module) + .fields([uid, title]); + if (filter) + config.filter(filter); + var rows = entities.getRows(config); + for (let i = 0, l = rows.length; i < l; i++) + objects.push([rows[i][uid], rows[i][title]]) + } + return objects; + } + else + return null; +} + +/** + * returns the name of an attribute with all parent attribute names + * + * @param {String} pAttributeId the id of the attribute + * @param {Boolean} [pSimpleName=false] Use only the name of the attribute and not the names of the parents. + * @param {Boolean} [pTranslate=true] translate the name + * + * @return {String} the name of the attribute + */ +AttributeUtil.getFullAttributeName = function (pAttributeId, pSimpleName, pTranslate) +{ + if (pSimpleName === undefined) + pSimpleName = false; + if (pTranslate === undefined) + pTranslate = true; + + if (!pAttributeId) + return ""; + if (pSimpleName) + return AttributeUtil.getSimpleAttributeName(pAttributeId, pTranslate); + var attributeNames = []; + var attribute; + do { + attribute = db.array(db.ROW, SqlCondition.begin() + .andPrepare(["AB_ATTRIBUTE", "AB_ATTRIBUTEID", "ATTRIBUTE"], pAttributeId) + .buildSql("select ATTRIBUTE.ATTRIBUTE_NAME, PARENT1.ATTRIBUTE_NAME, PARENT2.ATTRIBUTE_NAME, PARENT2.ATTRIBUTE_PARENT_ID \n\ + from AB_ATTRIBUTE ATTRIBUTE \n\ + left join AB_ATTRIBUTE PARENT1 on ATTRIBUTE.ATTRIBUTE_PARENT_ID = PARENT1.AB_ATTRIBUTEID \n\ + left join AB_ATTRIBUTE PARENT2 on PARENT1.ATTRIBUTE_PARENT_ID = PARENT2.AB_ATTRIBUTEID") + ); + if (attribute.length > 0) + { + attributeNames.push(attribute[0]); + if (attribute[1]) + attributeNames.push(attribute[1]); + if (attribute[2]) + attributeNames.push(attribute[2]); + pAttributeId = attribute[3]; + } + else + pAttributeId = ""; + } while (pAttributeId); + + if (pTranslate) + { + for (let i = 0; i < attributeNames.length; i++) + { + attributeNames[i] = translate.text(attributeNames[i]); + } + } + return attributeNames.reverse().join(" / "); +} + +/** + * returns the name of an attribute + * + * @param {String} pAttributeId the id of the attribute + * @param {boolean} [pTranslate] if the name should be translated + * + * @return {String} the name of the attribute + */ +AttributeUtil.getSimpleAttributeName = function (pAttributeId, pTranslate) +{ + var attributeName = db.cell(SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId) + .buildSql("select ATTRIBUTE_NAME from AB_ATTRIBUTE") + ); + if (pTranslate) + attributeName = translate.text(attributeName); + return attributeName; +} + +/** + * returns the ids of all subordinated attributes of an attribute + * + * @param {String|Array} pAttributeIds the id(s) of the attribute(s) + * + * @result {String[]} array with the ids of every subordinated attribute + */ +AttributeUtil.getAllChildren = function (pAttributeIds) +{ + var childIds = []; + if (typeof(pAttributeIds) == "string") + pAttributeIds = [pAttributeIds]; + + while (pAttributeIds.length > 0) + { + pAttributeIds = db.array(db.COLUMN, SqlCondition.begin() + .andIn("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeIds) + .buildSql("select AB_ATTRIBUTEID from AB_ATTRIBUTE") + ); + if (pAttributeIds.length > 0) + childIds = childIds.concat(pAttributeIds); + } + return childIds; +} + +/** + * checks if an attribute has attribute relations + * + * @param {String} pAttributeId the id of the attribute + * + * @result {boolean} true if it has relations + */ +AttributeUtil.hasRelations = function (pAttributeId) +{ + if (!pAttributeId) + return false; + return db.cell(SqlCondition.begin() + .andPrepare("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId) + .buildSql( + "select count(*) from AB_ATTRIBUTERELATION", "1=2" //TODO: is there a way exists could be used? + ) + ) != "0"; +} + +/** + * returns the type of an attribute + * + * @param {String} pAttributeId the id of the attribute + * + * @result {String} attribute type + */ +AttributeUtil.getAttributeType = function (pAttributeId) +{ + if (!pAttributeId) + return ""; + var attrTypeSelect = "select ATTRIBUTE_TYPE from AB_ATTRIBUTE"; + attrTypeSelect = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId) + .buildSql(attrTypeSelect); + return db.cell(attrTypeSelect).trim(); +} + +AttributeUtil.hasAttributes = function (pObjectType) +{ + if (!pObjectType) + return false; + return db.cell(SqlCondition.begin() + .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_ACTIVE", "1") + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP, "# != ?") + .buildSql( + "select count(*) from AB_ATTRIBUTEUSAGE \n\ + join AB_ATTRIBUTE on AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID", "1=2" + ) + ) != "0"; //TODO: is there a way exists could be used? +} + +/*********************************************************************************************************************/ + +/** + * Provides functions for the work with attributeRelations, getting the value of an attributeRelation for an object. + * Don't instanciate this! + * + * @class + */ +function AttributeRelationUtils () {} + +/** + * gets the value of an attributeRelation for one dataset (e. g. a person) + * + * @param {String} pAttributeId attribute-id + * @param {String} pObjectRowId row-id of the dataset + * @param {String} [pObjectType=null] object-type + * @param {String} [pGetViewValue=false] if true the values are resolved and formatted + * @param {String} [pGetAttrname=false] if true the attributename is also returned + * + * @return {String|String[]|null} the value of the attribute or an array of attrname and value [attrname, value] (if pGetAttrname is true) + */ +AttributeRelationUtils.getAttribute = function (pAttributeId, pObjectRowId, pObjectType, pGetViewValue, pGetAttrname) +{ + var attrCond = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", pObjectRowId) + .andPrepare("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId); + if (pObjectType != null) + attrCond.andPrepare("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType); + + var defaultFields = [ + "AB_ATTRIBUTE.ATTRIBUTE_TYPE", + "AB_ATTRIBUTE.DROPDOWNDEFINITION", + "COMBOVAL.ATTRIBUTE_NAME" + ]; + + if (pGetAttrname) + defaultFields.push("AB_ATTRIBUTE.ATTRIBUTE_NAME"); + + var valueFields = AttributeTypeUtil.getAllDatabaseFields(); + var attributeSql = attrCond.buildSql("select " + defaultFields.join(", ") + ", " + valueFields.join(", ") + + " from AB_ATTRIBUTERELATION join AB_ATTRIBUTE on AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID" + + " left join AB_ATTRIBUTE COMBOVAL on " + $AttributeTypes.COMBO.databaseField + " = COMBOVAL.AB_ATTRIBUTEID"); + + var attributeValues = db.array(db.ROW, attributeSql); + if (!attributeValues.length) + return null; + + let value = attributeValues[AttributeTypeUtil.getTypeColumnIndex(attributeValues[0]) + defaultFields.length]; + if (pGetViewValue && attributeValues[1].trim() == $AttributeTypes.COMBO) + value = attributeValues[2]; + else if (pGetViewValue) + value = AttributeTypeUtil.getAttributeViewValue(attributeValues[0].trim(), value, attributeValues[1]); + + if (pGetAttrname) + value = [attributeValues[3], value]; + + return value; +} + +/** + * gets all attributes for a dataset + * + * @param {String} pObjectRowId object rowid + * @param {String} [pObjectType=null] object-type + * @param {String} [pUseAttributeIds=0] if 0 the full attribute names are returned + * if 1 the ids are used instead of the full attribute names + * if 2 the ids AND the full attribute name is returned + * @param {String} [pUseIdValues=false] if true the values are not resolved or formatted [attributeId, attributeName, value] + * + * @return {String[][]} two-dimensional array a row is [attributeId|attributeName, value] (or [attributeId, attributeName, value]) + */ +AttributeRelationUtils.getAllAttributes = function (pObjectRowId, pObjectType, pUseAttributeIds, pUseIdValues) +{ + var attrCond = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", pObjectRowId); + if (pObjectType != null) + attrCond.andPrepare("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType); + + var defaultFields = [ + "AB_ATTRIBUTE_ID", + "AB_ATTRIBUTE.ATTRIBUTE_TYPE", + "AB_ATTRIBUTE.DROPDOWNDEFINITION", + "COMBOVAL.ATTRIBUTE_NAME" + ]; + var valueFields = AttributeTypeUtil.getAllDatabaseFields(); + var attributeSql = attrCond.buildSql("select " + defaultFields.join(", ") + ", " + valueFields.join(", ") + + " from AB_ATTRIBUTERELATION join AB_ATTRIBUTE on AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID" + + " left join AB_ATTRIBUTE COMBOVAL on " + $AttributeTypes.COMBO.databaseField + " = COMBOVAL.AB_ATTRIBUTEID"); + + var attributeNameMap = {}; + var attributeValues = db.table(attributeSql).map(function (row) + { + let attribute = row[0]; + let attrname; + if (pUseAttributeIds == 0 || pUseAttributeIds == 2) + { + var tmpAttrname = ""; + if (!(attribute in attributeNameMap)) + attributeNameMap[attribute] = AttributeUtil.getFullAttributeName(attribute); + tmpAttrname = attributeNameMap[attribute]; + + // if mode 0, return only the name + if (pUseAttributeIds == 0) + attribute = tmpAttrname + + // if mode 2 return both + if (pUseAttributeIds == 2) + attrname = tmpAttrname + } + let value = row[AttributeTypeUtil.getTypeColumnIndex(row[1]) + defaultFields.length]; + if (!pUseIdValues && row[1].trim() == $AttributeTypes.COMBO) + value = row[3]; + else if (!pUseIdValues) + value = AttributeTypeUtil.getAttributeViewValue(row[1].trim(), value, row[2]); + + // add attrname only if id AND attrname is needed + var data = []; + + data.push(attribute); + + if (attrname) + data.push(attrname); + + data.push(value); + return data; + }); + + return attributeValues; +} + +/** + * gets the correct attribute value from a map with values depending on the attribute id + * + * @param {String} pAttributeId the attribute id + * @param {Object} pValueMap a map with the attribute values and the db fields as keys + * @param {Boolean} [pGetViewValue=false] if true, get the view value + * + * @return {String|null} the value of the attribute or null if the attribute doesn't exist + */ +AttributeRelationUtils.selectAttributeValue = function (pAttributeId, pValueMap, pGetViewValue) +{ + var sqlSelect = "select ATTRIBUTE_TYPE, DROPDOWNDEFINITION from AB_ATTRIBUTE"; + var type = db.array(db.ROW, SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeId) + .buildSql(sqlSelect) + ); + if (!type.length) + return null; + + type[0] = type[0].trim(); + var field = AttributeTypeUtil.getDatabaseField(type[0]); + var value = pValueMap[field]; + if (pGetViewValue && type[0] == $AttributeTypes.COMBO) + { + value = db.cell(SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.AB_ATTRIBUTEID", value) + .buildSql("select ATTRIBUTE_NAME from AB_ATTRIBUTE") + ); + } + else if (pGetViewValue) + value = AttributeTypeUtil.getAttributeViewValue(type[0], value, type[1]); + + return value; +} + +AttributeRelationUtils.getAttributes = function () +{ + //TODO: implement maybe +} + +/** + * sets the value of an attribute for one dataset (e. g. a person) + */ +AttributeRelationUtils.setAttribute = function () +{ + //TODO: implement +} + +/** + * adds rows for attributes with min_count > 0 + * + * @param {String} pObjectType the object type + * @param {String} pConsumer the name of the attribute relation consumer + */ +AttributeRelationUtils.presetMandatoryAttributes = function (pObjectType, pConsumer) +{ + var mandatoryAttributes = db.table( + SqlCondition.begin() + .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# <> ?") + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.GROUP, "# <> ?") + .and("ATTRIBUTE_ACTIVE = 1") + .and("MIN_COUNT > 0") + .buildSql("select AB_ATTRIBUTE_ID, MIN_COUNT from AB_ATTRIBUTEUSAGE " + + "join AB_ATTRIBUTE on AB_ATTRIBUTE_ID = AB_ATTRIBUTEID") + ); + mandatoryAttributes.forEach(function (usage) + { + //adding an attribute more than 20 times would be too much (having a min_count > 20 is very unlikely) + for (let i = 0; i < usage[1] && i < 20; i++) + neon.addRecord(pConsumer, { + "AB_ATTRIBUTE_ID" : usage[0] + }); + }); +} + +/** + * Checks if the count of the used attributes is valid and returns a message if it's not. + * + * @param {String} pRowId the row id of the entity + * @param {String} [pObjectType=null] the object type + * @param {String} pConsumerField the name of the attribute relation consumer + * + * @return {String} the validation message or an empty string if everything is ok + */ +AttributeRelationUtils.validateAttributeCount = function (pRowId, pObjectType, pConsumerField) +{ + var attributeChanges = {}; + var deletedRows = vars.get("$field." + pConsumerField + ".deletedRows"); + var changedRows = vars.get("$field." + pConsumerField + ".changedRows"); + var insertedRows = vars.get("$field." + pConsumerField + ".insertedRows"); + + if (deletedRows) + { + deletedRows.forEach(function (row) + { + this[row.UID] = ""; + }, attributeChanges); + } + + if (changedRows) + { + changedRows.forEach(function (row) + { + this[row.UID] = row.AB_ATTRIBUTE_ID; + }, attributeChanges); + } + + //get the current count of usages considering the changes + //this will merge the counts of attributeChanges and the already stored attributerelations + var countObj = AttributeRelationUtils.countAttributeRelations(pRowId, pObjectType, attributeChanges); + + if (insertedRows) //append the new rows + { + insertedRows.forEach(function (row) + { + this[row.AB_ATTRIBUTE_ID] = (this[row.AB_ATTRIBUTE_ID] || 0) + 1; + }, countObj); + } + var attributeCondition = SqlCondition.begin(); + AttributeUtil.getPossibleAttributes(pObjectType).forEach(function (attributeId) + { + this.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", attributeId); + }, attributeCondition); + + var usageCondition = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType) + .andSqlCondition(attributeCondition, "1=2"); + + //retrieve all min/max counts of the possible attributes + var minMaxCounts = db.table(usageCondition.buildSql( + "select AB_ATTRIBUTEID, ATTRIBUTE_NAME, MIN_COUNT, MAX_COUNT from AB_ATTRIBUTEUSAGE \ + join AB_ATTRIBUTE on AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID", "1=2" + )); + + var validationMessage = []; + minMaxCounts.forEach(function ([attributeId, name, minCount, maxCount]) + { + let count = this[attributeId] || 0; + //compares the actual usage with the min and max count and generates a message if the usage is too low or too high + if (count < minCount) + validationMessage.push(translate.withArguments("Attribute \"%0\" has to be used at least %1.", [name, _getTranslatedCount(minCount)])); + if (maxCount && count > maxCount) + validationMessage.push(translate.withArguments("Attribute \"%0\" can't be used more than %1.", [name, _getTranslatedCount(maxCount)])); + }, countObj); + + return validationMessage.join("\n"); + + //returns the correct count expression by choosing either singular (1 time) or plural (2 times) + function _getTranslatedCount (pCount) + { + if (pCount == 1) + return pCount + " " + translate.text("${COUNT_PREPOSITION_SINGLE}"); + return pCount + " " + translate.text("${COUNT_PREPOSITION_MULTIPLE}"); + } +} + +/** + * counts attribute relations + * + * @param {String} pRowId the row id of the entity + * @param {String} [pObjectType=null] the object type + * @param {Object} [pAttributeChanges=null] object containing changes and deletions of attributes + * structure = {attributeRelationId : new attributeId or "" when deleted} + * + * @return {Object} object with attribute ids and the count of the usage (without new rows) + */ +AttributeRelationUtils.countAttributeRelations = function (pRowId, pObjectType, pAttributeChanges) +{ + //use cases: + //complete new row ==> increase count by 1 for that attribute [this is done in another function] + //row removed ==> decrease count by 1 + //row edit: replace one attribute by another attribute ==> increase the new attribute count and decrease the old attribute count + //row edit: replace attribute with no new value ==> decrease count for the old attribute + //unchanged (already stored) row ==> increase count + var countObj = {}; + + var condition = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", pRowId) + .andPrepareIfSet("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType); + + var storedAttributeRelations = db.table(condition.buildSql( + "select AB_ATTRIBUTERELATIONID, AB_ATTRIBUTE_ID from AB_ATTRIBUTERELATION", + "1=2" + )); + + storedAttributeRelations.forEach(function ([storedAttrRelationId, storedAttributeId]) { + var currentAttributeId = storedAttributeId; + //merging the data that is stored in the DB and the provided changes + if (pAttributeChanges && storedAttrRelationId in pAttributeChanges) + currentAttributeId = pAttributeChanges[storedAttrRelationId]; + + // it doesn't matter if a row has been deleted or if the attribute has been set to "nothing" + if (currentAttributeId == "") + _decrCount(storedAttributeId); + else + { + _incrCount(currentAttributeId); + if (currentAttributeId != storedAttributeId) + _decrCount(storedAttributeId); + } + }); + + function _incrCount(pAttributeId) + { + if (countObj[pAttributeId]) + countObj[pAttributeId]++; + else + countObj[pAttributeId] = 1; + } + + function _decrCount(pAttributeId) + { + if (countObj[pAttributeId]) + countObj[pAttributeId]--; + else + countObj[pAttributeId] = 0; + } + + return countObj; +} + +/*********************************************************************************************************************/ + + +/** + * Object for the enumeration and management of all attribute types. + * This Object is only for the general definition of attribute types and for getting + * data about every type, anything that has to do with a specific attribute (= the function requires an attribute id) + * should be done in AttributeUtils. + * The required values and methods for each type are: + * + * toString = function that should return a unique name + * contentType = the value that is returned in the contentType process for the attribute + * databaseField = the database field that holds values of attributes with the type + * + * optional: + * getViewValue = function that gets the display value for a given value + * isGroup = if true, the attribute can have children + * getDropDownDefinitions = function that returns an array of possible values + * for DROPDOWNDEFINITION + * + * The display name is controlled by the keyword 'AttributeType' + */ +function $AttributeTypes () {} + +$AttributeTypes.TEXT = { + toString : function () {return "TEXT";}, + contentType : "TEXT", + databaseField : "CHAR_VALUE" +}; +$AttributeTypes.DATE = { + toString : function () {return "DATE";}, + contentType : "DATE", + databaseField : "DATE_VALUE", + getViewValue : function (pValue) + { + return datetime.toDate(pValue, translate.text("dd.MM.yyyy")); + } +}; +$AttributeTypes.NUMBER = { + toString : function () {return "NUMBER";}, + contentType : "NUMBER", + databaseField : "NUMBER_VALUE" +}; +$AttributeTypes.BOOLEAN = { + toString : function () {return "BOOLEAN";}, + contentType : "BOOLEAN", + databaseField : "INT_VALUE", + getViewValue : function (pValue) + { + return pValue == "1" ? translate.text("Yes") : translate.text("No"); + } +}; +$AttributeTypes.COMBO = { + toString : function () {return "COMBO";}, + contentType : "UNKNOWN", + databaseField : "ID_VALUE", + isGroup : true, + possibleChildren : ["COMBOVALUE"] +}; +$AttributeTypes.COMBOVALUE = { + toString : function () {return "COMBOVALUE";}, + contentType : null, + databaseField : null +}; +$AttributeTypes.GROUP = { + toString : function () {return "GROUP";}, + contentType : null, + databaseField : null, + isGroup : true +}; +$AttributeTypes.KEYWORD = { + toString : function () {return "KEYWORD";}, + contentType : "UNKNOWN", + databaseField : "ID_VALUE", + getViewValue : function (pValue, pKeyword) + { + return KeywordUtils.getViewValue(pKeyword, pValue); + }, + getDropDownDefinitions : function () + { + return KeywordUtils.getContainerNames().map(function (e) + { + return [e, e];//currently the first column is ID, second view value - which is the same because there is no ID for keyword-containers + }); + } +}; +$AttributeTypes.VOID = { + toString : function () {return "VOID";}, + contentType : null, + databaseField : null, + isGroup : true, + possibleChildren : ["VOID"] +}; +$AttributeTypes.MEMO = { + toString : function () {return "MEMO";}, + contentType : "LONG_TEXT", + databaseField : "CHAR_VALUE" +}; +$AttributeTypes.OBJECTSELECTION = { + toString : function () {return "OBJECTSELECTION";}, + contentType : "UNKNOWN", + databaseField : "ID_VALUE", + getViewValue : function (pValue, pModule) + { + if (pValue) + { + var title = "#CONTENTTITLE"; + var config = entities.createConfigForLoadingRows() + .entity(pModule) + .fields([title]) + .uid(pValue); + var rows = entities.getRow(config); + pValue = rows ? rows[title] : pValue; + } + return pValue; + }, + getDropDownDefinitions : function () + { + var dropDownList = []; + //TODO filter entities + project.getDataModels(project.DATAMODEL_KIND_ENTITY).forEach( + function (entity) + { + if (entity[1]) + dropDownList.push([entity[0], translate.text(entity[1])]); + } + ); + return dropDownList; + } +}; +$AttributeTypes.THEME = { + toString : function () {return "THEME";}, + contentType : "LONG_TEXT", + databaseField : "CHAR_VALUE", + isGroup : true, + possibleChildren : ["THEME"] +}; + +function AttributeTypeUtil () {} + +/** + * returns the required contentType for the given attribute type + * + * @param {String} pAttributeType the attribute type + * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) + * @return {String} the contentType for the attribute + */ +AttributeTypeUtil.getContentType = function (pAttributeType) +{ + if (pAttributeType) + { + pAttributeType = pAttributeType.trim(); + + if (pAttributeType in $AttributeTypes) + return $AttributeTypes[pAttributeType].contentType; + } + return null; +} + +/** + * returns if the type is a group type + * + * @param {String} pAttributeType the attribute type + * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) + * @return {Boolean} if the type is a group type + */ +AttributeTypeUtil.isGroupType = function (pAttributeType) +{ + if (pAttributeType) + { + pAttributeType = pAttributeType.trim(); + if (pAttributeType in $AttributeTypes) + return $AttributeTypes[pAttributeType].isGroup || false; + } + return null; +} + +/** + * returns the database field for the given attribute type that holds the value of the attribute + * + * @param {String} pAttributeType the attribute type + * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) + * @return {String} the database field for the attribute + */ +AttributeTypeUtil.getDatabaseField = function (pAttributeType) +{ + if (pAttributeType) + { + pAttributeType = pAttributeType.trim(); + if (pAttributeType in $AttributeTypes) + return $AttributeTypes[pAttributeType].databaseField; + } + return null; +} + +/** + * returns the possible children types for the given attribute type + * + * @param {String} pAttributeType the attribute type + * (use the values of the AttributeTypes object, e. g. AttributeTypes.TEXT) + * @return {String[]} the possible children types + */ +AttributeTypeUtil.getPossibleChildren = function (pAttributeType) +{ + if (pAttributeType) + { + pAttributeType = pAttributeType.trim(); + if (pAttributeType in $AttributeTypes) + return $AttributeTypes[pAttributeType].possibleChildren; + } + return null; +} + +AttributeTypeUtil.getAttributeViewValue = function (pAttributeType, pValue, pKeyword) +{ + if (pAttributeType in $AttributeTypes && $AttributeTypes[pAttributeType].getViewValue) + return $AttributeTypes[pAttributeType].getViewValue(pValue, pKeyword); + return pValue; +} + +AttributeTypeUtil._initTypeColumnData = function () +{ + var columns = []; + var typeColumnMap = {}; + for (let type in $AttributeTypes) + { + type = $AttributeTypes[type]; + if (type.databaseField) + { + var typeKey = type.toString(); + var colIndex = columns.indexOf(type.databaseField); + if (colIndex == -1) + { + colIndex = columns.length; + columns.push(type.databaseField); + } + typeColumnMap[typeKey] = colIndex; + } + } + this._allDBColumns = columns; + this._typeColumnMap = typeColumnMap; +} + +AttributeTypeUtil.getAllDatabaseFields = function () +{ + if (this._allDBColumns == undefined) + AttributeTypeUtil._initTypeColumnData(); + return this._allDBColumns; +} + +AttributeTypeUtil.getTypeColumnIndex = function (pAttributeType) +{ + if (this._typeColumnMap == undefined) + AttributeTypeUtil._initTypeColumnData(); + return this._typeColumnMap[pAttributeType.trim()]; +} + +/*********************************************************************************************************************/ + +/** + * Functions for AttributeUsages. + * Do not instanciate this! + */ +function AttributeUsageUtil () {} + +/** + * Creates AttributeUsages for all subordinate attributes of an attribute. + * This is required when an usage is added to a superordinate attribute. + * + * @param {String} pAttributeId the id of the superordinate attribute + * @param {String} pObjectType the context + */ +AttributeUsageUtil.insertChildrenUsages = function (pAttributeId, pObjectType) +{ + if (!pAttributeId) + return; + var table = "AB_ATTRIBUTEUSAGE"; + var columns = ["AB_ATTRIBUTEUSAGEID", "AB_ATTRIBUTE_ID", "OBJECT_TYPE"]; + var types = db.getColumnTypes(table, columns); + + var sqlSelect = "select AB_ATTRIBUTEID, " + + " (select count(*) from AB_ATTRIBUTEUSAGE where AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID and OBJECT_TYPE = '" + + pObjectType + "') = 0 from AB_ATTRIBUTE"; + + var inserts = []; + _addInserts(pAttributeId, pObjectType); + db.inserts(inserts); + + function _addInserts (pAttributeId, pObjectType) + { + var condition = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeId); + var attributes = db.table(condition.buildSql(sqlSelect)); + + attributes.forEach(function (row) + { + if (row[1] == "true") + { + let values = [util.getNewUUID(), row[0], pObjectType]; + inserts.push([table, columns, types, values]); + } + _addInserts(row[0], pObjectType); + }); + } +} + +/** + * Updates AttributeUsages for all subordinate attributes of an attribute. + * This is required when an usage of a superordinate attribute is changed. + * + * @param {String} pAttributeId the id of the superordinate attribute + * @param {String} pOldObjectType ye olde context + * @param {String} pNewObjectType the new context + */ +AttributeUsageUtil.updateChildrenUsages = function (pAttributeId, pOldObjectType, pNewObjectType) +{ + if (!pNewObjectType || !pAttributeId) + return; + + var table = "AB_ATTRIBUTEUSAGE"; + + var countSubQuery = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pNewObjectType) + .and("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID") + .buildSql("select count(*) from AB_ATTRIBUTEUSAGE"); + + var sqlSelect = SqlBuilder.begin() + .select(["AB_ATTRIBUTEID", "AB_ATTRIBUTEUSAGEID", countSubQuery]) + .from("AB_ATTRIBUTE") + .leftJoin("AB_ATTRIBUTEUSAGE", SqlCondition.begin() + .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pOldObjectType) + .and("AB_ATTRIBUTEID = AB_ATTRIBUTE_ID")); + + var updateCond = SqlCondition.begin(); + + //it is possible that the new objectType is already in a subordinate attribute + //and an update could cause a duplicate entry so one has to be deleted + var deleteCond = SqlCondition.begin(); + + _addUpdateIds(pAttributeId, pOldObjectType); + + if (updateCond.isSet()) + db.updateData(table, ["OBJECT_TYPE"], null, [pNewObjectType], updateCond.build("1=2")); + if (deleteCond.isSet()) + db.deleteData(table, deleteCond.build("1=2")); + + function _addUpdateIds (pAttributeId) + { + var condition = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeId); + var query = sqlSelect.where(condition); + var attributes = db.table(query.build()); + + attributes.forEach(function (row) + { + if (row[1] && row[2] != "0") + deleteCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]); + else if (row[1]) + updateCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]); + _addUpdateIds(row[0]); + }); + } +} + +/** + * Deletes AttributeUsages for all subordinate attributes of an attribute. + * This is required when an usage is removed from a superordinate attribute. + * + * @param {String} pAttributeId the id of the superordinate attribute + * @param {String} pObjectType the context + */ +AttributeUsageUtil.deleteChildrenUsages = function (pAttributeId, pObjectType) +{ + var table = "AB_ATTRIBUTEUSAGE"; + + var sqlSelect = "select AB_ATTRIBUTEID, AB_ATTRIBUTEUSAGEID " + + " from AB_ATTRIBUTE left join AB_ATTRIBUTEUSAGE on AB_ATTRIBUTEID = AB_ATTRIBUTE_ID and OBJECT_TYPE = '" + pObjectType + "'"; + + var deleteCond = SqlCondition.begin(); + _addDeleteIds(pAttributeId, pObjectType); + if (deleteCond.isSet()) + db.deleteData(table, deleteCond.build("1=2")); + + function _addDeleteIds (pAttributeId) + { + var condition = SqlCondition.begin() + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?") + .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeId); + var attributes = db.table(condition.buildSql(sqlSelect)); + + attributes.forEach(function (row) + { + if (row[1]) + deleteCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]) + _addDeleteIds(row[0]); + }); + } +} + +/** + * Deletes duplicate attribute usages. + * + * @param {String} [pAttributeId=null] attribute id, if omitted, all duplicates will be deleted + */ +AttributeUsageUtil.removeDuplicates = function (pAttributeId) +{ + var condition = SqlCondition.begin() + .and("exists (select AB_ATTRIBUTEUSAGEID from AB_ATTRIBUTEUSAGE AU where AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AU.AB_ATTRIBUTE_ID " + + "and AB_ATTRIBUTEUSAGE.OBJECT_TYPE = AU.OBJECT_TYPE and AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID != AU.AB_ATTRIBUTEUSAGEID)"); + if (pAttributeId) + condition.andPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", pAttributeId); + + var duplicates = db.table(condition.buildSql("select AB_ATTRIBUTEUSAGEID, AB_ATTRIBUTE_ID, OBJECT_TYPE from AB_ATTRIBUTEUSAGE")); + var usageObj = {}; + var deleteCond = SqlCondition.begin(); + + duplicates.forEach(function (row) + { + if (!(row[1] in this)) + this[row[1]] = {}; + if (row[2] in this[row[1]]) + deleteCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[0]); + this[row[1]][row[2]] = true; + }, usageObj); + if (deleteCond.isSet()) + db.deleteData("AB_ATTRIBUTEUSAGE", deleteCond.build("1=2")); } \ No newline at end of file -- GitLab