public IActionResult Post(Guid rosterId, string rosterCode, [FromBody] StaffMember item) { if (item == null || item.RosterId != rosterId || item.StaffMemberCode != rosterCode) { return(BadRequest()); } var serverStaffMember = ServerStaffMember.FromStaffMember(item); _context.Staff.Add(serverStaffMember); _context.SaveChanges(); return(CreatedAtRoute(new { item.RosterId, item.StaffMemberCode }, serverStaffMember)); }
public IActionResult Put(Guid rosterId, string abbreviation, [FromBody] StaffMember item) { if (item == null || item.StaffMemberCode != abbreviation || item.RosterId != rosterId) { return(BadRequest()); } var existing = _context.Staff.Find(rosterId, abbreviation); if (existing == null) { return(NotFound()); } var serverStaffMember = ServerStaffMember.FromStaffMember(item); _context.Entry(existing).CurrentValues.SetValues(serverStaffMember); _context.SaveChanges(); return(new NoContentResult()); }
public IEnumerable <Event> GetCalls(ServerStaffMember staffMember, int daysPriorToCommence = 14) { var datePrior = DateTime.Today - TimeSpan.FromDays(daysPriorToCommence); var dpt = staffMember.Roster; var userAppointments = (from a in _context.Appointments .Include("VersionCreated").Include("VersionCancelled") .AsNoTracking() where a.RosterId == staffMember.RosterId && a.StaffMemberCode == staffMember.StaffMemberCode && a.Start > datePrior orderby a.Start select a).ToLookup(a => new { Cancelled = a.VersionCancelledId != null, a.IsLeaveShift, a.Description }); List <Event> leave = new List <Event>(); List <Event> cancelled = new List <Event>(); List <Event> shifts = new List <Event>(); foreach (var g in userAppointments) { if (g.Key.Cancelled) { cancelled.AddRange(MapCancelled(g)); } else if (g.Key.IsLeaveShift) { leave.AddRange(MapLeave(g)); } else { shifts.AddRange(MapCalls(g)); } } shifts.Sort(SortEvents); var datePred = PredicateBuilder.New <ServerAppointment>(); foreach (var s in shifts.ConsecutiveGroup((prior, curr) => curr.DtStart.AsSystemLocal <= prior.DtEnd.AsSystemLocal)) { var start = s[0].DtStart.AsSystemLocal; var finish = s[s.Count - 1].DtEnd.AsSystemLocal; datePred = datePred.Or(a => a.Start <finish && a.Finish> start); } var colleagues = (_context.Appointments .Include("VersionCreated") .Include("StaffMember") .AsNoTracking() .Where(a => a.RosterId == staffMember.RosterId && a.VersionCancelledId == null && !a.IsLeaveShift && a.StaffMemberCode != staffMember.StaffMemberCode) .Where(datePred) .OrderBy(a => a.Start) .ToList()); var debugColleagues = new List <ServerAppointment>(); var badDate = new DateTime(2017, 5, 8, 8, 0, 0); foreach (var s in shifts.ConsecutiveGroup((prior, curr) => curr.DtStart.AsSystemLocal <= prior.DtEnd.AsSystemLocal)) { var start = s[0].DtStart.AsSystemLocal; var finish = s[s.Count - 1].DtEnd.AsSystemLocal; if (colleagues.Any(a => a.Start < finish && a.Finish > start && a.Start == badDate)) { Console.WriteLine(badDate); } } int colleagueIndex = 0; foreach (var s in shifts) { DateTime shiftFinish = s.DtEnd.AsSystemLocal; int length = 0; int startIndex = colleagueIndex; while (colleagueIndex < colleagues.Count && colleagues[colleagueIndex].Start < shiftFinish) { ++length; ++colleagueIndex; } var shiftColleagues = colleagues.GetRange(startIndex, length); Debug.Assert(shiftColleagues.All(c => c.Finish > s.DtStart.AsSystemLocal && c.Start < s.DtEnd.AsSystemLocal), "colleagues working outside date range"); UpdateEventWithColleaguesData(s, shiftColleagues); if (colleagueIndex >= colleagues.Count) { break; } } Debug.Assert(colleagueIndex >= colleagues.Count, "All colleagues not assigned"); return(shifts.Concat(leave).Concat(cancelled).ToList()); }
public ShiftModelErrorCollection UpsertAppointments(IEnumerable <Appointment> dayModels, Guid rosterId, bool createStaff = false) { var returnVar = new ShiftModelErrorCollection { ModelErrors = new List <ShiftModelError>() }; if (!dayModels.Any()) { return(returnVar); } CalendarVersion _version = null; var getVersion = new Func <CalendarVersion>(() => { if (_version == null) { _version = new CalendarVersion { Created = DateTime.Now }; _context.Versions.Add(_version); } return(_version); }); var staff = _context.Staff.Where(s => s.RosterId == rosterId).ToDictionary(s => s.StaffMemberCode); var shifts = _context.Shifts.Where(s => s.RosterId == rosterId).ToDictionary(s => s.Code); //to do concurrency/lock rows //https://msdn.microsoft.com/en-us/library/dn456843(v=vs.113).aspx var lastViewedVersionId = staff.Values.Max(s => s.LastViewedVersionId) ?? int.MinValue; var newAppointments = dayModels.SelectMany(dms => { if (shifts.TryGetValue(dms.ShiftCode, out ServerShift shift)) { var startDate = dms.Date + shift.ShiftStart; var finishDate = startDate + shift.Duration; var apptList = new List <ServerAppointment>(dms.StaffInitials.Length); foreach (var si in dms.StaffInitials) { if (staff.TryGetValue(si, out ServerStaffMember sm)) { apptList.Add(new ServerAppointment { Start = startDate, Finish = finishDate, Staff = sm, RosterId = rosterId, Description = shift.Description, IsLeaveShift = shift.LeaveShift }); } else if (createStaff) { var newStaff = new ServerStaffMember { StaffMemberCode = si, RosterId = rosterId }; _context.Staff.Add(newStaff); staff.Add(si, newStaff); } else { //_context.Staff.Add(new ServerStaffMember { RosterId = rosterId, RosterCode = si }); returnVar.ModelErrors.Add(new ShiftModelError { ErrorType = ShiftModelError.ShiftErrorType.StaffInitialsNotFound, ErrorModel = dms }); } } return(apptList); } else { returnVar.ModelErrors.Add(new ShiftModelError { ErrorModel = dms, ErrorType = ShiftModelError.ShiftErrorType.ShiftCodeNotFound }); return(Enumerable.Empty <ServerAppointment>()); } }).ToDictionary(a => new { a.Start, a.Staff.StaffMemberCode, a.Description }); var existingAppointments = _context.Appointments .Where(ContainsDates(newAppointments.Values.Select(a => a.Start))) .Where(a => a.VersionCancelledId == null && rosterId == a.RosterId) .ToList(); //logic: //existing date/description/staffmember not matched to newly created in same date range -> delete or set VersionCancelled //is matched - do nothing //remainder - add foreach (var existAppt in existingAppointments) { if (!newAppointments.Remove(new { existAppt.Start, existAppt.Staff.StaffMemberCode, existAppt.Description })) { if (lastViewedVersionId >= existAppt.VersionCreatedId) { existAppt.VersionCancelled = getVersion(); } else { _context.Appointments.Remove(existAppt); } } } foreach (var newAppt in newAppointments.Values) { newAppt.VersionCreated = getVersion(); _context.Appointments.Add(newAppt); } try { _context.SaveChanges(); } catch (System.Data.DataException e) { returnVar.DatabaseException = e; } return(returnVar); }