123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Comal.Classes;
- using InABox.Core;
- namespace Comal.Stores
- {
- internal class LeaveRequestStore : BaseStore<LeaveRequest>
- {
- private void UpdateAssignments(IEnumerable<LeaveRequest> entities)
- {
- var empids = entities.Select(x => x.EmployeeLink.ID).ToArray();
- var ids = entities.Select(x => x.ID).ToArray();
- var empquery = Task.Run(() =>
- {
- return Provider.Query(
- new Filter<Employee>(x => x.ID).InList(empids),
- new Columns<Employee>(x => x.ID, x => x.UsualStart, x => x.UsualFinish)
- );
- });
- var assquery = Task.Run(() =>
- {
- return Provider.Query(
- new Filter<Assignment>(x => x.LeaveRequestLink.ID).InList(ids),
- new Columns<Assignment>(x => x.ID, x => x.LeaveRequestLink.ID, x => x.Date)
- );
- });
- var timequery = Task.Run(() =>
- {
- return Provider.Query(
- new Filter<TimeSheet>(x => x.LeaveRequestLink.ID).InList(ids),
- new Columns<TimeSheet>(x => x.ID, x => x.LeaveRequestLink.ID, x => x.Date)
- );
- });
- Task.WaitAll(empquery, assquery, timequery);
- var assignments = assquery.Result;
- var timesheets = timequery.Result;
- var employees = empquery.Result;
- var Updates = new Dictionary<TimeSheet, Assignment>();
- foreach (var entity in entities)
- {
- var emp = employees.Rows.FirstOrDefault(x => x.Get<Employee, Guid>(c => c.ID).Equals(entity.EmployeeLink.ID))?.ToObject<Employee>();
- var normalStart = emp != null && emp.UsualStart.Ticks > 0 ? emp.UsualStart : new TimeSpan(8, 0, 0);
- var normalFinish = emp != null && emp.UsualFinish.Ticks > 0 ? emp.UsualFinish : normalStart.Add(new TimeSpan(8, 30, 0));
- var leavedays = new List<LeaveDay>();
- if (entity.Status == LeaveRequestStatus.Approved)
- for (var date = entity.From; date <= entity.To; date = date.AddDays(1))
- if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
- {
- var start = date == entity.From && entity.FromTime > normalStart ? entity.FromTime : normalStart;
- var finish = date == entity.To && entity.ToTime < normalFinish ? entity.ToTime : normalFinish;
- leavedays.Add(new LeaveDay(date, start, finish));
- }
- var approval = DateTime.Now;
- var note = string.Format("{0}\nApproved on {1:dd MMM yy} by {2}", entity.Notes, approval, entity.LastUpdateBy);
- foreach (var leaveday in leavedays)
- {
- var assignment = new Assignment();
- var assrow = assignments.Rows.FirstOrDefault(r =>
- r.Get<Assignment, Guid>(c => c.LeaveRequestLink.ID) == entity.ID &&
- r.Get<Assignment, DateTime>(c => c.Date) == leaveday.Date);
- if (assrow != null)
- {
- // Don't Delete this Assignment!
- assignments.Rows.Remove(assrow);
- assignment.ID = assrow.Get<Assignment, Guid>(c => c.ID);
- //assignment.CommitChanges();
- }
- assignment.EmployeeLink.ID = entity.EmployeeLink.ID;
- assignment.Date = leaveday.Date;
- assignment.Start = leaveday.Start;
- assignment.Finish = leaveday.Finish;
- assignment.Duration = leaveday.Finish - leaveday.Start;
- assignment.ActivityLink.ID = entity.LeaveType.ID;
- assignment.Description = note;
- assignment.Completed = approval;
- assignment.LeaveRequestLink.ID = entity.ID;
- var timesheet = new TimeSheet();
- var timerow = timesheets.Rows.FirstOrDefault(r =>
- r.Get<TimeSheet, Guid>(c => c.LeaveRequestLink.ID) == entity.ID && r.Get<TimeSheet, DateTime>(c => c.Date) == leaveday.Date);
- if (timerow != null)
- {
- // Don't Delete this Timesheet!
- timesheets.Rows.Remove(timerow);
- timesheet.ID = timerow.Get<TimeSheet, Guid>(c => c.ID);
- //timesheet.CommitChanges();
- }
- timesheet.EmployeeLink.ID = entity.EmployeeLink.ID;
- timesheet.Date = leaveday.Date;
- timesheet.Start = leaveday.Start;
- timesheet.Finish = leaveday.Finish;
- timesheet.Duration = leaveday.Finish - leaveday.Start;
- timesheet.ActivityLink.ID = entity.LeaveType.ID;
- timesheet.Approved = approval;
- timesheet.ApprovedStart = leaveday.Start;
- timesheet.ApprovedFinish = leaveday.Finish;
- timesheet.ApprovedDuration = leaveday.Finish - leaveday.Start;
- timesheet.Notes = note;
- timesheet.Confirmed = approval;
- timesheet.LeaveRequestLink.ID = entity.ID;
- Updates[timesheet] = assignment;
- }
- }
- var AssignmentsToDelete = new List<Assignment>();
- foreach (var row in assignments.Rows)
- AssignmentsToDelete.Add(new Assignment { ID = row.Get<Assignment, Guid>(x => x.ID) });
- Provider.Delete(AssignmentsToDelete, UserID);
- var TimeSheetsToDelete = new List<TimeSheet>();
- foreach (var row in timesheets.Rows)
- TimeSheetsToDelete.Add(new TimeSheet { ID = row.Get<TimeSheet, Guid>(x => x.ID) });
- Provider.Delete(TimeSheetsToDelete, UserID);
- Provider.Save(Updates.Keys.Where(x => x.IsChanged()));
- foreach (var update in Updates)
- update.Value.TimeSheetLink.ID = update.Key.ID;
- Provider.Save(Updates.Values.Where(x => x.IsChanged()));
- #region Old Code
- //Filter<Assignment> assfilter = new Filter<Assignment>(x => x.LeaveRequestLink.ID).IsEqualTo(entity.ID);
- //assfilter.Ors.Add(new Filter<Assignment>(x => x.Date).IsGreaterThanOrEqualTo(entity.From)
- // .And(x => x.Date).IsLessThanOrEqualTo(entity.To)
- // .And(x=>x.EmployeeLink.ID).IsEqualTo(entity.EmployeeLink.ID)
- //);
- //List<Assignment> assignments = assStore.Load(assfilter).ToList();
- //Logger.Send(LogType.Information, UserID, String.Format("* LeaveRequest: {0} Assignments Found", assignments.Count));
- //List<Assignment> deletes = new List<Assignment>();
- //List<Tuple<TimeSheet, Assignment>> updates = new List<Tuple<TimeSheet, Assignment>>();
- //if (entity.Approved == DateTime.MinValue)
- //{
- // // Clear Out All Assignments / Timesheets for Unapproved Requests
- // foreach (var unapproved in assignments.Where(x => x.LeaveRequestLink.ID.Equals(entity.ID)))
- // deletes.Add(unapproved);
- //}
- //else
- //{
- // TimeSpan normalDuration = normalFinish - normalStart;
- // Logger.Send(LogType.Information, UserID, String.Format("* LeaveRequest: Normal Duration is {0} hours", normalDuration.TotalHours));
- // // Clear out any existing assignments / timesheets that fall outside the requested dates
- // foreach (var excluded in assignments.Where(x => (x.LeaveRequestLink.ID == entity.ID) && ((x.Date.Date < entity.From.Date) || (x.Date.Date > entity.To.Date))))
- // deletes.Add(excluded);
- // Logger.Send(LogType.Information, UserID, String.Format("* LeaveRequest: Scanning from {0} to {1}", entity.From, entity.To));
- // DateTime date = entity.From;
- // while (date <= entity.To)
- // {
- // Logger.Send(LogType.Information, UserID, String.Format("* LeaveRequest: Scanning {0}", date));
- // if ((date.DayOfWeek != DayOfWeek.Saturday) && (date.DayOfWeek != DayOfWeek.Sunday))
- // {
- // var current = assignments.FirstOrDefault(x => x.Date.Date.Equals(date) && x.LeaveRequestLink.ID.Equals(entity.ID));
- // // Are there any other assignments for the current day
- // var others = assignments.Where(x => x.Date.Date.Equals(date) && !x.LeaveRequestLink.ID.Equals(entity.ID));
- // TimeSpan start = date.Equals(entity.From) ? entity.FromTime > normalStart ? entity.FromTime : normalStart : normalStart;
- // TimeSpan balance = (date.Equals(entity.To) ? (entity.ToTime < normalFinish ? entity.ToTime : normalFinish) : normalFinish) - start;
- // Logger.Send(LogType.Information, UserID, String.Format("* LeaveRequest: Starting Balance is {0}", balance.TotalHours));
- // foreach (var other in others)
- // {
- // TimeSpan otherdur = other.Duration;
- // DateTime otherdate = other.Date;
- // if (otherdate.TimeOfDay.Add(otherdur) > start)
- // start = otherdate.TimeOfDay.Add(otherdur);
- // balance = balance.Subtract(otherdur);
- // }
- // Logger.Send(LogType.Information, UserID, String.Format("* LeaveRequest: Finishing Balance is {0}", balance.TotalHours));
- // if (balance.Ticks <= 0L)
- // {
- // // If the day is already fully assigned, skip or delete it
- // if (current != null)
- // deletes.Add(current);
- // }
- // else
- // {
- // if (current == null)
- // {
- // current = new Assignment();
- // current.LeaveRequestLink.ID = entity.ID;
- // current.Date = date;
- // current.Description = String.Format("Leave Request Approved on {0:dd MMM yy HH:mm}", entity.Approved);
- // assignments.Add(current);
- // }
- // current.ActivityLink.ID = entity.LeaveType.ID;
- // current.EmployeeLink.ID = entity.EmployeeLink.ID;
- // current.Date = date;
- // current.Start = start;
- // current.Duration = balance;
- // TimeSheet ts = FindSubStore<TimeSheet>().Load(new Filter<TimeSheet>(x => x.ID).IsEqualTo(current.TimeSheetLink.ID)).FirstOrDefault();
- // if (ts == null)
- // ts = new TimeSheet();
- // ts.EmployeeLink.ID = current.EmployeeLink.ID;
- // ts.JobLink.ID = current.JobLink.ID;
- // ts.ActivityLink.ID = current.ActivityLink.ID;
- // ts.LeaveRequestLink.ID = current.LeaveRequestLink.ID;
- // ts.Date = current.Date.Date;
- // ts.Start = current.Date.TimeOfDay;
- // ts.Finish = current.Date.TimeOfDay.Add(current.Duration);
- // ts.Notes = String.Format("Leave Request Approved on {0:dd MMM yy HH:mm}", entity.Approved);
- // updates.Add(new Tuple<TimeSheet, Assignment>(ts,current));
- // }
- // }
- // date = date.AddDays(1);
- // }
- //}
- //if (deletes.Any())
- // assStore.Delete(deletes, "Removing Assignment from Leave Request");
- //var tsupdates = updates.Where(x => x.Item1.IsChanged());
- //if (tsupdates.Any())
- // FindSubStore<TimeSheet>().Save(tsupdates.Select(x=>x.Item1), "Creating TimeSheet for Leave Request");
- //foreach (var update in updates)
- // update.Item2.TimeSheetLink.ID = update.Item1.ID;
- //var assupdates = updates.Where(x => x.Item2.IsChanged());
- //if (assupdates.Any())
- // assStore.Save(assupdates.Select(x=>x.Item2), "Assignment Generated from Approved Leave Request");
- #endregion
- }
- protected override void OnSave(LeaveRequest entity, ref string auditnote)
- {
- base.OnSave(entity, ref auditnote);
- UpdateAssignments(new[] { entity });
- if (entity.HasOriginalValue(c => c.Status))
- NotifyEmployee(
- entity,
- x => x.EmployeeLink.ID,
- e => e.HasOriginalValue(x => x.Status),
- e => string.Format("Leave Request {0}", e.Status),
- e =>
- {
- var sb = new StringBuilder();
- sb.AppendLine(string.Format(
- "Your Leave Request submitted {0:dd MMM yyy} for {1:dd MMM yy} - {2:dd MMM yy} has changed from {3} to {4}.",
- e.Created,
- e.From,
- e.To,
- e.GetOriginalValue(c => c.Status),
- e.Status
- ));
- if (!string.IsNullOrWhiteSpace(e.StatusNotes))
- sb.AppendLine(string.Format("\nNotes:\n{0}", e.StatusNotes?.Trim()));
- return sb.ToString();
- }
- );
- }
- protected override void OnSave(IEnumerable<LeaveRequest> entities, ref string auditnote)
- {
- base.OnSave(entities, ref auditnote);
- UpdateAssignments(entities);
- }
- private class LeaveDay
- {
- public LeaveDay(DateTime date, TimeSpan start, TimeSpan finish)
- {
- Date = date;
- Start = start;
- Finish = finish;
- }
- public DateTime Date { get; }
- public TimeSpan Start { get; }
- public TimeSpan Finish { get; }
- }
- //protected override void BeforeDelete(LeaveRequest entity)
- //{
- // base.BeforeDelete(entity);
- // entity.Status = LeaveRequestStatus.Rejected;
- // UpdateAssignments(new LeaveRequest[] { entity });
- //}
- }
- }
|