Update Parent Item when Relationships Tab is Changed

Good day all,

I have ItemType sm_ITA with a Relationship of sm_ITA_Assignment.  sm_ITA_Assignment (Assignments) is not related to another ItemType.  When an Assignment is added or deleted I need the sm_license_count property of the parent sm_ITA to be updated with the count of Assignments.  I have read several posts that seemed to be similar to this, but can't get anything to work.  I have methods that will change sm_license_count on a save if it doesn't match the Assignment count, but it will not allow me to add or delete Assignments.  I have a method that will make the update, but the sm_ITA has to be saved twice.    Thanks for any help that can be provided of what I am missing.

Will Update Value - sm_ITA Server Event onBeforeUpdate

- Doesn't allow changes, additions, or deletions to Assignments

Won't Update - sm_ITA Server Event onAfterUpdate

this.fetchRelationships("sm_ITA_Assignment");

Item RelationshipsItem = this.getRelationships("sm_ITA_Assignment");

string count = "" + RelationshipsItem.getItemCount();

this.setProperty("sm_license_count", count);

return this;

Item ITA ("edit") - onBeforeUpdate & onAfterUpdate - Returns an error of "An item with the same key has already been added."

Item ITA ("get") - onBeforeUpdate & onAfterUpdate - Does nothing

var ITA ("edit") - onBeforeUpdate & onAfterUpdate - Returns an error of "An item with the same key has already been added."

var ITA ("get") - onBeforeUpdate & onAfterUpdate - Does nothing

Innovator inn = this.getInnovator();

 int currentValue = Int32.Parse(this.getProperty("sm_license_count")); 

 Item relItm = inn.newItem("sm_ITA_Assignment", "get"); 

    relItm.setProperty("source_id", this.getID());

    relItm = relItm.apply();

int totalCount = relItm.getItemCount();  // Number of entries in sm_ITA_Assignements

string count = totalCount.ToString();

if(currentValue != totalCount)

{

    Item ITA = inn.newItem ("sm_ITA", "edit");  // have tried with get

        ITA.setID (this.getID());

        ITA.setProperty ("sm_license_count", count);

        ITA = ITA.apply();

 }

 return this;

  • Try this code attached to OnBeforeUpdate and OnBeforeAdd server events sm_ITA item type

    var addRels = this.node.SelectNodes("Relationships/Item[@type='sm_ITA_Assignment' and @action='add']");
    var delRels = this.node.SelectNodes("Relationships/Item[@type='sm_ITA_Assignment' and @action='delete']");
    string stcurlicenses = this.getProperty("sm_license_count");
    int curLicenses = string.IsNullOrEmpty(stcurlicenses) ? 0 : Int32.Parse(stcurlicenses);
    curLicenses = curLicenses + addRels.Count - delRels.Count;
    this.setProperty("sm_license_count", curLicenses.ToString());
    return this;

  • alaxala,

    Thank you for this code!  It works perfectly.

  • Hi Alaxala,

    thanks for this code sample! Haven´t seen this variant before. As far as I see, you addRels and delRels variable mainly contains relationships that has been recently added/deleted to the item and then recalculates the property based on the changes. That´s a smart solution. I have done something similar in the past but in much more complicated way.

    Do you also have a variant, that can catch all existing relationships this way? I want to analyze all of my relationship to find a few specific one with certain properties. Would be a big improvement if I could avoid a get query.

  • Unfortunately this is not possible. While changed relationships must be present in the "this" item node to make changes in the database, unchanged relationships are never present in. So, we can't avoid additional query.

  • Thanks for this additional information! Then I will stick to the classic query variant :-)