EnVisageOnline/Main/Source/EnVisage/Code/BLL/CompanyManager.cs

325 lines
9.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using EnVisage.Models;
namespace EnVisage.Code.BLL
{
public class CompanyManager : ManagerBase<Company, CompanyModel>
{
public CompanyManager(EnVisageEntities dbContext)
: base(dbContext)
{
}
protected override Company InitInstance()
{
return new Company { Id = Guid.NewGuid() };
}
protected override Company RetrieveReadOnlyById(Guid key)
{
return DataTable.AsNoTracking().FirstOrDefault(t => t.Id == key);
}
public override DbSet<Company> DataTable
{
get
{
return DbContext.Companies;
}
}
#region Public Methods
public CompanyModel GetCompanyByName(string name)
{
return CompanyModelBasicQuery.Where(x => x.Name == name).FirstOrDefault();
}
public CompanyModel GetCompanyById(Guid id)
{
return CompanyModelBasicQuery.FirstOrDefault(q => q.Id == id);
}
/// <summary>Loads a first Company with parentId == null.</summary>
/// <returns>A <see cref="CompanyModel"/> object.</returns>
public CompanyModel LoadParent()
{
var parent = CompanyModelBasicQuery.FirstOrDefault(t => t.ParentCompanyId == null);
if (parent == null)
throw new BLLException("There is no Parent Company in the database. It should be created on application start.", false);
return parent;
}
public CompanyModel LoadWithChildCollections(Guid companyId)
{
var model = LoadCompanyModel(companyId);
if (model != null && model.Id != Guid.Empty)
{
model.ClientId = DbContext.Company2Client.AsNoTracking().Where(x => x.CompanyId == model.Id)
.Select(x => x.ClientId)
.ToList();
model.ViewId = DbContext.Company2View.AsNoTracking().Where(x => x.CompanyId == model.Id)
.Select(x => x.ViewId)
.ToList();
}
return model;
}
public override Company Save(CompanyModel model)
{
var company = base.Save(model);
if (Guid.Empty.Equals(model.Id))
{
if (model.ClientId != null)
{
foreach (var clientId in model.ClientId)
{
var client = DbContext.Company2Client.Create();
client.Id = Guid.NewGuid();
client.ClientId = clientId;
client.CompanyId = company.Id;
DbContext.Company2Client.Add(client);
}
}
if (model.ViewId != null)
{
foreach (var viewId in model.ViewId)
{
var company2View = DbContext.Company2View.Create();
company2View.Id = Guid.NewGuid();
company2View.ViewId = viewId;
company2View.CompanyId = company.Id;
DbContext.Company2View.Add(company2View);
}
}
}
else
{
var clients = DbContext.Company2Client.Where(x => x.CompanyId == model.Id).ToList();
clients.Where(x => model.ClientId == null || !model.ClientId.Contains(x.ClientId)).ToList().
ForEach(x => DbContext.Entry(x).State = EntityState.Deleted);
var company2Views = DbContext.Company2View.Where(x => x.CompanyId == model.Id).ToList();
company2Views.Where(x => model.ViewId == null || !model.ViewId.Contains(x.ViewId)).ToList().
ForEach(x => DbContext.Entry(x).State = EntityState.Deleted);
if (model.ClientId != null)
{
foreach (var clientId in model.ClientId.Where(c => !clients.Select(x => x.ClientId).Contains(c)))
{
var client = DbContext.Company2Client.Create();
client.Id = Guid.NewGuid();
client.ClientId = clientId;
client.CompanyId = company.Id;
DbContext.Company2Client.Add(client);
}
}
if (model.ViewId != null)
{
foreach (var viewId in model.ViewId.Where(c => !company2Views.Select(x => x.ViewId).Contains(c)))
{
var company2View = DbContext.Company2View.Create();
company2View.Id = Guid.NewGuid();
company2View.ViewId = viewId;
company2View.CompanyId = model.Id;
DbContext.Company2View.Add(company2View);
}
}
}
#region Save of attached to company watchers and contributors
// Get child companies for current, if it is parent for some
var childCompaniesForCurrent = DbContext.Companies.Where(x =>
x.ParentCompanyId.HasValue && x.ParentCompanyId.Value.Equals(company.Id)).Select(x => x.Id).ToList();
// Remove existing records for current company and it's child companies
var recsToRemove = DbContext.User2Company.Where(x =>
x.CompanyId.Equals(company.Id) || childCompaniesForCurrent.Contains(x.CompanyId)).ToList();
DbContext.User2Company.RemoveRange(recsToRemove);
SaveCompanyUsers(company.Id, model.Contributors, CollaborationRole.Contributor);
// If a user is already a contributor, we no need to save him as a watcher
var watchersFiltered = (model.Contributors != null) && (model.Watchers != null) ?
model.Watchers.Except(model.Contributors).ToList() : new List<Guid>();
SaveCompanyUsers(company.Id, watchersFiltered, CollaborationRole.Watcher);
#endregion
return company;
}
private void SaveCompanyUsers(Guid companyId, List<Guid> users, CollaborationRole role)
{
if ((users == null) || (users.Count < 1))
return;
foreach (Guid userId in users)
{
User2Company newRec = new User2Company()
{
Id = Guid.NewGuid(),
CompanyId = companyId,
UserId = userId,
RelationType = role
};
DbContext.User2Company.Add(newRec);
}
}
/// <summary>
/// Returns All companies, available for given user, ordered by parent company.
/// </summary>
/// <param name="userId">User Id</param>
/// <returns>All companies.</returns>
public IList<Company> GetCompaniesByUser(Guid? userId)
{
IQueryable<Company> qry = null;
if (userId.HasValue)
{
qry =
from c in DbContext.Companies
join u2c in DbContext.VW_User2Company on c.Id equals u2c.CompanyId
where u2c.UserId.Equals(userId.Value) && ((u2c.Read == 1) || (u2c.Write == 1))
select c;
}
else
{
qry = DbContext.Companies;
}
var result = qry.Distinct().ToList();
return result;
}
/// <summary>
/// Returns All companies, available for given user
/// </summary>
/// <param name="userId">User Id</param>
/// <returns>Companies, available for user or all companies, if user not specified</returns>
public Task<List<Company>> GetCompaniesByUserAsync(Guid? userId)
{
Task<List<Company>> result;
if (userId.HasValue)
{
result =
(from c in DbContext.Companies
join u2c in DbContext.VW_User2Company on c.Id equals u2c.CompanyId
where u2c.UserId.Equals(userId.Value) && ((u2c.Read == 1) || (u2c.Write == 1))
select c).Distinct().ToListAsync();
}
else
{
result = DbContext.Companies.ToListAsync();
}
return result;
}
public IList<Company> GetCompaniesByUserFiltered(List<Guid> companies)
{
if (companies == null)
throw new ArgumentNullException("companies");
var availableToUserCompanies = this.GetCompaniesByUser(null);
var result = availableToUserCompanies.Where(x => companies.Contains(x.Id)).ToList();
return result;
}
/// <summary>
/// Returns All companies, available for given user, ordered by parent company.
/// </summary>
/// <param name="userId">User Id</param>
/// <returns>All companies.</returns>
public IList<CompanyApiModel> GetCompaniesByUser4Display(Guid? userId)
{
IQueryable<CompanyApiModel> companies = null;
if (userId.HasValue)
{
companies = (from cmp in DbContext.Companies.AsNoTracking()
join visible4User in DbContext.VW_User2Company4Display on cmp.Id equals visible4User.CompanyId
where (!userId.HasValue || visible4User.UserId.Equals(userId.Value)) &&
((visible4User.Read == 1) || (visible4User.Write == 1))
select cmp).ToArray().Select(t=> new CompanyApiModel(t)).AsQueryable();
} else
{
companies = DbContext.Companies.ToArray().Select(x => new CompanyApiModel(x)).AsQueryable();
}
return companies.Distinct().ToList();
}
public CompanyModel LoadCompanyModel(Guid companyId)
{
return CompanyModelBasicQuery.FirstOrDefault(x => x.Id == companyId);
}
public List<CompanyModel> LoadCompanies()
{
return CompanyModelBasicQuery.ToList();
}
public Dictionary<KeyValuePair<Guid, string>, List<CompanyModel>> GetCompanies()
{
var data = CompanyModelBasicQuery.ToArray();
var result = new Dictionary<KeyValuePair<Guid, string>, List<CompanyModel>>();
foreach (var parent in data.Where(t => !t.ParentCompanyId.HasValue).OrderBy(t => t.Name))
{
var key = new KeyValuePair<Guid, string>(parent.Id, parent.Name);
if (!result.ContainsKey(key))
result.Add(key, new List<CompanyModel>());
}
foreach (var child in data.Where(t => t.ParentCompanyId.HasValue).OrderBy(t => t.Name))
{
var parentKey = new KeyValuePair<Guid, string>(child.ParentCompanyId.Value, child.ParentCompanyName);
// add parent if it wasnt added in previous foreach for some reason
if (!result.ContainsKey(parentKey))
result.Add(parentKey, new List<CompanyModel>());
var parent = result[parentKey];
if (parent != null)
parent.Add((CompanyModel)child);
}
return result;
}
#endregion
#region Private Members
private IQueryable<CompanyModel> CompanyModelBasicQuery
{
get
{
var query = DbContext.Companies.Include(x => x.Projects).Include(x => x.Company1)
.Include(x => x.Company2).Include(x => x.Teams).AsNoTracking()
.Select(x =>
new CompanyModel
{
Id = x.Id,
Name = x.Name,
ParentCompanyId = x.ParentCompanyId,
ParentCompanyName = x.ParentCompanyId.HasValue ? x.Company2.Name : null,
ProjectsCount = x.Projects.Count,
CompaniesCount = x.Company1.Count,
TeamsCount = x.Teams.Count
});
return query;
}
}
#endregion
}
}