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

616 lines
28 KiB
C#

using EnVisage.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
using System.Text;
using System.Web;
namespace EnVisage.Code.BLL
{
public class NotificationManager: ManagerBase<Notification, NotificationModel>
{
public NotificationManager(EnVisageEntities dbContext): base(dbContext)
{
}
protected override Notification InitInstance()
{
return new Notification { Id = Guid.NewGuid() };
}
protected override Notification RetrieveReadOnlyById(Guid key)
{
return DataTable.AsNoTracking().FirstOrDefault(t => t.Id == key);
}
public override DbSet<Notification> DataTable => DbContext.Notifications;
public override Notification Save(NotificationModel model)
{
if (model == null)
throw new ArgumentNullException(nameof(model));
bool newDbObject = false;
Notification dbObj = null;
if (model.Id != Guid.Empty)
dbObj = DataTable.Find(model.Id);
if (dbObj == null)
{
newDbObject = true;
dbObj = new Notification { Id = model.Id };
model.Actions = GetNotificationActions(model.type);
}
model.CopyTo(dbObj);
if (newDbObject)
DbContext.Notifications.Add(dbObj);
else
DbContext.Entry(dbObj).State = EntityState.Modified;
if (IsContextLocal)
DbContext.SaveChanges();
var actions = GetNotificationActions(model.type);
model.Actions = actions;
Hubs.Notifications.NotificationRouter.sentNotification(model);
return dbObj;
}
public void Delete(Guid id)
{
Notification dbObj = Load(id, false);
NotificationModel model = new NotificationModel(dbObj, DbContext);
model.Actions = GetNotificationActions(model.type);
if (dbObj != null)
DbContext.Notifications.Remove(dbObj);
if (IsContextLocal)
DbContext.SaveChanges();
Hubs.Notifications.NotificationRouter.removeNotification(model);
}
public Dictionary<Guid, List<Notification>> GetNotifications(Guid parentId, NotificationGroupType? grouptype)
{
return GetNotifications(new List<Guid> { parentId }, grouptype);
}
public Dictionary<Guid, List<Notification>> GetNotifications(Guid parentId)
{
return GetNotifications(new List<Guid> { parentId });
}
public Dictionary<Guid, List<Notification>> GetNotifications(List<Guid> parentIds, NotificationGroupType? grouptype)
{
if (parentIds == null || parentIds.Count <= 0)
return new Dictionary<Guid, List<Notification>>();
var notificationsQuery = DbContext.Notifications.Where(x => x.ParentId.HasValue && parentIds.Contains(x.ParentId.Value));
if (grouptype.HasValue)
notificationsQuery = notificationsQuery.Where(x => x.NotificationGroup == (int)grouptype);
return notificationsQuery.OrderBy(x => x.NotificationDate).ToList().GroupBy(x => x.ParentId.Value)
.ToDictionary(x => x.Key, g => g.ToList());
}
public List<Notification> GetNotifications(NotificationGroupType? type)
{
if (type == null)
return new List<Notification>();
var notificationsQuery = DbContext.Notifications.Where(x => x.NotificationGroup == (int)type);
return notificationsQuery.ToList();
}
public List<Notification> GetNotifications(NotificationGroupType? grouptype, NotificationType? type)
{
if (type == null && grouptype == null)
return new List<Notification>();
var notificationsQuery = DbContext.Notifications.Where(x => x.NotificationGroup == (int)grouptype && x.NotificationType == (int)type).OrderBy(x => x.NotificationDate);
return notificationsQuery.ToList();
}
public Dictionary<Guid, List<Notification>> GetNotifications(Guid parentId, NotificationType? type)
{
return GetNotifications(new List<Guid> { parentId }, type);
}
public Dictionary<Guid, List<Notification>> GetNotifications(List<Guid> parentIds, NotificationType? type)
{
if (parentIds == null || parentIds.Count <= 0)
return new Dictionary<Guid, List<Notification>>();
var notificationsQuery = DbContext.Notifications.Where(x => x.ParentId.HasValue && parentIds.Contains(x.ParentId.Value));
if (type.HasValue)
notificationsQuery = notificationsQuery.Where(x => x.NotificationType == (int)type);
return notificationsQuery.OrderBy(x => x.NotificationDate).ToList().GroupBy(x => x.ParentId.Value)
.ToDictionary(x => x.Key, g => g.ToList());
}
public Dictionary<Guid, List<Notification>> GetNotifications(List<Guid> parentIds)
{
if (parentIds == null || parentIds.Count <= 0)
return new Dictionary<Guid, List<Notification>>();
var notificationsQuery = DbContext.Notifications.Where(x => x.ParentId.HasValue && parentIds.Contains(x.ParentId.Value) && x.NotificationViewed != true);
Dictionary<Guid, List<Notification>> dc = notificationsQuery.OrderBy(x => x.NotificationDate).ToList().GroupBy(x => x.ParentId.Value)
.ToDictionary(x => x.Key, g => g.ToList());
dc = CleanOldNotifications(parentIds, dc);
return dc;
}
public List<NotificationControlModel> GetNotificationActions(NotificationType type)
{
var notificationsQuery = DbContext.NotificationControls.Where(x => x.NotificationType == (int)type);
var notificationMethod = new List<NotificationControlModel>();
foreach (var x in notificationsQuery)
{
notificationMethod.Add(new NotificationControlModel()
{
Id = x.Id,
type = (NotificationType)x.NotificationType,
HowToSend = (NotificationHowToSend)x.HowtoSend
});
}
return notificationMethod;
}
public void UpdateNotificationAsViewed(NotificationModel notification)
{
var n= DataTable.FirstOrDefault(x => x.Id == notification.Id);
if (n != null)
{
n.NotificationViewed = true;
DbContext.Entry(n).State = EntityState.Modified;
}
if (IsContextLocal)
DbContext.SaveChanges();
}
public void RemoveNotification(Guid userid, Guid parentId)
{
var notifys = GetNotificationList(userid, parentId);
foreach (var n in notifys)
{
if (n.ExpiresOnDate == null)
{
DbContext.Notifications.Remove(n);
DbContext.Entry(n).State = EntityState.Deleted;
}
}
if (IsContextLocal)
DbContext.SaveChanges();
}
public void UpdateNotificationAsViewed(Guid userid, Guid parentId)
{
var notifys = GetNotificationList(userid, parentId);
foreach (var n in notifys)
{
if (n.ExpiresOnDate == null)
{
n.NotificationViewed = true;
DbContext.Entry(n).State = EntityState.Modified;
}
}
if (IsContextLocal)
DbContext.SaveChanges();
}
private List<Notification>GetNotificationList(Guid userid, Guid parentId)
{
var scenarios = DbContext.Scenarios.Where(x => x.Id == parentId).ToList();
if (scenarios.Count == 0)
scenarios = DbContext.Scenarios.Where(x => x.ParentId == parentId && x.Type == (int) ScenarioType.Portfolio).ToList();
var rt = new List<Notification>();
var userNotifications = DbContext.Notifications.Where(x => x.ParentId == userid && !string.IsNullOrEmpty(x.Link)).ToList();
foreach (var s in scenarios)
{
rt.AddRange(userNotifications.Where(x => x.Link.Contains(s.Id.ToString()) || x.Link.Contains(s.ParentId.ToString())).ToList());
}
return rt;
}
public void UpdateNotificationAsViewedOnLoad(Guid userid, Guid parentId)
{
var notifys = DbContext.Notifications.Where(x => x.ParentId == userid && !string.IsNullOrEmpty(x.Link) &&
x.Link.Contains(parentId.ToString()) && x.DeleteOnPageView == true).ToList();
foreach (var n in notifys)
{
n.NotificationViewed = true;
DbContext.Entry(n).State = EntityState.Modified;
}
if (IsContextLocal)
DbContext.SaveChanges();
}
public List<NotificationControlModel> GetAllNotificationActions()
{
var notificationsQuery = DbContext.NotificationControls;
var notificationMethod = new List<NotificationControlModel>();
foreach (var x in notificationsQuery)
{
notificationMethod.Add(new NotificationControlModel()
{
Id = x.Id,
type = (NotificationType)x.NotificationType,
HowToSend = (NotificationHowToSend)x.HowtoSend
});
}
return notificationMethod;
}
private Dictionary<Guid, List<Notification>> CleanOldNotifications(List<Guid> parentIds, Dictionary<Guid, List<Notification>> list)
{
string userId = HttpContext.Current.User.Identity.GetUserId();
var aspUser = DbContext.AspNetUsers.FirstOrDefault(x => x.Id == userId);
Dictionary <Guid, List<Notification>> newlist = new Dictionary<Guid, List<Notification>>();
if (aspUser != null)
{
var lastlogin = aspUser.LastLoginDate;
var removeAfterDurationstr = new SystemSettingsManager(DbContext).GetSystemSettingsValue((int)SystemSettingType.RemoveNotificationsAfterDays);
int removeAfterDuration = 1;
if (!string.IsNullOrEmpty(removeAfterDurationstr))
Int32.TryParse(removeAfterDurationstr, out removeAfterDuration);
if (removeAfterDuration < 0)
removeAfterDuration = 1;
foreach (Guid id in parentIds)
{
var nl = new List<Notification>();
if (id != Guid.Empty)
{
//get last login date
if (lastlogin != null)
{
if (list.ContainsKey(id))
{
foreach (Notification n in list[id])
{
TimeSpan diff = lastlogin.Value - n.NotificationDate;
if (diff.TotalDays >= removeAfterDuration && n.NotificationViewed)
Delete(n.Id);
else
nl.Add(n);
}
}
}
else
{
if (list.ContainsKey(id))
{
foreach (Notification n in list[id])
{
nl.Add(n);
}
}
}
}
else
nl = list[id];
if (nl.Count > 0)
newlist.Add(id, nl);
}
//aspUser.LastLoginDate = DateTime.Now;
//this.DbContext.SaveChanges();
}
return newlist;
}
public void SendScenarioChangeNotifications(Scenario scenario,Type t, Status s, EntityState state, string url)
{
try
{
if ((s != null && s.Id != Guid.Empty) || (t != null && t.Id != Guid.Empty))
{
var userid = HttpContext.Current.User.Identity.GetID();
var user = this.DbContext.AspNetUsers.Where(x => x.Id == userid).FirstOrDefault();
string Name = "System";
if (user != null)
Name = user.FirstName + " " + user.LastName;
string message = "";
string title = "";
var whos = new List<WorkFlowContactDetails>();
var whot = new List<WorkFlowContactDetails>();
var who = new List<WorkFlowContactDetails>();
Uri uri = null;
if (s != null && s.Id != Guid.Empty)
{
if (s.NotifyOnProjectDelete.HasValue && s.NotifyOnProjectDelete.Value && state == EntityState.Deleted)
{
whos = (new WorkFlowManager(null)).GetContactDetails(s.Id, WorkFlowContactNotificationType.ProjectDelete, scenario.ParentId);
title = scenario.Name + " has been deleted";
message = Name + " has removed the scenario from Prevu®";
url = null;
}
if (s.NotifyOnProjectChange.HasValue && s.NotifyOnProjectChange.Value && state == EntityState.Modified)
{
whos = (new WorkFlowManager(null)).GetContactDetails(s.Id, WorkFlowContactNotificationType.ProjectUpdate, scenario.ParentId);
title = scenario.Name + " has been updated";
message = Name + " has updated this scenario";
}
if (s.NotifyOnProjectCreate.HasValue && s.NotifyOnProjectCreate.Value && state == EntityState.Added)
{
whos = (new WorkFlowManager(null)).GetContactDetails(s.Id, WorkFlowContactNotificationType.ProjectCreate, scenario.ParentId);
title = scenario.Name + " has been created";
message = Name + " has created this scenario";
}
}
if (t != null && t.Id != Guid.Empty)
{
if (t.NotifyOnProjectDelete.HasValue && t.NotifyOnProjectDelete.Value && state == EntityState.Deleted)
{
whot = (new WorkFlowManager(null)).GetContactDetails(t.Id, WorkFlowContactNotificationType.ProjectDelete, scenario.ParentId);
title = scenario.Name + " has been deleted";
message = Name + " has removed the scenario from Prevu®";
}
if (t.NotifyOnProjectChange.HasValue && t.NotifyOnProjectChange.Value && state == EntityState.Modified)
{
whot = (new WorkFlowManager(null)).GetContactDetails(t.Id, WorkFlowContactNotificationType.ProjectUpdate, scenario.ParentId);
title = scenario.Name + " has been updated";
message = Name + " has updated this scenario";
}
if (t.NotifyOnProjectCreate.HasValue && t.NotifyOnProjectCreate.Value && state == EntityState.Added)
{
whot = (new WorkFlowManager(null)).GetContactDetails(t.Id, WorkFlowContactNotificationType.ProjectCreate, scenario.ParentId);
title = scenario.Name + " has been created";
message = Name + " has created this scenario";
}
}
whos.AddRange(whot);
foreach (var w in whos)
{
if (!who.Any(x => x.EmailAddress == w.EmailAddress))
who.Add(w);
}
if (!string.IsNullOrEmpty(url))
uri = new Uri(url);
foreach (var u in who)
{
if (this.DbContext.Notifications.Any(x => x.Title == title && x.Description == message && x.ParentId == u.UserId && x.IdinLink == scenario.Id))
continue;
NotificationModel m = new NotificationModel();
m.title = title;
m.description = message;
m.link = uri;
m.IdinLink = scenario.Id;
m.WorkFlowState = null;
m.WorkFlowLinkName = scenario.Name;
m.NotificationGroup = NotificationGroupType.Project;
m.ParentId = u.UserId;
m.Id = Guid.NewGuid();
m.NotificationViewed = false;
m.ExpiresOnDate = DateTime.Now.AddDays(1);
m.NotificationDate = DateTime.Now;
m.type = NotificationType.User;
(new NotificationManager(null)).Save(m);
}
}
}
catch (Exception dd)
{
LogException(dd);
}
}
public void SendProjectChangeNotifications(Project project, Type t, Status s, EntityState state,string url)
{
try
{
if (s != null && s.Id != Guid.Empty || t != null && t.Id != Guid.Empty)
{
var userid = HttpContext.Current.User.Identity.GetID();
var user = DbContext.AspNetUsers.FirstOrDefault(x => x.Id == userid);
string name = "System";
if (user != null)
name = user.FirstName + " " + user.LastName;
string message = "";
string title = "";
var whos = new List<WorkFlowContactDetails>();
var whot = new List<WorkFlowContactDetails>();
var who = new List<WorkFlowContactDetails>();
Uri uri = null;
if (s != null && s.Id != Guid.Empty)
{
if (s.NotifyOnProjectDelete.HasValue && s.NotifyOnProjectDelete.Value && state == EntityState.Deleted)
{
whos = new WorkFlowManager(null).GetContactDetails(s.Id, WorkFlowContactNotificationType.ProjectDelete, project.Id);
title = project.Name + " has been deleted";
message = name + " has removed the project from Prevu®";
url = null;
}
if (s.NotifyOnProjectChange.HasValue && s.NotifyOnProjectChange.Value && state == EntityState.Modified)
{
whos = new WorkFlowManager(null).GetContactDetails(s.Id, WorkFlowContactNotificationType.ProjectUpdate, project.Id);
title = project.Name + " has been updated";
message = name + " has updated this project";
}
if (s.NotifyOnProjectCreate.HasValue && s.NotifyOnProjectCreate.Value && state == EntityState.Added)
{
whos = new WorkFlowManager(null).GetContactDetails(s.Id, WorkFlowContactNotificationType.ProjectCreate, project.Id);
title = project.Name + " has been created";
message = name + " has created this project";
}
}
if (t != null && t.Id != Guid.Empty)
{
if (t.NotifyOnProjectDelete.HasValue && t.NotifyOnProjectDelete.Value && state == EntityState.Deleted)
{
whot = new WorkFlowManager(null).GetContactDetails(t.Id, WorkFlowContactNotificationType.ProjectDelete, project.Id);
title = project.Name + " has been deleted";
message = name + " has removed the project from Prevu®";
}
if (t.NotifyOnProjectChange.HasValue && t.NotifyOnProjectChange.Value && state == EntityState.Modified)
{
whot = new WorkFlowManager(null).GetContactDetails(t.Id, WorkFlowContactNotificationType.ProjectUpdate, project.Id);
title = project.Name + " has been updated";
message = name + " has updated this project";
}
if (t.NotifyOnProjectCreate.HasValue && t.NotifyOnProjectCreate.Value && state == EntityState.Added)
{
whot = (new WorkFlowManager(null)).GetContactDetails(t.Id, WorkFlowContactNotificationType.ProjectCreate, project.Id);
title = project.Name + " has been created";
message = name + " has created this project";
}
}
whos.AddRange(whot);
foreach (var w in whos)
{
if (who.All(x => x.EmailAddress != w.EmailAddress))
who.Add(w);
}
if (!string.IsNullOrEmpty(url))
uri = new Uri(url);
foreach (var u in who)
{
if (DbContext.Notifications.Any(x => x.Title == title && x.Description == message && x.ParentId == u.UserId && x.IdinLink == project.Id))
continue;
NotificationModel m = new NotificationModel
{
title = title,
description = message,
link = uri,
IdinLink = project.Id,
WorkFlowState = null,
WorkFlowLinkName = project.Name,
NotificationGroup = NotificationGroupType.Project,
ParentId = u.UserId,
Id = Guid.NewGuid(),
NotificationViewed = false,
ExpiresOnDate = DateTime.Now.AddDays(1),
NotificationDate = DateTime.Now,
type = NotificationType.User
};
(new NotificationManager(null)).Save(m);
}
}
}catch (Exception dd)
{
LogException(dd);
}
}
public void ClearExpiredNotifications()
{
var ids= DataTable.Where(x => x.ExpiresOnDate <= DateTime.Now).Select(x=>x.Id).ToList();
foreach (var id in ids)
Delete(id);
}
public void CreateTeamAddNotification(List<WorkFlowContactDetails> who,Guid id, int expiresOnDays, bool expireOnView, string wfstate)
{
try
{
if (id == Guid.Empty)
return;
string title_tmplt = "Your team has been added to {ProjectName}";
string message_tmplt = "{ProjectName} requires your attention";
var projectId = DbContext.Scenarios.Where(x => x.Id == id).Select(x => x.ParentId).FirstOrDefault();
bool sendToProject = false;
string linkName = "Scenario";
Guid idInLink = id;
if (projectId == null || projectId == Guid.Empty)
{
projectId = id;
sendToProject = true;
linkName = "Project";
}
string projectName = DbContext.Projects.Where(x => x.Id == projectId).Select(x => x.Name).FirstOrDefault();
var url = sendToProject ? Session.AbsoluteUrl.EditProjectUrl(projectId, DbContext) : Session.AbsoluteUrl.EditScenarioUrl(id, DbContext);
Uri uri = null;
if (!string.IsNullOrEmpty(url))
uri = new Uri(url);
DateTime? expiresOnDate = null;
if (expiresOnDays > 0)
expiresOnDate = DateTime.Now.AddDays(expiresOnDays);
foreach (var u in who)
{
var title = title_tmplt.Replace("{TeamName}", u.TeamName).Replace("{ProjectName}", projectName);
var message = message_tmplt.Replace("{ProjectName}", projectName);
if (DbContext.Notifications.Any(x => x.Title == title && x.Description == message && x.ParentId == u.UserId && x.IdinLink == projectId && x.NotificationViewed ==false))
continue;
NotificationModel m = new NotificationModel
{
title = title,
description = message,
link = uri,
ExpiresOnDate = expiresOnDate,
IdinLink = idInLink,
WorkFlowState = wfstate,
WorkFlowLinkName = linkName,
NotificationGroup = NotificationGroupType.Project,
ParentId = u.UserId,
Id = Guid.NewGuid(),
NotificationViewed = false,
DeleteOnPageView = expireOnView,
NotificationDate = DateTime.Now,
type = NotificationType.User
};
(new NotificationManager(null)).Save(m);
}
}catch(Exception dd)
{
LogException(dd);
}
}
private void LogException(Exception ex)
{
var sb = new StringBuilder();
sb.AppendLine($"{ex.GetType()}: {ex.Message}");
sb.AppendLine(ex.StackTrace);
var innerCount = 0;
var innerEx = ex;
while (innerEx.InnerException != null && innerCount++ < Constants.MAX_INNER_EXCEPTION_LOG_LEVEL)
{
if (innerEx.Message != innerEx.InnerException.Message)
sb.AppendLine("Inner Exception Message: " + innerEx.InnerException.Message);
innerEx = innerEx.InnerException;
}
var dbEntityValidationException = ex as DbEntityValidationException;
if (dbEntityValidationException != null)
{
foreach (var validationErrors in dbEntityValidationException.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
sb.AppendFormat("Property: {0} Error: {1}", validationError.PropertyName,
validationError.ErrorMessage);
}
}
sb.AppendLine(dbEntityValidationException.StackTrace);
}
if (HttpContext.Current != null)
{
sb.AppendLine();
sb.AppendLine($"URL: {HttpContext.Current.Request.Url}");
sb.AppendLine($"Referrer: {HttpContext.Current.Request.UrlReferrer}");
sb.AppendLine($"QueryString: {HttpContext.Current.Request.QueryString}");
sb.AppendLine($"UserHostAddress: {HttpContext.Current.Request.UserHostAddress}");
sb.AppendLine($"UserAgent: {HttpContext.Current.Request.UserAgent}");
if (HttpContext.Current.Request.Form.Count > 0)
{
sb.AppendLine();
sb.AppendLine("Form:");
foreach (string key in HttpContext.Current.Request.Form.Keys)
{
sb.AppendLine($"{key}: {HttpContext.Current.Request.Form[key]}");
}
}
}
// log error using NLog
Logger.Fatal(sb.ToString());
}
}
}