diff --git a/entity/Activity_entity/recordcontainers/db/onDBDelete.js b/entity/Activity_entity/recordcontainers/db/onDBDelete.js index 0b4ab0d79b9ffb3e4d312560e84718ab38e2aa88..a50bce1e44d7fa89abbb2605ae42e8ba3092fb9b 100644 --- a/entity/Activity_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Activity_entity/recordcontainers/db/onDBDelete.js @@ -1,3 +1,10 @@ +import("Context_lib"); +import("system.vars"); import("Sql_lib"); +import("Attribute_lib"); -newWhere("ACTIVITYLINK.ACTIVITY_ID", "$field.ACTIVITYID").deleteData(); \ No newline at end of file +newWhere("ACTIVITYLINK.ACTIVITY_ID", "$field.ACTIVITYID").deleteData(); + +new AttributeRelationQuery(vars.get("$field.ACTIVITYID"), null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); + \ No newline at end of file diff --git a/entity/Campaign_entity/recordcontainers/db/onDBDelete.js b/entity/Campaign_entity/recordcontainers/db/onDBDelete.js index 8c3db7d4887c574724a66fa0753364218a868324..4a47111a898384fe8d3ace4bca27a742ff1406a1 100644 --- a/entity/Campaign_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Campaign_entity/recordcontainers/db/onDBDelete.js @@ -1,6 +1,8 @@ +import("Context_lib"); import("system.db"); import("system.vars"); import("Sql_lib"); +import("Attribute_lib"); var currentId = vars.getString("$field.CAMPAIGNID"); @@ -19,4 +21,7 @@ if (currentId) }); db.deletes(toDelete); -} \ No newline at end of file +} + +new AttributeRelationQuery(currentId, null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); \ No newline at end of file diff --git a/entity/Contract_entity/Contract_entity.aod b/entity/Contract_entity/Contract_entity.aod index 03b96e6d6e75c962645b70676733e242c5743943..6608690641cf1da4201220b3c1421d43d5e17784 100644 --- a/entity/Contract_entity/Contract_entity.aod +++ b/entity/Contract_entity/Contract_entity.aod @@ -384,6 +384,7 @@ <fromClauseProcess>%aditoprj%/entity/Contract_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess> <conditionProcess>%aditoprj%/entity/Contract_entity/recordcontainers/db/conditionProcess.js</conditionProcess> <orderClauseProcess>%aditoprj%/entity/Contract_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess> + <onDBDelete>%aditoprj%/entity/Contract_entity/recordcontainers/db/onDBDelete.js</onDBDelete> <linkInformation> <linkInformation> <name>78925203-f1c5-4e7e-9424-1a23500c655d</name> diff --git a/entity/Contract_entity/recordcontainers/db/onDBDelete.js b/entity/Contract_entity/recordcontainers/db/onDBDelete.js new file mode 100644 index 0000000000000000000000000000000000000000..b9de11647b14efdc5b1651b28193052a84998710 --- /dev/null +++ b/entity/Contract_entity/recordcontainers/db/onDBDelete.js @@ -0,0 +1,6 @@ +import("system.vars"); +import("Context_lib"); +import("Attribute_lib"); + +new AttributeRelationQuery(vars.get("$field.CONTRACTID"), null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); \ No newline at end of file diff --git a/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js b/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js index a5b405bd03814af4c9bd758e5db8d0329200cf60..8ecca18f87ccd7a2c0c473cd8e3b3087d8a55342 100644 --- a/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js +++ b/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js @@ -1,10 +1,15 @@ +import("Context_lib"); import("Sql_lib"); import("system.vars"); import("system.db"); +import("Attribute_lib"); var binaryId = newSelect("ID", SqlUtils.getBinariesAlias()) .from("ASYS_BINARIES") .where("ASYS_BINARIES.ROW_ID", "$field.DOCUMENTTEMPLATEID") .cell(); if (binaryId) - db.deleteBinary(binaryId, SqlUtils.getBinariesAlias()); \ No newline at end of file + db.deleteBinary(binaryId, SqlUtils.getBinariesAlias()); + +new AttributeRelationQuery(vars.get("$field.DOCUMENTTEMPLATEID"), null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); \ No newline at end of file diff --git a/entity/Employee_entity/Employee_entity.aod b/entity/Employee_entity/Employee_entity.aod index dd20915b9f3a31053421416f69e276e664a507e2..ca9331355b1030eca6a28166522a70d87e1fd6a0 100644 --- a/entity/Employee_entity/Employee_entity.aod +++ b/entity/Employee_entity/Employee_entity.aod @@ -363,6 +363,7 @@ <name>jdito</name> <jDitoRecordAlias>Data_alias</jDitoRecordAlias> <isFilterable v="true" /> + <isRequireContainerFiltering v="true" /> <isSortable v="true" /> <contentProcess>%aditoprj%/entity/Employee_entity/recordcontainers/jdito/contentProcess.js</contentProcess> <onInsert>%aditoprj%/entity/Employee_entity/recordcontainers/jdito/onInsert.js</onInsert> diff --git a/entity/Employee_entity/recordcontainers/jdito/contentProcess.js b/entity/Employee_entity/recordcontainers/jdito/contentProcess.js index d5f8e7904ab14664284c2e53511be8a05485bc44..78bae2c27e11814875466e02b79032ce7acf4ef2 100644 --- a/entity/Employee_entity/recordcontainers/jdito/contentProcess.js +++ b/entity/Employee_entity/recordcontainers/jdito/contentProcess.js @@ -1,3 +1,4 @@ +import("system.logging"); import("Sql_lib"); import("system.db"); import("Attribute_lib"); @@ -7,7 +8,7 @@ import("system.tools"); import("Util_lib"); import("Contact_lib"); import("JditoFilter_lib"); -import("Employee_lib"); +import("Employee_lib");attrib var users; if (vars.exists("$local.idvalues") && vars.get("$local.idvalues")) @@ -43,7 +44,7 @@ users = users.map(function (user) var filter = vars.get("$local.filter"); //TODO: this is a workaround that filters the records manually, it should be possible to filter the users with a tools.* method -var filterFields = ["UID", "TITLE", "ISACTIVE", "FIRSTNAME", "LASTNAME", "EMAIL_ADDRESS", "", "DESCRIPTION", "CONTACT_ID", "DEPARTMENT", "", "", "ROLE_FILTER"]; +var filterFields = ["UID", "TITLE", "ISACTIVE", "FIRSTNAME", "LASTNAME", "EMAIL_ADDRESS", "", "DESCRIPTION", "CONTACT_ID", "DEPARTMENT", "", "", "ROLE_FILTER", "$$$LOOKUPFIELD$$$"]; var filterFns = { "ROLE_FILTER" : function (pRecordVal, pFilterVal, pOperator) { @@ -62,8 +63,20 @@ var filterFns = { default: return false; } + }, + "$$$LOOKUPFIELD$$$" : function (pRecordValue, pFilterValue, pOperator, pRow) + { + if (pOperator == "CONTAINS") + { + return pRow.some(function (fieldValue) + { + return (new RegExp(pFilterValue, "i")).test(fieldValue); + }); + } + return false; } }; +logging.log(JSON.stringify(filter, null, "\t")) users = JditoFilterUtils.filterRecords(filterFields, users, filter.filter, filterFns); users.forEach(function (user) {user[12] = "";}); //clean up the ROLE_FILTER field, we don't need it after filtering diff --git a/entity/Employee_entity/recordcontainers/jdito/onDelete.js b/entity/Employee_entity/recordcontainers/jdito/onDelete.js index ab759edc01f99d49bbc901935e5d0805b54cfe10..05394e349deb777b797db46b0925d4e47f831d67 100644 --- a/entity/Employee_entity/recordcontainers/jdito/onDelete.js +++ b/entity/Employee_entity/recordcontainers/jdito/onDelete.js @@ -1,3 +1,5 @@ +import("Context_lib"); +import("Attribute_lib"); import("system.neon"); import("system.vars"); import("system.tools"); @@ -5,4 +7,9 @@ import("Employee_lib"); //the current user should not delete himself if (EmployeeUtils.getCurrentUserName() != vars.get("$field.TITLE") && !EmployeeUtils.hasRelations(vars.get("$field.CONTACT_ID"))) - tools.deleteUser(vars.get("$field.TITLE")); \ No newline at end of file +{ + tools.deleteUser(vars.get("$field.TITLE")); + + AttributeRelationQuery(EmployeeUtils.sliceUserId(vars.get("$field.UID")), null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); +} \ No newline at end of file diff --git a/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js b/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js index 541e655e366ce0336ba70969c703bb67dcbe8d1b..7fc0b527fdceab78d1a224caf8c8229fcb5e03a4 100644 --- a/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js @@ -1,6 +1,8 @@ +import("Context_lib"); import("Sql_lib"); import("system.vars"); import("system.db"); +import("Attribute_lib"); var leadImportId = vars.getString("$field.LEADIMPORTID"); @@ -22,14 +24,16 @@ newSelect("LEADLOGID") if(leadImportId != "")//delete the connected importfields { - db.deleteData("IMPORTFIELD", newWhere("IMPORTFIELD.LEADIMPORT_ID", leadImportId).build()); - db.deleteData("LEADTEMP", newWhere("LEADTEMP.ROW_ID", leadImportId).build()); - db.deleteData("LEAD", newWhere("LEAD.LEADIMPORT_ID", leadImportId).build()); - db.deleteData("LEADLOG", newWhere("LEADLOG.LEADIMPORT_ID", leadImportId).build()); + newWhere("IMPORTFIELD.LEADIMPORT_ID", leadImportId).deleteData(); + newWhere("LEADTEMP.ROW_ID", leadImportId).deleteData(); + newWhere("LEAD.LEADIMPORT_ID", leadImportId).deleteData(); + newWhere("LEADLOG.LEADIMPORT_ID", leadImportId).deleteData(); } binMetadata.forEach(function(pMeta) { //delete the connected binData db.deleteBinary(pMeta.id, SqlUtils.getBinariesAlias()); }); - \ No newline at end of file + +new AttributeRelationQuery(leadImportId, null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); \ No newline at end of file diff --git a/entity/Offer_entity/recordcontainers/db/onDBDelete.js b/entity/Offer_entity/recordcontainers/db/onDBDelete.js index dbcf3083e10d4f8e2686a00a91f238d27e33c1f1..1e1ad63fd5ccb8c6fa1a56dc2c313247474d34fb 100644 --- a/entity/Offer_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Offer_entity/recordcontainers/db/onDBDelete.js @@ -1,9 +1,14 @@ +import("Context_lib"); import("Workflow_lib"); import("Sql_lib"); import("system.vars"); +import("Attribute_lib"); newWhere("OFFERITEM.OFFER_ID", "$field.OFFERID") .deleteData(); +new AttributeRelationQuery(vars.get("$field.OFFERID"), null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); + WorkflowStarter.deleted({sum : Number(vars.get("$field.TotalGross")), status : vars.get("$field.STATUS")}); WorkflowSignalSender.deleted(); \ No newline at end of file diff --git a/entity/Order_entity/recordcontainers/db/onDBDelete.js b/entity/Order_entity/recordcontainers/db/onDBDelete.js index 78799f19269dee9332c2bf22d10e8247b889c132..9d21e312247e4be629915bcebe2e0f1e489457a3 100644 --- a/entity/Order_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Order_entity/recordcontainers/db/onDBDelete.js @@ -1,3 +1,9 @@ +import("Context_lib"); +import("system.vars"); import("Sql_lib"); +import("Attribute_lib"); -newWhere("SALESORDERITEM.SALESORDER_ID", "$field.SALESORDERID").deleteData(); \ No newline at end of file +newWhere("SALESORDERITEM.SALESORDER_ID", "$field.SALESORDERID").deleteData(); + +new AttributeRelationQuery(vars.get("$field.SALESORDERID"), null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); \ No newline at end of file diff --git a/entity/Organisation_entity/recordcontainers/db/onDBDelete.js b/entity/Organisation_entity/recordcontainers/db/onDBDelete.js index b40a056ac00e3fec5cff3d5b2f52df957c0a5584..8ee5af70d3b5bff479cd64e4e16db0fb2542d6ee 100644 --- a/entity/Organisation_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Organisation_entity/recordcontainers/db/onDBDelete.js @@ -1,10 +1,15 @@ +import("Context_lib"); import("Workflow_lib"); import("system.vars"); import("DuplicateScanner_lib"); +import("Attribute_lib"); // TODO: enable when duplicate-module is finalized let contactId = vars.get("$field.CONTACTID"); DuplicateScannerUtils.DeleteCachedDuplicate(contactId); +new AttributeRelationQuery(contactId, null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); + //WorkflowStarter.deleted(); //WorkflowSignalSender.deleted(); \ No newline at end of file diff --git a/entity/Person_entity/recordcontainers/db/onDBDelete.js b/entity/Person_entity/recordcontainers/db/onDBDelete.js index 961f7f520c417062146000eefd6a1f684683568d..85ede0d4e7b00eff43445e5906725a325ef1cedd 100644 --- a/entity/Person_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Person_entity/recordcontainers/db/onDBDelete.js @@ -1,3 +1,5 @@ +import("Context_lib"); +import("Attribute_lib"); import("Workflow_lib"); import("system.vars"); import("DuplicateScanner_lib"); @@ -5,5 +7,8 @@ import("DuplicateScanner_lib"); let contactId = vars.get("$field.CONTACTID"); DuplicateScannerUtils.DeleteCachedDuplicate(contactId); +new AttributeRelationQuery(contactId, null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); + //WorkflowStarter.deleted(); //WorkflowSignalSender.deleted(); \ No newline at end of file diff --git a/entity/Product_entity/recordcontainers/db/onDBDelete.js b/entity/Product_entity/recordcontainers/db/onDBDelete.js index 9fe9dbd2473b9f99b08619e247c6f4ab22acabaa..0ab63616f119ad19dc5a9318f42cfd7eab6524d6 100644 --- a/entity/Product_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Product_entity/recordcontainers/db/onDBDelete.js @@ -1,4 +1,6 @@ +import("Context_lib"); import("Sql_lib"); +import("Attribute_lib"); newWhereIfSet("PROD2PROD.DEST_ID", "$field.PRODUCTID") .deleteData(); @@ -10,4 +12,7 @@ newWhereIfSet("PRODUCTPRICE.PRODUCT_ID", "$field.PRODUCTID") .deleteData(); newWhereIfSet("STOCK.PRODUCT_ID", "$field.PRODUCTID") - .deleteData(); \ No newline at end of file + .deleteData(); + +new AttributeRelationQuery(productId, null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); \ No newline at end of file diff --git a/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js b/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js index 050a3e6b0da0d33875135bd9c1c8f5cb40503737..bdeb6b5340b8ac62e3f9330b5a14367ee687593e 100644 --- a/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js +++ b/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js @@ -3,6 +3,7 @@ import("Context_lib"); import("system.db"); import("system.vars"); import("Sql_lib"); +import("Attribute_lib"); var currentId = vars.getString("$field.SALESPROJECTID"); @@ -42,4 +43,7 @@ if (currentId) // TODO: auch Dokumente, Aktivitäten, Aufgaben, Zeiterfassungen löschen? } +new AttributeRelationQuery(currentId, null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); + WorkflowStarter.deleted(); \ No newline at end of file diff --git a/entity/SupportTicket_entity/SupportTicket_entity.aod b/entity/SupportTicket_entity/SupportTicket_entity.aod index 6a47734f54f374d06e5eb8981c3842ff51f00751..90581faffeffc21f276ddf139aee0e0d3f57266f 100644 --- a/entity/SupportTicket_entity/SupportTicket_entity.aod +++ b/entity/SupportTicket_entity/SupportTicket_entity.aod @@ -405,6 +405,7 @@ <conditionProcess>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/conditionProcess.js</conditionProcess> <orderClauseProcess>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess> <onDBInsert>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/onDBInsert.js</onDBInsert> + <onDBDelete>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js</onDBDelete> <linkInformation> <linkInformation> <name>512c662b-33f6-4491-bd24-a8b862f2de84</name> diff --git a/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js b/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js index 03335cb841ab9bc3075360dc349f3fcd6338eeec..607773386a086a99f8815eeace21e53f453fb85d 100644 --- a/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js +++ b/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js @@ -1,3 +1,9 @@ +import("Context_lib"); +import("system.vars"); +import("Attribute_lib"); import("Sql_lib"); -newWhereIfSet("TASKLINK.TASK_ID", "$field.TASK_TASKID").deleteData(); \ No newline at end of file +newWhereIfSet("TASKLINK.TASK_ID", "$field.TASK_TASKID").deleteData(); + +new AttributeRelationQuery(vars.get("$field.TICKETID"), null, ContextUtils.getCurrentContextId()) + .deleteAllAttributes(); \ No newline at end of file diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js index 04bbeaf9cff3ad1af1ae13cb7e8890acd31df2c4..c38845e81d7c4b72931a90084071a9e5dda027a5 100644 --- a/process/Attribute_lib/process.js +++ b/process/Attribute_lib/process.js @@ -1301,7 +1301,7 @@ AttributeRelationQuery.prototype.includeDisplayValue = function () /** * Executes the query and returns the result, depending on the properties of the AttributeRelationQuery object. * - * @return {Object[]} Array of objects. By default, the objects contain the properties {attributeId, value, attributeRelationId, attributeName, attributeType}. + * @return {AttributeRelation[]} Array of objects. By default, the objects contain the properties {attributeId, value, attributeRelationId, attributeName, attributeType}. * If includeDisplayValue is true, the object also contains the property 'displayValue' and if includeFullAttributeName is true, there is also the property * 'fullAttributeName'. */ @@ -1313,7 +1313,9 @@ AttributeRelationQuery.prototype.getAttributes = function () "AB_ATTRIBUTE.ATTRIBUTE_NAME", "COMBOVAL.ATTRIBUTE_NAME", "AB_ATTRIBUTE.AB_ATTRIBUTEID", - "AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID" + "AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", + "AB_ATTRIBUTERELATION.OBJECT_ROWID", + "AB_ATTRIBUTERELATION.OBJECT_TYPE" ]; var valueFields = AttributeTypeUtil.getAllDatabaseFields(); @@ -1328,13 +1330,7 @@ AttributeRelationQuery.prototype.getAttributes = function () var mappingFn = function (row) { - var attrObj = { - attributeId : row[4], - value : row[AttributeTypeUtil.getTypeColumnIndex(row[0]) + defaultFields.length], - attributeRelationId : row[5], - attributeName : row[2], - attributeType : row[0] - }; + var attrObj = new AttributeRelation(row[5], row[4], row[AttributeTypeUtil.getTypeColumnIndex(row[0]) + defaultFields.length], row[2], row[0], row[6], row[7]); if (this._includeDisplayValue) { @@ -1355,7 +1351,7 @@ AttributeRelationQuery.prototype.getAttributes = function () } /** - * @return {Object} + * @return {AttributeRelation} */ AttributeRelationQuery.prototype.getSingleAttribute = function () { @@ -1442,13 +1438,98 @@ AttributeRelationQuery.prototype.insertAttribute = function (pValue, pOmitValida /** * deletes all attribute relations with the given rowId and objectType + * + * @return {Number} count of deleted rows */ AttributeRelationQuery.prototype.deleteAllAttributes = function () { if (!this._rowId) throw new Error("AttributeRelationQuery: Row id is required for delete"); - newWhere("AB_ATTRIBUTERELATION.OBJECT_ROWID", this._rowId) - .andIfSet("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", this._objectType) + return newWhere("AB_ATTRIBUTERELATION.OBJECT_ROWID", this._rowId) + .andIfSet("AB_ATTRIBUTERELATION.OBJECT_TYPE", this._objectType) .deleteData(); +} + +/** + * Object representing one attribute relation in the database. Don't use this constructor in you own code! + * Instances of this should only be created by functions in this library. + * + * @param {String} pAttributeRelationId attribute relation id + * @param {String} pAttributeId attribute id + * @param {String} pValue value of the attribute + * @param {String} pAttributeName name of the attribute + * @param {String} pAttributeType type of the attribute + * @param {String} pObjectRowId rowId of the linked object + * @param {String} pObjectType context of the linked object + */ +function AttributeRelation (pAttributeRelationId, pAttributeId, pValue, pAttributeName, pAttributeType, pObjectRowId, pObjectType) +{ + if (!pAttributeRelationId) + throw new Error("AttributeRelation: pAttributeRelationId must be provided"); + + this.attributeRelationId = pAttributeRelationId; + this.attributeId = pAttributeId; + this.value = pValue; + this.attributeName = pAttributeName; + this.attributeType = pAttributeType; + this.objectRowId = pObjectRowId; + this.objectType = pObjectType; + this.displayValue = undefined; + this.fullAttributeName = undefined; +} + +/** + * updates the value of the attribute in the database + * + * @param {String} pValue the new value of the attribute relation + * @return {Boolean} currently the function always returns true (if some kind of validation is implemented in the future, + * it will return false if the validation fails) + */ +AttributeRelation.prototype.updateAttribute = function (pValue) +{ + if (pValue == undefined || pValue == "") + throw new Error("AttributeRelation: no value provided for update"); + + var attrData = { + "DATE_EDIT" : vars.get("$sys.date"), + "USER_EDIT" : vars.get("$sys.user") + }; + + var valueField = AttributeTypeUtil.getDatabaseField(this.attributeType); + if (valueField) + attrData[valueField] = pValue; + + newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", this.attributeRelationId) + .updateFields(attrData); + return true; +} + +/** + * deletes the attribute relation from the database + * + * @param {Boolean} [pOmitValidation=false] if set to true, the function won't check if the min count prohibits the deletion + * @retun {Boolean} true if it was deleted and false if the min count doesn't allow the deletion + */ +AttributeRelation.prototype.deleteAttribute = function (pOmitValidation) +{ + if (!pOmitValidation) + { + var minCount = newSelect("MIN_COUNT") + .from("AB_ATTRIBUTEUSAGE") + .where("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", this.attributeId) + .and("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", this.objectType) + .cell(); + + if (minCount && minCount != 0) + { + let timesUsed = new AttributeRelationQuery(this.objectRowId, this.attributeId, this.objectType).getAttributeCount(); + if (timesUsed <= minCount) + return false; + } + } + + newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", this.attributeRelationId) + .deleteData(); + return true; } \ No newline at end of file