Skip to content
Snippets Groups Projects
Commit a6362298 authored by Sebastian Listl's avatar Sebastian Listl :speech_balloon:
Browse files

Merge branch '1044885_AttributeGroupMinMaxCount' into '2021.1.0'

[Projekt: Entwicklung - Neon][TicketNr.: 1044885][Attribute MIN/MAX Anzahl...

See merge request xrm/basic!856
parents f95c6144 3cde8e5e
No related branches found
No related tags found
No related merge requests found
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
<key>Event End</key> <key>Event End</key>
<value>Veranstaltungs Ende</value> <value>Veranstaltungs Ende</value>
</entry> </entry>
<entry>
<key>Attributes of attribute group \"%0\" have to be used at least %1.</key>
<value>Eigenschaften der Eigenschaftsgruppe \"%0\" müssen mindestens %1 verwendet werden.</value>
</entry>
<entry> <entry>
<key>Redirect needs a full Url with http/https</key> <key>Redirect needs a full Url with http/https</key>
<value>Für die Weiterleitung wird eine vollständige Url mit http/https benötigt</value> <value>Für die Weiterleitung wird eine vollständige Url mit http/https benötigt</value>
...@@ -67,6 +71,10 @@ ...@@ -67,6 +71,10 @@
<value>Objekt nicht gefunden <value>Objekt nicht gefunden
</value> </value>
</entry> </entry>
<entry>
<key>Attributes of attribute group \"%0\" can't be used more than %1.</key>
<value>Eigenschaften der Eigenschaftsgruppe \"%0\" dürfen maximal %1 verwendet werden.</value>
</entry>
<entry> <entry>
<key>Change responsible</key> <key>Change responsible</key>
<value>Verantwortlichen wechseln</value> <value>Verantwortlichen wechseln</value>
......
...@@ -78,6 +78,40 @@ AttributeUtil.getPossibleAttributes = function (pObjectType, pIncludeGroups, pFi ...@@ -78,6 +78,40 @@ AttributeUtil.getPossibleAttributes = function (pObjectType, pIncludeGroups, pFi
if (pAttributeCount) if (pAttributeCount)
{ {
// get parents of already linked attributes
var parentAttributes = AttributeUtil.getAllParents(Object.keys(pAttributeCount));
// get max usage from attribute parents
var parentAttributesMaxCount = [];
if (parentAttributes.length > 0)
{
// retrieve all max counts of the parent attributes
parentAttributesMaxCount = newSelect("AB_ATTRIBUTEID, MAX_COUNT")
.from("AB_ATTRIBUTEUSAGE")
.join("AB_ATTRIBUTE", "AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID")
.where("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", parentAttributes, SqlBuilder.IN())
.and("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType)
.table();
}
// count how many children of each parent are already linked
var parentChildUsageCount = {};
parentAttributes.forEach(function(attr) { parentChildUsageCount[attr] = (parentChildUsageCount[attr] || 0) + 1; });
// if actual usage >= max usage exclude parent and its children
for each (let parentAttr in parentAttributesMaxCount)
{
if (parentAttr[1] && parentChildUsageCount[parentAttr[0]] >= parentAttr[1])
{
// exclude this parent and its children
attrSelect.and(newWhere()
.and("AB_ATTRIBUTE.AB_ATTRIBUTEID", parentAttr[0], SqlBuilder.NOT_EQUAL())
.and("AB_ATTRIBUTE.AB_ATTRIBUTEID", AttributeUtil.getAllChildren(parentAttr[0]), SqlBuilder.NOT_IN())
);
}
}
for (let attributeId in pAttributeCount) for (let attributeId in pAttributeCount)
{ {
attrSelect.and(newWhere() attrSelect.and(newWhere()
...@@ -336,6 +370,37 @@ AttributeUtil.getAllChildren = function (pAttributeIds) ...@@ -336,6 +370,37 @@ AttributeUtil.getAllChildren = function (pAttributeIds)
return childIds; return childIds;
} }
/**
* Returns the ids of all superordinate attributes of an attribute.
*
* @param {String|Array} pAttributeIds <p>
* The id(s) of the attribute(s).<br>
* @return {String[]} <p>
* Array with the ids of every superordinate attribute.<br>
*/
AttributeUtil.getAllParents = function (pAttributeIds)
{
var parentIds = [];
if (typeof(pAttributeIds) == "string")
pAttributeIds = [pAttributeIds];
while (pAttributeIds.length > 0)
{
pAttributeIds = newSelect("ATTRIBUTE_PARENT_ID")
.from("AB_ATTRIBUTE")
.where("AB_ATTRIBUTE.AB_ATTRIBUTEID", pAttributeIds, SqlBuilder.IN())
.arrayColumn();
if (pAttributeIds.length > 0)
parentIds = parentIds.concat(pAttributeIds);
}
// remove empty array elements
parentIds = parentIds.filter(function (id) { return id != null && id != '' });
return parentIds;
}
/** /**
* Checks if an attribute has attribute relations. * Checks if an attribute has attribute relations.
* *
...@@ -718,7 +783,58 @@ AttributeRelationUtils.validateAttributeCount = function (pRowId, pObjectType, p ...@@ -718,7 +783,58 @@ AttributeRelationUtils.validateAttributeCount = function (pRowId, pObjectType, p
//retrieve all min/max counts of the possible attributes //retrieve all min/max counts of the possible attributes
minMaxCounts = minMaxCountsSelect.table(); minMaxCounts = minMaxCountsSelect.table();
} }
// attribute ids of current attribute changes (client) and attributerelations (database)
var currentAttributes = [];
for (let attribute in countObj) if (countObj[attribute] > 0) currentAttributes.push(attribute);
// get all parent attributes of current attributes
var currentParentAttributes = AttributeUtil.getAllParents(currentAttributes);
// get all possible parent attributes
var possibleParentAttributes = newSelect("distinct ATTRIBUTE_PARENT_ID")
.from("AB_ATTRIBUTE")
.where("AB_ATTRIBUTE.AB_ATTRIBUTEID", possibleAttributes, SqlBuilder.IN())
.arrayColumn();
// remove empty elements
possibleParentAttributes = possibleParentAttributes.filter(function (el) { return el != null && el != ""; });
// count current usages of parent attributes
var countParentObj = {};
currentParentAttributes.forEach(function(parentAttribute) { countParentObj[parentAttribute] = (countParentObj[parentAttribute] || 0) + 1; });
// add missing possible parent attributes with usage of 0 to countParentObj
var addAttr;
for each (let possibleParent in possibleParentAttributes)
{
addAttr = true;
for (let countParent in countParentObj)
{
if (possibleParent == countParent)
{
addAttr = false;
break;
}
}
if (addAttr) countParentObj[possibleParent] = 0;
}
var minMaxParentCounts = [];
if (possibleParentAttributes.length > 0)
{
var minMaxParentCountsSelect = newSelect("AB_ATTRIBUTEID, ATTRIBUTE_NAME, MIN_COUNT, MAX_COUNT")
.from("AB_ATTRIBUTEUSAGE")
.join("AB_ATTRIBUTE", "AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID")
.where("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", possibleParentAttributes, SqlBuilder.IN())
.and("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType);
// retrieve all min/max counts of parent attributes
minMaxParentCounts = minMaxParentCountsSelect.table();
}
var validationMessage = []; var validationMessage = [];
minMaxCounts.forEach(function ([attributeId, name, minCount, maxCount]) minMaxCounts.forEach(function ([attributeId, name, minCount, maxCount])
{ {
...@@ -730,6 +846,16 @@ AttributeRelationUtils.validateAttributeCount = function (pRowId, pObjectType, p ...@@ -730,6 +846,16 @@ AttributeRelationUtils.validateAttributeCount = function (pRowId, pObjectType, p
validationMessage.push(translate.withArguments("Attribute \"%0\" can't be used more than %1.", [name, _getTranslatedCount(maxCount)])); validationMessage.push(translate.withArguments("Attribute \"%0\" can't be used more than %1.", [name, _getTranslatedCount(maxCount)]));
}, countObj); }, countObj);
minMaxParentCounts.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("Attributes of attribute group \"%0\" have to be used at least %1.", [name, _getTranslatedCount(minCount)]));
if (maxCount && count > maxCount)
validationMessage.push(translate.withArguments("Attributes of attribute group \"%0\" can't be used more than %1.", [name, _getTranslatedCount(maxCount)]));
}, countParentObj);
return validationMessage.join("\n"); return validationMessage.join("\n");
//returns the correct count expression by choosing either singular (1 time) or plural (2 times) //returns the correct count expression by choosing either singular (1 time) or plural (2 times)
...@@ -2062,4 +2188,4 @@ AttributeRelation.prototype.deleteAttribute = function (pOmitValidation) ...@@ -2062,4 +2188,4 @@ AttributeRelation.prototype.deleteAttribute = function (pOmitValidation)
newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", this.attributeRelationId) newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", this.attributeRelationId)
.deleteData(); .deleteData();
return true; return true;
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment