Преглед изворни кода

Calendar: Implemented filling block functionality.

Kenric Nugteren пре 4 недеља
родитељ
комит
b079ad44f7
1 измењених фајлова са 100 додато и 7 уклоњено
  1. 100 7
      prs.desktop/Components/Calendar/Calendar.xaml.cs

+ 100 - 7
prs.desktop/Components/Calendar/Calendar.xaml.cs

@@ -616,12 +616,16 @@ namespace PRSDesktop
             using (EventSuppressor.All<Suppress>())
             {
                 InitializeComponent();
+
                 _splitPanel.DataContext = this;
 
                 StartHour = 0;
                 EndHour = 24;
             }
 
+            CalendarControl.GetFillBlockStart = GetFillBlockStart;
+            CalendarControl.GetFillBlockEnd = GetFillBlockEnd;
+
             CalendarControl.RowInterval = TimeIntervalToTimeSpan(TimeInterval);
             CalendarViewSelector.ItemsSource = new List<KeyValuePair<CalendarViewType, string>>
             {
@@ -632,7 +636,7 @@ namespace PRSDesktop
             CalendarViewSelector.DisplayMemberPath = "Value";
             CalendarViewSelector.SelectedValuePath = "Key";
         }
-        
+
         public virtual void Setup()
         {
             using (new EventSuppressor(Suppress.Settings, Suppress.Refresh, Suppress.Events))
@@ -1028,6 +1032,58 @@ namespace PRSDesktop
             bColumnsLoaded = true;
         }
 
+        private (TimeSpan Start, TimeSpan End)? GetFillBlock(DateTime date, object? column, TimeSpan time)
+        {
+            if (column is not Employee employee) return null;
+
+            if ((BackgroundType == CalendarBackgroundType.Roster) ||
+                ((BackgroundType == CalendarBackgroundType.Automatic) && (date >= DateTime.Today)))
+            {
+                var roster = RosterUtils.GetRoster(EmployeeSelector.GetRoster(employee.ID), employee.RosterStart, date);
+                if (roster is null) return null;
+
+                var blocks = roster.GetBlocks(date, TimeSpan.Zero, TimeSpan.FromDays(1));
+                var block = blocks.FirstOrDefault(x => x.Start <= time && time <= x.Finish);
+                if (block is null) return null;
+
+                return (block.Start, block.Finish);
+            }
+            else
+            {
+                foreach (var timesheet in _timesheets.Where(t => (t.EmployeeLink.ID == employee.ID) && (t.Date == date)))
+                {
+                    var start = !timesheet.Approved.IsEmpty()
+                        ? timesheet.ApprovedStart
+                        : timesheet.Start;
+                    var finish = !timesheet.Approved.IsEmpty()
+                        ? timesheet.ApprovedFinish
+                        : timesheet.Finish;
+                    if(finish == default)
+                    {
+                        finish = TimeSpan.FromHours(24);
+                    }
+                    if(start <= time && time <= finish)
+                    {
+                        return (start, finish);
+                    }
+                } 
+
+                return null;
+            }
+        }
+
+        private TimeSpan? GetFillBlockStart(DateTime date, object? column, TimeSpan time)
+        {
+            var block = GetFillBlock(date, column, time);
+            return block?.Start;
+        }
+
+        private TimeSpan? GetFillBlockEnd(DateTime date, object? column, TimeSpan time)
+        {
+            var block = GetFillBlock(date, column, time);
+            return block?.End;
+        }
+
         private void Calendar_BlockHeld(object sender, CalendarBlockEventArgs e)
         {
             Calendar_BlockRightClicked(sender, e);
@@ -1047,7 +1103,25 @@ namespace PRSDesktop
                     e.Menu.AddSeparator();
                     e.Menu.AddItem("Copy Assignment", null, appointment.Model, CopyAssignment);
                     e.Menu.AddSeparator();
-                    e.Menu.AddItem("Fill Available Time", null, appointment.Model, FillAssignment);
+                    e.Menu.AddItem("Fill Available Time", null, () =>
+                    {
+                        if(CalendarControl.GetEmptySpace(e.Point, out var start, out var end, time: e.Start, exclude: [appointment]))
+                        {
+                            var time = AssignmentType switch
+                            {
+                                CalendarAssignmentType.Automatic or CalendarAssignmentType.Actual => appointment.Model.Actual,
+                                CalendarAssignmentType.Booked => appointment.Model.Booked,
+                                _ => throw new InvalidEnumException<CalendarAssignmentType>(AssignmentType)
+                            };
+                            if(start is null || end is null)
+                            {
+                                var block = GetFillBlock(e.Date, e.Column, e.Start);
+                                time.Start = start ?? block?.Start ?? time.Start;
+                                time.Finish = end ?? block?.End ?? time.Finish;
+                            }
+                            Client.Save(appointment.Model, "Adjusted to fill time");
+                        }
+                    });
                 }
                 e.Menu.AddSeparatorIfNeeded();
             
@@ -1081,6 +1155,30 @@ namespace PRSDesktop
                 createmenu.AddItem("New Assignment", null, slot, slot => CreateAssignment(slot));
                 createmenu.AddItem("New Meeting", null, slot, CreateMeeting);
 
+                CalendarTimeSlot FillSlot()
+                {
+                    if(CalendarControl.GetEmptySpace(e.Point, out var start, out var end))
+                    {
+                        if(start is null || end is null)
+                        {
+                            var block = GetFillBlock(e.Date, e.Column, CalendarControl.GetTime(e.Point));
+                            return new(employee.ID, e.Date, start ?? block?.Start ?? e.Start, end ?? block?.End ?? e.End);
+                        }
+                        else
+                        {
+                            return new(employee.ID, e.Date, start.Value, end.Value);
+                        }
+                    }
+                    else
+                    {
+                        return slot;
+                    }
+                }
+
+                var fillMenu = e.Menu.AddItem("Fill...", null, null);
+                fillMenu.AddItem("New Assignment", null, () => CreateAssignment(FillSlot()));
+                fillMenu.AddItem("New Meeting", null, () => CreateMeeting(FillSlot()));
+
                 if (_copiedmodel != null)
                 {
                     e.Menu.AddSeparator();
@@ -1221,11 +1319,6 @@ namespace PRSDesktop
 
         }
 
-        private void FillAssignment(Assignment model)
-        {
-            MessageBox.Show("Not Yet Implemented");
-        }
-
         private void EditAssignment(Assignment model)
         {
             var grid = CheckGrid(ref ag);