<?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="45">
      <Name>Asset Check Automation</Name>
      <Description>Automates asset check status update. When assets are manually moved or when check-in data is received from supported connectors - such as Microsoft Intune, Jamf, Zabbix, and others - the asset status is automatically set to Found. If no activity is detected within the past six months, the asset is marked for asset check.</Description>
      <UniqueId>5ab6a5b7-b08a-42bb-bd92-0879468afa12</UniqueId>
      <Version>6</Version>
      <AdvancedSettings />
      <Scripts>
        <Script id="103">
          <Name>AutomaticAssetCheck</Name>
          <Code>using System;
using System.Data;
using Microsoft.Data.SqlClient;
using Alvao.Apps.API;
using Alvao.Context;
using Dapper;
using Alvao.API.Common;
using System.Linq;
using Alvao.API.Common.Model.Database;

class ObjectMoveAutoAction : IObjectMoveAutoAction
{
    public Tuple&lt;bool, string&gt; OnObjectMoving(SqlConnection con, int objectId, int newParentObjectId, int personId)
    {
        throw new NotImplementedException();
    }

    public void OnObjectMoved(SqlConnection con, int objectId, int oldParentObjectId, int personId)
    {
        if (!Activation.IsModuleActivated(Alvao.Global.ModuleInfo.ModuleId.AMAutopilot))
        {
            throw new Exception("AMAutopilot module is not activated.");
        }
        var obj = Alvao.API.AM.Object.GetById(personId, objectId);
        if (obj.lintClassId == (int)Alvao.API.AM.Model.ObjectClass.Code.SpecObjTrash)
        {
            return;
        }
        if (Alvao.API.AM.ObjectProperty.TemplateContains(obj.lintClassId ?? 0, Alvao.API.Common.Model.Database.tblKind.KindCode.LastFoundAssetCheck))
        {
            Alvao.API.AM.ObjectProperty.Update(objectId, Alvao.API.Common.Model.Database.tblKind.KindCode.LastFoundAssetCheck, DateTime.Now.Date, false, true);
        }

        var propertyValues = Alvao.API.AM.ObjectProperty.GetValueList(0, (int)Alvao.API.Common.Model.Database.tblKind.KindCode.StatusAssetCheck).ToList();
        var kindValue = Alvao.API.AM.ObjectProperty.GetValuesByKindCodes(objectId, new[] { tblKind.KindCode.StatusAssetCheck }).FirstOrDefault().Value;
        var pendingValue = propertyValues[1].txtValue;
        var foundValue = propertyValues[2].txtValue;
        if (kindValue == pendingValue &amp;&amp; Alvao.API.AM.ObjectProperty.TemplateContains(obj.lintClassId ?? 0, Alvao.API.Common.Model.Database.tblKind.KindCode.StatusAssetCheck))
        {
            Alvao.API.AM.ObjectProperty.Update(objectId, tblKind.KindCode.StatusAssetCheck, foundValue, false);
        }
    }
}</Code>
          <IsLibCode>false</IsLibCode>
          <Codesign>rOUziUC+H+qdE4jTG++aRjhkFP3M8AkQDHbArP1cudf25cO/PEUUFoG2v16bGpqLnA0j8EFmLe9p12Xk1xPMlYtTexaz5tjUYLbMlqeOgAFABruWM3In9sZFJxkYOAMDG4ubpk/zAkphPWwOyRanviuAvpqaVqotXav+1P6uKN9uIvPipTVMSBCbT1WTYqvoQgD2qgrGMlg/IYm62H8lM7eemlLEc77Ft1bqXfbKDf7hhE9gbJxnyCsOOan37igtrSVqDfjqkIr6TKWrXhsmKov3hovsO7pJfkLLVhxdnfh8Kbz7Rb7ISlqplgDLy9cBLwd/hwq4tnvBKaaDzKCkIA==</Codesign>
        </Script>
        <Script id="104">
          <Name>PeriodicAssetCheckPending</Name>
          <Code>using System;
using System.Data;
using Microsoft.Data.SqlClient;
using Alvao.Global;
using Alvao.API.Common;
using Alvao.Apps.API;
using Alvao.Context;
using Dapper;
using System.Collections.Generic;
using Alvao.API.Common.Model.Database;
using System.Linq;

public class PeriodicAssetCheckPending : IPeriodicAction
{
    public string Name 
    { 
        get =&gt; "Asset check pending after 6 months";
        set { }
    }

    public void OnPeriod(SqlConnection con)
    {
        if (!Activation.IsModuleActivated(Alvao.Global.ModuleInfo.ModuleId.AMAutopilot))
        {
            throw new Exception("AMAutopilot module is not activated.");
        }
        DateTime serverTime = DateTime.Now;
        if (serverTime.Hour == 2)
        {
            string notFound = Alvao.API.AM.ObjectProperty.GetValueList(0, (int)Alvao.API.Common.Model.Database.tblKind.KindCode.StatusAssetCheck).ToList()[3].txtValue;
            using (var scope = AlvaoContext.GetConnectionScope())
            {
                string sql = @$"select p.NodeId from NodeCust p 
                inner join tblNode tn on p.NodeId = tn.intNodeId
                inner join ClassKind ck on tn.lintClassId =  ck.ClassId 
                inner join tblKind tk on ck.KindId = tk.intKindId 
                where AssetCheckDate &lt; DATEADD(MONTH, -6, GETDATE())
                AND tn.IsRemoved = 0 AND tn.IsDiscarded = 0
                AND tk.intKindCode = 178
                AND (StatusAssetCheck != @notFound OR StatusAssetCheck IS NULL)
                ";
                var nodeIds = scope.Connection.Query&lt;int&gt;(sql, new { notFound }, transaction: scope.Transaction).ToList();
                string pending = Alvao.API.AM.ObjectProperty.GetValueList(0, (int)Alvao.API.Common.Model.Database.tblKind.KindCode.StatusAssetCheck).ToList()[1].txtValue;

                foreach (int id in nodeIds)
                {
                    Alvao.API.AM.ObjectProperty.Update(id, tblKind.KindCode.StatusAssetCheck, pending, false, true);
                }
            }
        }
    }
}</Code>
          <IsLibCode>false</IsLibCode>
          <Codesign>RKJbIMVSP4rtGF/HZETJEO/fiiMt9Ishgn/xqUeyStwzYd+GKM8YB5iU7Sqvzte/j2T8RLrY/qYC2CbIb96on/fa/NgeP0smVRVel+GCRnsKWRdJIxsI/B08IAl+O37+Khlfhvv/UnipFR6DNdy5WhQ6q6Md8MRbdGKYxR4aoQr2xu0V5+XBr19aqQCGCxttYRY8Ih2PzI/AHR4Zo4lqdOdDjKGf34W4h0FEKZBJOHq5rV7vVOmiZK5ZvGCae5LHgIjMO4HAkRWfYfZ+2C1gCQaLnRAFe7e6qA8ejxPbYxXO5XgsYPtLpijbnkdWfg/iWtfCavxTih/p7a44qtlyBw==</Codesign>
        </Script>
        <Script id="106">
          <Name>ObjectPropertyAutoAction</Name>
          <Code>using System;
using System.Data;
using Microsoft.Data.SqlClient;
using Alvao.Apps.API;
using Alvao.Context;
using Dapper;
using System.Collections.Generic;
using Alvao.API.Common.Model.Database;
using Alvao.API.Common;
using System.Linq;

class ObjectPropertyAutoAction : IObjectPropertyAutoAction
{
    public ObjectPropertyModifyResult OnObjectPropertyModifying(ObjectPropertyEventArgs e)
    {
        throw new NotImplementedException();
    }

    public void OnObjectPropertyModified(ObjectPropertyEventArgs e)
    {
        if (!Activation.IsModuleActivated(Alvao.Global.ModuleInfo.ModuleId.AMAutopilot))
        {
            throw new Exception("AMAutopilot module is not activated.");
        }
        var allowedProps = new List&lt;tblKind.KindCode&gt;()
        {
            tblKind.KindCode.IntuneLastCheckIn,
            tblKind.KindCode.JamfLastCheckIn,
            tblKind.KindCode.AlvaoAgentLastCheckIn,
            tblKind.KindCode.ZabbixLastCheckIn,
            tblKind.KindCode.LansweeperLastCheckIn
        };
        var property = Alvao.API.AM.ObjectProperty.GetDefinition(e.PropertyKindId);
        if (property.intKindCode.HasValue &amp;&amp; allowedProps.Contains((tblKind.KindCode)property.intKindCode))
        {
            if (e.NewValue == null)
                return;
            string strDate = e.NewValue.ToString();
            var objectClassId = Alvao.API.AM.Object.GetById(e.PersonId, e.ObjectId).lintClassId;
            bool hasLastFoundProperty = objectClassId.HasValue &amp;&amp; Alvao.API.AM.ObjectProperty.TemplateContains(objectClassId.Value , tblKind.KindCode.LastFoundAssetCheck); 
            if (hasLastFoundProperty &amp;&amp; DateTime.TryParse(strDate, out DateTime dateValue))
            {
                Alvao.API.AM.ObjectProperty.Update(e.ObjectId, tblKind.KindCode.LastFoundAssetCheck, dateValue, true, false);
            }
            var propertyValues = Alvao.API.AM.ObjectProperty.GetValueList(0, (int)Alvao.API.Common.Model.Database.tblKind.KindCode.StatusAssetCheck).ToList();
            var kindValue = Alvao.API.AM.ObjectProperty.GetValuesByKindCodes(e.ObjectId, new[] { tblKind.KindCode.StatusAssetCheck }).FirstOrDefault().Value;
            var pendingValue = propertyValues[1].txtValue;
            var foundValue = propertyValues[2].txtValue;
            if (kindValue == pendingValue)
            {
                Alvao.API.AM.ObjectProperty.Update(e.ObjectId, tblKind.KindCode.StatusAssetCheck, foundValue, false);
            }
        }
    }
}</Code>
          <IsLibCode>false</IsLibCode>
          <Codesign>P1yUJaCdTgL1gqO7cPFOyGNTDHRcKNxeK6qsVFq1Jss8cD0Sx0enS6rYKKdC6TT5WnfC9kuxyW5iQJsEPWJu/s5qUNjPql/W02FIJRz2/n5LJgCRatrTiTuWV0gT453lm7DoNr0XC0CHqJlt5wVOgo1CFMy56EQTxL0XCre/CajoHmCs5ZAIkgQLNFG1lhlAUzokwTgSzaTq2NnZrRqDYeSkiDryE8b4pwRNTGUN0S1d9PWNI16GE2U3PprYv0jqQBouSd8tey36dmg38Q1ALFCYZ+kxpxBbAblCrZKasHIiz5/5a9dTf3dm8AI2gPItqlHvDf0ompYrVoBgnuxDJQ==</Codesign>
        </Script>
      </Scripts>
    </Application>
  </Applications>
</AlvaoApplication>