<?xml version="1.0" encoding="utf-8"?>
<AlvaoApplication xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ModelVersion="1">
  <Applications>
    <Application id="87">
      <Name>Object Url Commands</Name>
      <Description>Allows setting dynamic custom commands on AM objects, up to 3 per one object.
Command definition and target is defined by Advanced Settings &gt; AM.ObjectUrlDefinitions.</Description>
      <UniqueId>5d76a16e-66fd-4dea-8b21-e639f5b6ad08</UniqueId>
      <Version>2</Version>
      <AdvancedSettings>
        <Setting>
          <Name>AM.ObjectUrlDefinitions</Name>
          <Value />
        </Setting>
      </AdvancedSettings>
      <Scripts>
        <Script id="1694">
          <Name>FirstObjectURLCommand</Name>
          <Code>using System;
using System.Data;
using Alvao.Global;
using Alvao.API.Common;
using Alvao.API.Common.Model.CustomApps;
using Alvao.Apps.API;
using Alvao.Context;
using Dapper;

public class FirstObjectURLCommand : IEntityCommand 
{
    public string Id {get; set;}
    public Entity Entity {get; set;}
    private int scriptNo = 0;

    public FirstObjectURLCommand()
    {
        Id = "FirstObjectURLCommand";
        Entity = Entity.Object;;
    }

    public EntityCommandShowResult Show(int entityId, int personId) 
    {   
        if (!Helpers.IsMemberOfAssetManagers(personId))
            return new EntityCommandShowResult(false, String.Empty, String.Empty, 1);

        CommandConfig command = Helpers.GetCommand(entityId, scriptNo);

        if (command != null)
            return new EntityCommandShowResult(true, command.Name, command.Icon, command.Position);
        else
            return new EntityCommandShowResult(false, String.Empty, String.Empty, 1);
    }

    public CommandResult Run(int entityId, int personId)
    {
        CommandConfig command = Helpers.GetCommand(entityId, scriptNo);
        Helpers.GetFinalUrl(command, entityId);
        return new CommandResult(MessageType.None, string.Empty, command.Url);
    }
}</Code>
          <IsLibCode>false</IsLibCode>
          <Codesign>TciGOjHDHY1sdCN/p5b9BJiRFBAYueXjIM8K4vnE247HkUJNpNn9M+T1ig5OXyJo+A2EyuijlmQNGsVrfT+RMDdl+/Z1OaCmJRp61G0KnZQDAiNVaY3CwazNzvKfKNQV+lCZ2YsBz/Dzhr6wB9fct5ggLv/m3+AkJX+uDf1tVDKCgxQxku9QC7Ne8f34WTHgz8f6Dc72iR1XsvscV3rvcm7y6G4Fgaavian1nrhJuGa+TzQdHinXW2jAs3ngsZCP0OOw19W5eBJBc7MUo05ntVqmpl2QHYexlENrdSXY//WoLVluB3pquBQzchmOcgXdw73RfnSzeDM6Uht748FwtA==</Codesign>
        </Script>
        <Script id="1695">
          <Name>Helpers</Name>
          <Code>using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Alvao.Context;
using Dapper;
using System.Text.RegularExpressions;
using System.Text;
using Alvao.API.Common;

public static class Helpers
{

    public static CommandConfig GetCommand(int entityId, int scriptNo)
    {   
        if (String.IsNullOrEmpty(Alvao.API.Common.DbProperty.AM_ObjectUrlDefinitions))
            return null;

        var settings = JObject.Parse(Alvao.API.Common.DbProperty.AM_ObjectUrlDefinitions);
        var definitions = settings[""];
        List&lt;CommandConfig&gt; commands = new List&lt;CommandConfig&gt;();
        
        ObjectProperties currentObject = Helpers.GetObjectProperties(entityId) ??  null;
        if (currentObject == null)
            return null;

        foreach(var definition in definitions)
        {
            bool isRelevant = false;
            bool onAllComputerTypes = !(definition["onAllComputerTypes"] == null) &amp;&amp; definition["onAllComputerTypes"].ToObject&lt;bool&gt;(); 

            if (onAllComputerTypes &amp;&amp; currentObject.IsComputer)
                isRelevant = true;
            else if (definition["onObjectTypes"] != null)
            {
                foreach(var onObjectType in definition["onObjectTypes"])
                {
                    if (onObjectType.ToObject&lt;string&gt;() == currentObject.ObjectType)
                    {
                        isRelevant = true;
                        break;
                    }
                }
            }      
            else if (!onAllComputerTypes &amp;&amp; definition["onObjectTypes"] == null)
                isRelevant = true;      
            if (isRelevant)
                commands.Add(new CommandConfig(definition["name"].ToObject&lt;string&gt;(), definition["url"].ToObject&lt;string&gt;(), definition["position"].ToObject&lt;int&gt;(), definition["icon"].ToObject&lt;string&gt;()));
        }
        if (commands.Count == 0 || commands.Count &lt;= scriptNo)
            return null;
        else   
            return commands[scriptNo];
    }

    public static bool IsMemberOfAssetManagers(int personId)
    {
        return Alvao.API.Common.PersonRights.HaveGlobalRole(personId, PersonRights.GlobalRoles.AssetAdministrators | PersonRights.GlobalRoles.AssetManagers , false);
    }

    public static ObjectProperties GetObjectProperties(int entityId)
    {
        using (var scope = AlvaoContext.GetConnectionScope())
        {
            return scope.Connection.QueryFirstOrDefault&lt;ObjectProperties&gt;(@"
                SELECT
                    vClass.txtClass ObjectType,
                    tblClass.bComputer IsComputer
                FROM tblNode
                LEFT JOIN vClass ON tblNode.lintClassId = vClass.intClassId
                LEFT JOIN tblClass ON tblNode.lintClassId = tblClass.intClassId
                WHERE 
                    tblNode.IsTemplate = 0
                    AND intNodeId = @nodeId
            " , new { @nodeId = entityId});
        }
    }

    public static void GetFinalUrl(CommandConfig command, int entityId)
    {
        Regex expr = new Regex(@"\[\$([^.]+)([.^]+)(.*?)\$\]");

        foreach(Match match in expr.Matches(command.Url))
        {
            command.Url = command.Url.Replace(match.ToString(), GetDbValue(match, entityId));
        }
    }
    
    private static string GetDbValue(Match placeholder, int entityId)
    {
        string value;
        using (var scope = AlvaoContext.GetConnectionScope())
        {
            StringBuilder sqlQuery = new StringBuilder($@"SELECT [{placeholder.Groups[3]}] FROM {placeholder.Groups[1]} WHERE ");
            switch (placeholder.Groups[1].ToString())
            {
                // TODO: make it more dynamic
                case "NodeCust":
                    sqlQuery.Append($@"NodeId = @nodeId");
                    break;
                case "tblNode":
                    sqlQuery.Append($@"intNodeId = @nodeId");
                    break;
            }
            value = scope.Connection.QueryFirstOrDefault&lt;string&gt;(sqlQuery.ToString(), new { @nodeId = entityId });
        }   
        return value;
    }
    
}

public class ObjectProperties
{
    public string ObjectType {get;set;}
    public bool IsComputer {get;set;}
}

public class CommandConfig
{
    public string Name {get;}
    public string Url {get;set;}
    public int Position {get;}
    public string Icon {get;}

    public CommandConfig(string name, string url, int position, string icon)
    {
        Name = name;
        Url = url;
        Position = position;
        Icon = icon;
    }
}</Code>
          <IsLibCode>true</IsLibCode>
          <Codesign>fp/xlJQsRUvZzv6c2NPsPsEGFOFNd4+n++Q4qnhrqu1Hn7jSunRFOugcy66zo9ZdrV95UdSZbPkNaYZDdiACZsIsSikSD9C16Yf3tl4lH36kugwMsmoUyIZ0MlSt+68M696U7FfogTzYDTiO8siyQQwNpus5YMAIDnOTm5axc8mtgehXeIpo2H2sIpSS4Fjq0lNeVuTaRKTeAn0knFtgpfboUcW/FDSico2Ky/5hhN10K7t4MMSBHssMJyiq6mxQwpfe5qb/C3tq4vepuNFnViKwl02jG0IprLhBXhQa69DJQZc5xYc21Hb7GUy0rLbna4e3iLV31WqO/or/Chdauw==</Codesign>
        </Script>
        <Script id="1696">
          <Name>SecondObjectURLCommand</Name>
          <Code>using System;
using System.Data;
using Alvao.Global;
using Alvao.API.Common;
using Alvao.API.Common.Model.CustomApps;
using Alvao.Apps.API;
using Alvao.Context;
using Dapper;

public class SecondObjectURLCommand : IEntityCommand 
{
    public string Id {get; set;}
    public Entity Entity {get; set;}
    private int scriptNo = 1;

    public SecondObjectURLCommand()
    {
        Id = "SecondObjectURLCommand";
        Entity = Entity.Object;
    }

    public EntityCommandShowResult Show(int entityId, int personId)
    {    
        if (!Helpers.IsMemberOfAssetManagers(personId))
            return new EntityCommandShowResult(false, String.Empty, String.Empty, 1);
        
        CommandConfig command = Helpers.GetCommand(entityId, scriptNo);

        if (command != null)
            return new EntityCommandShowResult(true, command.Name, command.Icon, command.Position);
        else
            return new EntityCommandShowResult(false, String.Empty, String.Empty, 1);
    }

    public CommandResult Run(int entityId, int personId)
    {
        CommandConfig command = Helpers.GetCommand(entityId, scriptNo);
        Helpers.GetFinalUrl(command, entityId);
        return new CommandResult(MessageType.None, string.Empty, command.Url);
    }
}</Code>
          <IsLibCode>false</IsLibCode>
          <Codesign>pyxUo9rOalcQGfeKEUjyPu8VlaiV1OM8dlhUe3+AQUkImCiP8ywnq5SReQDGPQaLlsXyh8nD3TDiR9dnyx4lLezrEqpHfnGhSkxoNcdd7SmH49r56w4fTeu9Xh4RwPshft/P79+iFh739zh2OPF5MVkqmW8Yu992Q+lGhWZ2kByPHkGMEK26OpO0CGfX19fJQ8st6xZxZB7f6mMqstYkHZbq1GlY5ww34Kh6kUfbAix2wgw4qOnPoOcbfi9DNoPnhzW9Gmd+El3wYDLy5s6m2fD8Fo48tQ/TysjqHHI+ce9zhkIACWxZQmrF/hFXPNPrkbe/uvwmly16/MNZPjHnVw==</Codesign>
        </Script>
        <Script id="1697">
          <Name>ThirdObjectURLCommand</Name>
          <Code>using System;
using System.Data;
using Alvao.Global;
using Alvao.API.Common;
using Alvao.API.Common.Model.CustomApps;
using Alvao.Apps.API;
using Alvao.Context;
using Dapper;

public class ThirdObjectURLCommand : IEntityCommand 
{
    public string Id {get; set;}
    public Entity Entity {get; set;}
    private int scriptNo = 2;

    public ThirdObjectURLCommand()
    {
        Id = "ThirdObjectURLCommand";
        Entity = Entity.Object;
    }

    public EntityCommandShowResult Show(int entityId, int personId)
    {   
        if (!Helpers.IsMemberOfAssetManagers(personId))
            return new EntityCommandShowResult(false, String.Empty, String.Empty, 1);
        
        CommandConfig command = Helpers.GetCommand(entityId, scriptNo);

        if (command != null)
            return new EntityCommandShowResult(true, command.Name, command.Icon, command.Position);
        else
            return new EntityCommandShowResult(false, String.Empty, String.Empty, 1);
    }

    public CommandResult Run(int entityId, int personId)
    {
        CommandConfig command = Helpers.GetCommand(entityId, scriptNo);
        Helpers.GetFinalUrl(command, entityId);
        return new CommandResult(MessageType.None, string.Empty, command.Url);
    }
}</Code>
          <IsLibCode>false</IsLibCode>
          <Codesign>fqek4ERwRBqOZUVBAqc1ZF7KHRon5aCXJkSl5+Caz50RzPdlaKFnnGlOXCAa0xB9bOEdHNK8MMGTnm9c0lEzkYTGQyKoIRAggkBgg2Q0+nS1u9UfnUXCPLokITpZNeQNWLaI31mJLbLQ71RoNcYITmImMlTodCpE4hTuqURLjd11i65+cVwuE0LZ4Rd+w+lyJMb8ss0f/mv+RUBTGqRqjTg7YctG0+XCLaiS2PAdQf8ulFDSlzqmgX43LGb7OBh3npO8FTEJ9zokzJ1vIg+lL6nB2L4ZYNKH23bfOKGMX86VEpQS1ANC4Lr3tbJ1XicFVjYgiQg/Eg7TXAX0olRxNg==</Codesign>
        </Script>
      </Scripts>
    </Application>
  </Applications>
</AlvaoApplication>