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());
        }
예제 #3
0
        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());
        }
예제 #4
0
        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);
        }