﻿<?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="37">
      <Name>ObjectChatWithUser</Name>
      <Description>In the Object page, adds the Chat with user command to start a Microsoft Teams chat with the user who is responsible for the object or has been entrusted with its use.</Description>
      <Scripts>
        <Script id="100">
          <Name>Localization</Name>
          <Code>using System.Linq;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using Alvao.API.Common;

public class Localization
{
    public static List&lt;LocalizationItem&gt; Localizations
    {
        get
        {
            return new List&lt;LocalizationItem&gt;()
            {
                new LocalizationItem(1029, "ChatWithObjectUser", "Chat s uživatelem"),
                new LocalizationItem(1033, "ChatWithObjectUser", "Chat with user"),
                new LocalizationItem(1031, "ChatWithObjectUser", "Chat mit dem Benutzer"),
                new LocalizationItem(1045, "ChatWithObjectUser", "Chat z użytkownikiem"),
                new LocalizationItem(1051, "ChatWithObjectUser", "Chat s používateľom"),
            };
        }
    }

    public static string GetLocalization(int personId, string name)
    {
        var localeId = GetPersonLocaleId(personId);
        var translation = FindInList(localeId, name);
        if (string.IsNullOrEmpty(translation))
        {
            localeId = GetDefaultLocaleId();
            translation = FindInList(localeId, name);
        }
        return translation;
    }

    private static string FindInList(int localeId, string name)
    {
        return Localizations.FirstOrDefault(x =&gt; x.LocaleId == localeId &amp;&amp; x.Name == name)?.Translation;
    }

    private static int GetDefaultLocaleId()
    {
        var locale = Person.GetCultureInfoOrDefault(new Alvao.API.Common.Model.Database.tPerson()).LCID;
        return locale;
    }

    private static int GetPersonLocaleId(int personId)
    {
        var locale = Person.GetById(personId).iPersonLocaleId;
        if (!locale.HasValue)
        {
            return GetDefaultLocaleId();
        }
        return locale.Value;
    }
}

public class LocalizationItem
{
    public int LocaleId { get; set; }
    public string Name { get; set; }
    public string Translation { get; set; }

    public LocalizationItem(int localeId, string name, string translation)
    {
        this.LocaleId = localeId;
        this.Name = name;
        this.Translation = translation;
    }
}
</Code>
          <IsLibCode>true</IsLibCode>
        </Script>
        <Script id="101">
          <Name>Settings</Name>
          <Code>public class Settings
{
    public const bool OpenInConsole = false;
}</Code>
          <IsLibCode>true</IsLibCode>
        </Script>
        <Script id="102">
          <Name>TeamsWithUserCommand</Name>
          <Code>using Alvao.API.Common;
using Alvao.API.Common.Model.CustomApps;
using Alvao.Apps.API;
using Alvao.Context;
using Dapper;

public class TeamsWithUserCommand : IEntityCommand 
{
    public string Id {get; set;}
    public Entity Entity {get; set;}

    public TeamsWithUserCommand()
    {
        Id = "Chat with user".GetHashCode().ToString();
        Entity = Entity.Object;
    }

    public EntityCommandShowResult Show(int entityId, int personId)
    {   
        int position = 3;
        string icon = "TeamsLogo"; 
        string name = Localization.GetLocalization(personId, "ChatWithObjectUser"); 
        bool show = !string.IsNullOrEmpty(GetUserEmailForChat(entityId));

        return new EntityCommandShowResult (show, name, icon, position);
    }

    public CommandResult Run(int entityId, int personId)
    {
        MessageType messageType = MessageType.None; 
        string messageText = string.Empty;
        string navigateToUrl = string.Empty; 

        string email = GetUserEmailForChat(entityId);
        
        if (string.IsNullOrEmpty(email)) {
            messageType = MessageType.Error;
            return new CommandResult(messageType, messageText, navigateToUrl);
        }

        var waUrl = DbProperty.WebAppUrl;
        var amObject = Alvao.API.AM.Object.GetById(personId, entityId);
        var objectUrl = "";
        if (!string.IsNullOrEmpty(waUrl))
        {
            objectUrl = waUrl + "/Object/" + entityId;
        }

        // Opens directly Windows application. It may not work in other environments.
        var openIn = Settings.OpenInConsole ? "MSTeams:/" : "https://teams.microsoft.com/";
        var message = string.IsNullOrEmpty(objectUrl) ? $" {amObject.txtName}" : $" {amObject.txtName}  - {objectUrl}";
        
        navigateToUrl = $"{openIn}l/chat/0/0?users={email}&amp;topicName={System.Web.HttpUtility.UrlEncode(amObject.txtName)}&amp;message={System.Web.HttpUtility.UrlEncode(message)}";

        return new CommandResult(messageType, messageText, navigateToUrl);
    }

    private string GetUserEmailForChat(int objectId)
    {
        using (var scope = AlvaoContext.GetConnectionScope())
        {
            //Retrieving the required object data from the database.
            string email = scope.Connection.QueryFirstOrDefault&lt;string&gt;(@"
                select
                    pe.txtValue [Email]
                from tblNode n
                    join tblProperty p on p.lintNodeId=n.intNodeId
                    join tblKind k on k.intKindId=p.lintKindId and k.intKindCode=145
                    join tblNode u on u.intNodeId=p.NodeIdValue 
                    join tblProperty pe on pe.lintNodeId=u.intNodeId
                    join tblKind ke on ke.intKindId=pe.lintKindId and ke.intKindCode=46
                where n.intNodeId=@objectId

                union all

                select
                    pe.txtValue [Email]
                from tblNode n
                    join tblProperty p on p.lintNodeId=n.intNodeId and p.ParentNodeId is not null
                    join tblKind k on k.intKindId=p.lintKindId and k.intKindCode=5 
                    join tblProperty pe on pe.lintNodeId=p.ParentNodeId
                    join tblKind ke on ke.intKindId=pe.lintKindId and ke.intKindCode=46 
                    left join
                    (
                        select
                            p.lintNodeId
                        from tblProperty p
                            join tblKind k on k.intKindId=p.lintKindId and k.intKindCode=145 
                    ) zmz on zmz.lintNodeId=n.intNodeId
                where n.intNodeId=@objectId
                    and zmz.lintNodeId is null", new { objectId }
            );

            return email;
        }
    }
}
</Code>
          <IsLibCode>false</IsLibCode>
        </Script>
      </Scripts>
    </Application>
  </Applications>
</AlvaoApplication>