Newer
Older
import("system.translate");
import("system.util");
import("Util_lib");
import("system.vars");
import("system.result");
import("system.db");
import("Attribute_lib");
import("Sql_lib");
var idvalues = vars.exists("$local.idvalues") ? vars.get("$local.idvalues") : null;
var getTree = !idvalues && vars.getString("$param.GetTree_param") == "true";
var loadFullAttributeName = vars.getString("$param.DisplaySimpleName_param") != "true";
var typeWhitelist, typeBlacklist;
if (vars.getString("$param.GetTheme_param") == "true")
typeWhitelist = [$AttributeTypes.THEME.toString()];
else
typeBlacklist = [$AttributeTypes.THEME.toString()];
var loadEmptyAttributes = vars.getString("$param.ShowEmpty_param") == "true";
var filteredAttributeIds = vars.exists("$param.FilteredAttributeIds_param") && vars.get("$param.FilteredAttributeIds_param");
if (filteredAttributeIds)
filteredAttributeIds = JSON.parse(filteredAttributeIds);
var objectRowId = vars.get("$param.ObjectRowId_param");
var objectType = vars.get("$param.ObjectType_param");
var attributeQueryMaker = {
defaultQueryFields : [
"AB_ATTRIBUTERELATIONID",
"AB_ATTRIBUTE.AB_ATTRIBUTEID",
"AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID",
"AB_ATTRIBUTE.ATTRIBUTE_TYPE",
"AB_ATTRIBUTE.ATTRIBUTE_NAME",
"AB_ATTRIBUTE.DROPDOWNDEFINITION",
"COMBOVAL.ATTRIBUTE_NAME",
"AB_ATTRIBUTERELATION.DATE_NEW",
"AB_ATTRIBUTERELATION.USER_NEW",
"AB_ATTRIBUTERELATION.DATE_EDIT",
"AB_ATTRIBUTERELATION.USER_EDIT",
"AB_ATTRIBUTE.DROPDOWNFILTER"
],
valueQueryFields : AttributeTypeUtil.getAllDatabaseFields(),
getConditionForIdValues : function (pIdValues, pLoadEmptyAttributes)
var idCondition = newWhere();
if (pLoadEmptyAttributes)
pIdValues.forEach(function (id)
{
var [attributeRelationId, attributeId] = JSON.parse(id);
idCondition.or("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", attributeRelationId);
idCondition.or(newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID is null")
.and("AB_ATTRIBUTE.AB_ATTRIBUTEID", attributeId));
});
}
else
idCondition.andIfSet("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", pIdValues, SqlBuilder.IN());
return idCondition;
},
getConditionForLinkedObject : function (pObjectType, pLoadEmptyAttributes, pAttributeIds, pTypeBlacklist, pTypeWhitelist)
var attributeCondition = newWhereIfSet("AB_ATTRIBUTE.ATTRIBUTE_TYPE", pTypeBlacklist, SqlBuilder.NOT_IN());
attributeCondition.andIfSet("AB_ATTRIBUTE.ATTRIBUTE_TYPE", pTypeWhitelist, SqlBuilder.IN());
if (pLoadEmptyAttributes)
attributeCondition.andIfSet("AB_ATTRIBUTE.AB_ATTRIBUTEID", AttributeUtil.getPossibleAttributes(pObjectType), SqlBuilder.IN());
if (pAttributeIds)
{
let attributeChildren = AttributeUtil.getAllChildren(pAttributeIds);
let attributeIdCondition = newWhere();
if (attributeChildren.length > 0)
{
attributeIdCondition.and("AB_ATTRIBUTE.AB_ATTRIBUTEID", attributeChildren, SqlBuilder.IN())
attributeIdCondition.and("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, SqlBuilder.NOT_EQUAL());
}
// return nothing if filteredAttributeIds is an empty array. (--> and 1=2)
if (!attributeIdCondition.hasCondition())
return null;
attributeCondition.and(attributeIdCondition);
}
return attributeCondition;
},
getAttributeQuery : function (pIdValues, pObjectRowId, pObjectType, pLoadEmptyAttributes, pAttributeIds, pTypeBlacklist, pTypeWhitelist)
{
var attributeQuery = newSelect(this.defaultQueryFields.concat(this.valueQueryFields))
.from("AB_ATTRIBUTE")
.orderBy("AB_ATTRIBUTE.SORTING asc");

Johannes Hörmann
committed
if (pIdValues)
attributeQuery.where(this.getConditionForIdValues(pIdValues, pLoadEmptyAttributes));
else if (pObjectRowId)

Johannes Hörmann
committed
{
let condition = this.getConditionForLinkedObject(pObjectType, pLoadEmptyAttributes, pAttributeIds, pTypeBlacklist, pTypeWhitelist);
if (condition === null)
return null;
attributeQuery.where(condition);

Johannes Hörmann
committed
}
var attributeRelationCond = newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID"); //condition for the joined values (for AttributeRelation)
if (!pIdValues && pObjectRowId)
{
attributeRelationCond.and("AB_ATTRIBUTERELATION.OBJECT_ROWID", pObjectRowId);
attributeRelationCond.andIfSet("AB_ATTRIBUTERELATION.OBJECT_TYPE", pObjectType);
}
if (pLoadEmptyAttributes)
attributeQuery.leftJoin("AB_ATTRIBUTERELATION", attributeRelationCond);
else
attributeQuery.join("AB_ATTRIBUTERELATION", attributeRelationCond);
attributeQuery.leftJoin("AB_ATTRIBUTE", "COMBOVAL.AB_ATTRIBUTEID = " + $AttributeTypes.COMBO.databaseField, "COMBOVAL");
return attributeQuery;
}
}
var attributeQuery = attributeQueryMaker.getAttributeQuery(idvalues, objectRowId, objectType, loadEmptyAttributes, filteredAttributeIds, typeBlacklist, typeWhitelist);
var attributeRelations = attributeQuery != null ? attributeQuery.table(false) : [];
//Builds an object containing the minimal counts of the attributes, this is required for
//checking if an attribute is used not often enough or just often enough. When this is the case,
//deletion of this attributeRelation will be prohibited.
var minCountInsurance = {
minCounts : {},
usageCounts : {},
loadMinCounts : function (pObjectType)
var minUsages = newSelect("AB_ATTRIBUTE_ID, MIN_COUNT")
.from("AB_ATTRIBUTEUSAGE")
.whereIfSet("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", Object.keys(this.usageCounts), SqlBuilder.IN())
.and("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pObjectType)
.table(true);
minUsages.forEach(function ([attributeId, minCount])
this.minCounts[attributeId] = minCount;
}, this);
},
incrUsageCount : function (pAttributeId)
{
if (pAttributeId in this.usageCounts)
this.usageCounts[pAttributeId]++;
else
this.usageCounts[pAttributeId] = 1;
},
attributeNotDeletable : function (pAttributeId)
{
return this.minCounts[pAttributeId] >= this.usageCounts[pAttributeId];
}
};
attributeRelations = attributeRelations.map(function (row)
{
var [attrRelId, attrId, attrParentId, attrType, attrName, dropDownDef, comboViewVal, dateNew, userNew, dateEdit, userEdit, dropDownFilter] = row;
attrName = translate.text(attrName);
attrType = attrType.trim();
if (!getTree && loadFullAttributeName && attrParentId)
{
let parentName = AttributeUtil.getFullAttributeName(attrParentId);
attrName = (parentName ? parentName + " / " : "") + attrName;
var value = row[AttributeTypeUtil.getTypeColumnIndex(attrType) + attributeQueryMaker.defaultQueryFields.length];
var viewValue;
if (attrType == $AttributeTypes.COMBO)
viewValue = translate.text(comboViewVal);
else
viewValue = AttributeTypeUtil.getAttributeViewValue(attrType, value, dropDownDef);
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
minCountInsurance.incrUsageCount(attrId);
//if loadEmptyAttributes is true, the id is contains the attributeRelation id and the attribute id.
//in case there is no attributeRelation, a random id is used
return [
loadEmptyAttributes ? JSON.stringify([attrRelId || util.getNewUUID(), attrId]) : attrRelId,
attrRelId,
attrParentId,
value,
viewValue,
attrId,
attrName,
"", //protected
attrType.trim(),
dateNew,
userNew,
dateEdit,
userEdit,
value,
viewValue,
dropDownDef,
dropDownFilter
];
});
minCountInsurance.loadMinCounts(objectType);
attributeRelations.forEach(function (attributeRelation)
{
var attrId = attributeRelation[4];
if (minCountInsurance.attributeNotDeletable(attrId))
attributeRelation[7] = "true";
});
attributeRelations = _buildAttributeTree(attributeRelations);
result.object(attributeRelations);
/*
* loads the parents for a tree
*/
function _buildAttributeTree (pAttrRelations)
{
//object of attribute ids to avoid duplicates (more than one attribute can have the same parent)
var attrCatalog = {};
var parentAttributes = [];
_fetchParentAttributes(pAttrRelations.map(function (row) {return row[2]}), parentAttributes);
return TreeUtils.sortArrayForTree(parentAttributes, 0, 2).concat(pAttrRelations);
/*
* recursive function that loads all superordinate attributes for the tree
*/
function _fetchParentAttributes (pAttributeIds, pParentAttributes)
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
var attributeCond = newSelect("AB_ATTRIBUTEID, ATTRIBUTE_PARENT_ID, ATTRIBUTE_NAME")
.from("AB_ATTRIBUTE")
.where()
var nextIds = [];
pAttributeIds.forEach(function (id)
{
if (!(id in this))
attributeCond.orIfSet("AB_ATTRIBUTE.AB_ATTRIBUTEID", id);
}, attrCatalog);
attributeCond.table(true)
.forEach(function ([attrId, parentId, attrName])
{
this[attrId] = true; //make entry in attrCatalog to avoid duplicates
if (parentId)
nextIds.push(parentId);
pParentAttributes.push([
attrId, "", parentId, "", "", "", //0-5
translate.text(attrName), //translate attribute name
"true", //7
"", "", "", "", "", "", "", "", "" //8-16
]);
}, attrCatalog);
if (nextIds.length)
_fetchParentAttributes(nextIds, pParentAttributes);