﻿<?xml version="1.0"?>
<AlvaoApplication xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ModelVersion="1">
  <Applications>
    <Application id="51">
      <Name>Update Superior Group</Name>
      <Description>This app automatically fills a particular user group with all superiors of users from a particular organization. The user group can then be used for instance in a definition of a custom field of the type User.</Description>
      <Scripts>
        <Script id="132">
          <Name>UpdateSuperiorGroupPeriodic</Name>
          <Code>using System;
using System.Data;
using Microsoft.Data.SqlClient;
using Alvao.Apps.API;
using Dapper;
using System.Collections.Generic;
using Alvao.Context;
using System.Linq;

public class UpdateSuperiorGroupPeriodic : IPeriodicAction
{
    public string Name
    {
        get =&gt; "UpdateSuperiorGroupPeriodic";
        set { }
    }

    public void OnPeriod(SqlConnection con)
    {
        if (Settings.UPDATE_HOUR != DateTime.Now.Hour) return;

        var org = Alvao.API.SD.Organization.GetByName(Settings.ORGANIZATION_NAME);

        if (org == null)
        {
            throw new Exception("Unable to find the specified organization.");
        }

        var group = Alvao.API.Common.Role.GetByName(Settings.SUPERIOR_GROUP_NAME);

        if (group == null)
        {
            throw new Exception("Unable to find the specified group.");
        }

        var groupMembers = Alvao.API.Common.Role.GetDirectMemberUsers(group.iRoleId);

        using (var scope = AlvaoContext.GetConnectionScope())
        {
            try
            {
                var managersIds = scope.Connection.Query&lt;int&gt;(@"
                    select distinct ManagerPersonId from PersonManager pm
                        join tPerson p on p.iPersonId = pm.EmployeePersonId
                    where p.liAccountId = @organizationId and p.bHidden = 0 and p.dPersonRemoved is null", new { organizationId = org.iAccountId }, scope.LegacyTransaction).ToList();

                var idsToAdd = managersIds.Where(x =&gt; groupMembers.All(y =&gt; y.iPersonId != x)).ToList();
                var idsToRemove = groupMembers.Select(x =&gt; x.iPersonId).Where(x =&gt; managersIds.All(y =&gt; x != y)).ToList();

                foreach (int id in idsToAdd)
                {
                    Alvao.API.Common.Person.AddToGroup(id, new List&lt;int&gt;() { group.iRoleId });
                }

                foreach (int id in idsToRemove)
                {
                    Alvao.API.Common.Person.RemoveFromGroup(id, group.iRoleId);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
    }
}
</Code>
          <IsLibCode>false</IsLibCode>
        </Script>
        <Script id="133">
          <Name>Settings</Name>
          <Code>public static class Settings
{
    public const int UPDATE_HOUR = 2;
    public const string ORGANIZATION_NAME = "";
    public const string SUPERIOR_GROUP_NAME = "";
}</Code>
          <IsLibCode>true</IsLibCode>
        </Script>
      </Scripts>
    </Application>
  </Applications>
</AlvaoApplication>