using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Comal.Classes; using Comal.Stores; using InABox.Core; using InABox.Scripting; namespace PRSStores { internal class LeaveRequestStore : BaseStore { protected override void OnSave(LeaveRequest entity, ref string auditnote) { base.OnSave(entity, ref auditnote); if (entity.HasOriginalValue(c => c.Status)) NotifyEmployee( entity, x => x.EmployeeLink.ID, e => e.HasOriginalValue(x => x.Status), e => $"Leave Request {e.Status}", e => { var sb = new StringBuilder(); sb.AppendLine( $"Your Leave Request submitted {e.Created:dd MMM yyy} for {e.From:dd MMM yy} - {e.To:dd MMM yy} has changed from {e.GetOriginalValue(c => c.Status)} to {e.Status}."); if (!string.IsNullOrWhiteSpace(e.StatusNotes)) sb.AppendLine($"\nNotes:\n{e.StatusNotes?.Trim()}"); return sb.ToString(); } ); } protected override void AfterSave(LeaveRequest entity) { base.AfterSave(entity); if (entity.HasOriginalValue(c => c.EmployeeLink.ID) || entity.HasOriginalValue(c=>c.ApprovalSet.ID)) UpdateLeaveRequestApprovals(entity); } private void ClearLeaveRequestApprovals(LeaveRequest request) { // We need to clear all automatic bill approvals. var approvals = Provider.Query( new Filter(x => x.LeaveRequest.ID).IsEqualTo(request.ID) .And(x => x.IsCustom).IsEqualTo(false), Columns.Required().Add(x => x.ID)) .ToList(); Provider.Delete(approvals, UserID); } private void UpdateLeaveRequestApprovals(LeaveRequest request) { if (request.ID == Guid.Empty) return; if(request.ApprovalSet.ID == Guid.Empty) { ClearLeaveRequestApprovals(request); return; } var setEmployees = Provider.Query( new Filter(x => x.ApprovalSet.ID).IsEqualTo(request.ApprovalSet.ID), Columns.None().Add(x => x.Employee.ID), new SortOrder(x => x.Sequence)) .ToArray(); var approvals = Provider.Query( new Filter(x => x.LeaveRequest.ID).IsEqualTo(request.ID), Columns.Required().Add(x => x.Employee.ID).Add(x => x.IsCustom).Add(x => x.Status)) .ToList(); try { var customApprovals = new List(); foreach(var approval in approvals) { if (approval.IsCustom) { customApprovals.Add(approval); } else { if(approval.Status != LeaveRequestApprovalStatus.NotYetApproved) { // These really are custom approvals for our purposes, since they've been modified. customApprovals.Add(approval); } } } // Build up the automatic list. var autoApprovals = new List(); foreach(var employee in setEmployees) { var approval = new LeaveRequestApproval(); approval.Employee.CopyFrom(employee.Employee); approval.IsCustom = false; autoApprovals.Add(approval); } if(LeaveRequestApprovalSetStore.GetUpdateApprovalsScript(request.ApprovalSet.ID) is ScriptDocument script) { script.Execute(methodname: LeaveRequestApprovalSet.UpdateApprovalsMethodName, parameters: [request, autoApprovals]); } // Now, we have to merge the custom and auto lists, only saving auto approvals if there are no custom ones for that employee. var toAdd = new List(); var toRemove = new List(); var newList = customApprovals.ToList(); foreach(var approval in autoApprovals) { newList.Add(approval); if (!approvals.Any(x => x.Employee.ID == approval.Employee.ID)) { toAdd.Add(approval); } } foreach(var approval in approvals) { if (!newList.Any(x => x.Employee.ID == approval.Employee.ID)) { toRemove.Add(approval); } } foreach(var approval in toAdd) { approval.LeaveRequest.ID = request.ID; } Provider.Save(toAdd); Provider.Delete(toRemove, UserID); } catch(Exception e) { CoreUtils.LogException(UserID, e, "Error running leave request approval script"); } } } }