public void Update(FeeblDataContext ctx, bool isMet, string remark, int?counter) { // if the demand was still not met (it failed previously and is still failed) and it's priority is Normal or higher // we will initiate a ticket log for support if (!IsMet && !isMet && Priority >= (int)Lists.Priority.Normal) { // find the last log of state change for this demand var log = (from h in Histories orderby h.HistoryID descending select h).FirstOrDefault(); // create a buffer of MaxRunTime ?? 30 minutes and check the IsExported flag to prevent doubles if (log != null && log.Status == "Failed" && !log.IsExported && log.CreationTime <= DateTime.UtcNow.AddMinutes(-(MaxRunTime ?? 30))) { var subject = string.Format("{0} failed for {1} @ {2}", Process.Name, Process.Application.Name, Process.Customer.Name); if (Priority >= (int)Lists.Priority.High) { subject = "[PRIO: HIGH] " + subject; } var message = counter.HasValue ? string.Format("{0} / {1}", Methods.GetCounterValue(counter.Value), Methods.GetCounterValue(QuantityValue)) : string.Format("{0}, last run {1}", NextRunTime.Value.ToCET().ToString("MM/dd HH:mm"), Process.LastRunTime.HasValue ? Process.LastRunTime.Value.ToCET().ToString("MM/dd HH:mm") : "never"); var subscribers = Process.UserSubscriptions.Select(s => s.User.Email).Distinct().ToArray(); // include related users, in case of backup procedures var related = (from p in ctx.Processes from s in p.UserSubscriptions where p.CustomerID == Process.CustomerID && p.ApplicationID == Process.ApplicationID select s.User.Email).Distinct().ToArray(); var mail = new Email { Subject = subject, Body = $"{subject}<br /><br />Failed at {message}<br /><br />{Comment}<br /><br />Subscribers: {string.Join(",", subscribers)}<br />Related: {string.Join(",", related)}<br /><br />{Methods.GetUrl($"Demand?processID={ProcessID}")}" }; mail.AddReceipient("*****@*****.**"); mail.Send(); log.IsExported = true; } } // if there was a change in condition (we either failed a green process or just resolved a red process) // make sure the proper users are notified of this change else if (IsMet != isMet) { var diff = !isMet ? "Failed" : "Resolved"; ctx.Histories.InsertOnSubmit(new History { Counter = counter, CreationTime = DateTime.UtcNow, Demand = this, DemandID = DemandID, Status = diff, Remark = remark }); var emails = (from s in Process.UserSubscriptions where s.User.Email != null && s.User.Email != string.Empty && s.Email select s.User.Email).Distinct().ToList(); var mobiles = (from s in Process.UserSubscriptions where s.User.Mobile != null && s.User.Mobile != string.Empty && s.SMS select s.User.Mobile).Distinct().ToList(); // if this is triggered from a user itself (through Ignore) // remove this user from SMS notification if applicable if (FeeblPrincipal.Current != null) { var user = (FeeblIdentity)FeeblPrincipal.Current.Identity; if (!string.IsNullOrEmpty(user.Mobile)) { mobiles.Remove(user.Mobile); } } var subject = string.Format("{0} {1} for {2} @ {3}", Process.Name, diff.ToLower(), Process.Application.Name, Process.Customer.Name); var detail = counter.HasValue ? string.Format("{0} / {1}", Methods.GetCounterValue(counter.Value), Methods.GetCounterValue(QuantityValue)) : isMet ? string.Format("at {1} - next @{0}", NextRunTime.Value.ToCET().ToString("MM/dd HH:mm"), Process.LastRunTime.HasValue?Process.LastRunTime.Value.ToCET().ToString("MM/dd HH:mm") : "never") : string.Format("{0}, last run {1}", NextRunTime.Value.ToCET().ToString("MM/dd HH:mm"), Process.LastRunTime.HasValue ? Process.LastRunTime.Value.ToCET().ToString("MM/dd HH:mm") : "never"); if (!string.IsNullOrEmpty(remark)) { detail += ", " + remark; } if (emails.Any()) { var mail = new Email { Subject = subject, Body = detail + "<br /><br />" + Comment + "<br /><br />" + Methods.GetUrl($"Demand?processID={ProcessID}") }; foreach (var to in emails) { mail.AddReceipient(to); } mail.Send(); } if (mobiles.Any() && Priority >= (int)Lists.Priority.Low) { var sms = new SmsMessage { Body = subject + ", " + detail }; if (sms.Body.Length > 160) { sms.Body = subject; } if (sms.Body.Length > 160) { sms.Body = string.Format("{0} {1}!", Process.Name, diff.ToLower()); } foreach (var to in mobiles) { sms.AddReceipient(to); } sms.Send(); } var slack = new Slack { Body = string.Format("<{0}|{1}>, {2}", Methods.GetUrl($"Demand?processID={ProcessID}"), subject, detail), Success = isMet }; slack.AddReceipient("feebl"); slack.AddReceipient(Process.Application.Name.ToLower()); slack.AddReceipient(Process.Customer.Name.ToLower()); slack.Send(); IsMet = isMet; } ErrorMessage = (!isMet && counter.HasValue) ? string.Format("{0} / {1}", Methods.GetCounterValue(counter.Value), Methods.GetCounterValue(QuantityValue)) : string.Empty; }