<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div class="container">
<div class="row">
<h2>Create your snippet's HTML, CSS and Javascript in the editor tabs</h2>
</div>
</div>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Caching;
namespace
{
public class StructureNode
{
private const string STRUCTURE_CACHE_KEY = "STRUCTURE_CACHE";
public static bool StructureCached
{
get
{
var cache = HttpRuntime.Cache.Get(STRUCTURE_CACHE_KEY);
return !(cache == null || cache is string);
}
}
public static void CreateStructureCache()
{
if (HttpRuntime.Cache.Get(STRUCTURE_CACHE_KEY) != null)
return;
Task.Run(() =>
{
var sw = new Stopwatch();
HttpRuntime.Cache.Insert(STRUCTURE_CACHE_KEY, "?", null, Cache.NoAbsoluteExpiration, new TimeSpan(24, 0, 0), CacheItemPriority.Normal, null);
sw.Start();
var items = GetItems();
sw.Stop();
HttpRuntime.Cache.Insert(STRUCTURE_CACHE_KEY, items, null, Cache.NoAbsoluteExpiration, new TimeSpan(24, 0, 0), CacheItemPriority.Normal, null);
LoggingService.Info(string.Format("Structure cache created. Time: {0}", sw.Elapsed.ToString("hh\\:mm\\:ss\\.fff")));
});
}
public static List<StructureNode> AllDepartments
{
get
{
return HttpRuntime.Cache.Get(STRUCTURE_CACHE_KEY) as List<StructureNode>;
}
}
public int ID { get; set; }
public string Title { get; set; }
public int EmployeesCount { get; set; }
public string ExternalUrl { get; set; }
public EmployeeInfo Manager { get; set; }
public EmployeeInfo Curator { get; set; }
private int? ParentDepID { get; set; }
public List<StructureNode> Children { get; set; }
public static List<StructureNode> RootDepartments
{
get
{
var rootCount = StructureNode.AllDepartments.Count(d => !d.ParentDepID.HasValue);
var rootId = rootCount == 1
? StructureNode.AllDepartments.First(d => !d.ParentDepID.HasValue).ID
: (int?)null;
return StructureNode.AllDepartments.Where(d => d.ParentDepID == rootId)
.OrderBy(d => d.Title)
.Select(d =>
{
EnsureDepartmentChildren(d);
return d;
})
.ToList();
}
}
public void RecalcEmployeesCount(IEnumerable<StructureNode> allItems)
{
var childDeps = allItems.Where(d => d.ParentDepID == this.ID)
.ToList();
childDeps.ForEach(d => d.RecalcEmployeesCount(allItems));
this.EmployeesCount += childDeps.Sum(ch => ch.EmployeesCount);
}
public static void EnsureDepartmentChildren(StructureNode dep)
{
dep.Children = AllDepartments.Where(ch => ch.ParentDepID == dep.ID)
.OrderBy(ch => ch.Title)
.ToList();
}
public static StructureNode GetDepartmentInfo(int? depId)
{
var dep = AllDepartments.FirstOrDefault(d => d.ID == depId);
if (dep == null)
return null;
EnsureDepartmentChildren(dep);
return dep;
}
public static StructureNode GetDepartmentWithParent(int depId)
{
var current = GetDepartmentInfo(depId);
if (current == null)
return null;
var parent = GetParent(current);
while (parent != null)
{
current = parent;
parent = GetParent(current);
}
return current;
}
private static StructureNode GetParent(StructureNode item)
{
var parent = GetDepartmentInfo(item.ParentDepID);
if (parent != null)
{
var index = parent.Children.FindIndex(d => d.ID == item.ID);
parent.Children[index] = item;
}
return parent;
}
public static List<object> GetStructureByTitle(string search)
{
var singleRoot = StructureNode.AllDepartments.Count(d => !d.ParentDepID.HasValue) == 1;
return StructureNode.AllDepartments.Where(d => d.Title.ToLower().Contains(search.ToLower()) && (singleRoot ? d.ParentDepID.HasValue : true))
.Select(d => new
{
data = d.ID,
value = d.Title
})
.Take(10)
.ToList<object>();
}
private static List<StructureNode> GetItems()
{
List<StructureNode> flatDepsInfo = new List<StructureNode>();
try
{
using (var db = _Consts.Db)
{
db.CommandTimeout = db.CommandTimeout * 100;
flatDepsInfo = db.Departments.NotArchive()
.GroupJoin(db.Employees,
d => d.ID,
e => e.DepartmentId,
(d, e) => new
{
department = d,
employeesCount = e.Count(tE => (!tE.IsArchive.HasValue || !tE.IsArchive.Value))
})
.GroupJoin(db.Employees,
j => j.department.ManagerId,
e => e.ID,
(j, manager) => new
{
j.department,
j.employeesCount,
manager
})
.SelectMany(j => j.manager.DefaultIfEmpty(), (j, manager) => new
{
j.department,
j.employeesCount,
manager = manager == null
? null
: new EmployeeInfo { ID = manager.ID, Title = manager.Title, Photo = manager.Photo }
})
.GroupJoin(db.Employees,
j => j.department.CuratorId,
e => e.ID,
(j, curator) => new
{
j.department,
j.employeesCount,
j.manager,
curator
})
.SelectMany(j => j.curator.DefaultIfEmpty(), (j, curator) => new
{
j.department.ID,
j.department.Title,
j.department.ParentId,
j.department.URL,
j.employeesCount,
j.manager,
curator = curator == null
? null
: new EmployeeInfo { ID = curator.ID, Title = curator.Title, Photo = curator.Photo }
})
.ToList()
.Select(d => new StructureNode
{
ID = d.ID,
Title = d.Title,
ParentDepID = d.ParentId,
ExternalUrl = d.URL,
EmployeesCount = d.employeesCount,
Manager = d.manager,
Curator = d.curator
})
.ToList();
}
flatDepsInfo.Where(d => d.ParentDepID == null)
.ToList()
.ForEach(d => d.RecalcEmployeesCount(flatDepsInfo));
}
catch (Exception ex)
{
LoggingService.Error(ex);
}
return flatDepsInfo;
}
}
}