Written by

Question Bill Wang · Dec 22, 2016

Computed property

Hi,

I have 3 classes defined to model the team/team-member/employee relationship, where each employee can belong to multiple teams, each team can have multiple employees, and one and only one team member is a team leader:

Class User.Employee Extends %Persistent
{

Property Code As %String;

Property Name As %String;

Property BirthDate As %Date;

Property JoinDate As %Date;

}
Class User.Team Extends %Persistent
{

Property Code As %String;

Property Name As %String;

Relationship ChildMember As TeamMember [ Cardinality = children, Inverse = TeamParRef ];

}
Class User.TeamMember Extends %Persistent
{

Relationship TeamParRef As Team [ Cardinality = parent, Inverse = ChildMember, Required ];

Property MemberDR As Employee;

Property IsLeader As %Library.Boolean;

}

Question:

1. how can a computed property Leader be defined on the Team class to return its team leader?

2. how to ensure that only one member is a team leader?

I'm thinking about adding a trigger so that:

When the IsLeader property is set to true (was previously false) for a TeamMember object, then TeamMember.TeamParRef.Leader's  IsLeader is set to false.

But not too sure how to write the code to implement this.

Thanks,

Bill

Comments

Eduard Lebedyuk · Dec 23, 2016

Here's an idea on how to do it without triggers altogether.

1. Set IsLeader property only in case member is a leader. So its 1 or NULL.

2. Add unique index on (Team, IsLeader). Unique index can have any number of NULL records.

3. If you try to add more than one leader, you'll get an error:

ERROR #5808: Key not unique: Utils.TeamMember:IsLeaderIndex:^Utils.TeamMemberI("IsLeaderIndex"," 1"," 1") [%SaveData+14^Utils.TeamMember.1:USER]

Sample code:

Class Utils.TeamMember Extends %Persistent
{

Property Team As %String;

Property Member As %String;

Property IsLeader(VALUELIST = ",1");

Index IsLeaderIndex On (Team, IsLeader) [ Unique ];

/// do ##class(Utils.TeamMember).Test()
ClassMethod Test(AddTwoLeaders = {$$$YES})
{
    do ..%KillExtent()
    write $System.Status.GetErrorText(..Add(1, "Alice"))
    write $System.Status.GetErrorText(..Add(1, "Bob"))
    write $System.Status.GetErrorText(..Add(1, "Clover"))
    write $System.Status.GetErrorText(..Add(1, "Dave", 1))
    if AddTwoLeaders {
        write $System.Status.GetErrorText(..Add(1, "Helen", 1))
    }
}

ClassMethod Add(Team, Member, IsLeader = "")
{
    set obj = ..%New()
    set obj.Team = Team
    set obj.Member = Member
    set obj.IsLeader = IsLeader
    quit obj.%Save()
}

}
0