Explorar el Código

Fixed Docking on re-login and fixed private tasks being able to be dragged. Fixed StockHolding issues

Kenric Nugteren hace 2 años
padre
commit
9d6c4a83b0

+ 33 - 24
prs.desktop/Dashboards/DigitalFormsDashboard.xaml.cs

@@ -984,19 +984,22 @@ namespace PRSDesktop
                     if (variables.Any())
                     {
                         var dict = Serialization.Deserialize<Dictionary<string, object>>(form.FormData);
-                        foreach (var key in dict.Keys)
+                        if(dict is not null)
                         {
-                            var variable = variables.FirstOrDefault(x => string.Equals(key, x.Code));
-                            var type = variable?.FieldType();
-                            if (variable != null)
+                            foreach (var key in dict.Keys)
                             {
-                                var value = variable.ParseValue(dict[key]);
-                                var format = variable.FormatValue(value);
-                                var sKey = key.Replace("/", " ");
-                                if (data.Columns.Contains(sKey))
+                                var variable = variables.FirstOrDefault(x => string.Equals(key, x.Code));
+                                var type = variable?.FieldType();
+                                if (variable != null)
                                 {
-                                    dataRow[sKey] = format;
-                                    bHasData = true;
+                                    var value = variable.ParseValue(dict[key]);
+                                    var format = variable.FormatValue(value);
+                                    var sKey = key.Replace("/", " ");
+                                    if (data.Columns.Contains(sKey))
+                                    {
+                                        dataRow[sKey] = format;
+                                        bHasData = true;
+                                    }
                                 }
                             }
                         }
@@ -1004,12 +1007,13 @@ namespace PRSDesktop
                     else
                     {
                         var dict = Serialization.Deserialize<Dictionary<Guid, object>>(form.FormData);
-                        foreach (var key in dict.Keys)
-                            if (data.Columns.Contains(key.ToString()))
-                            {
-                                dataRow[key.ToString()] = dict[key];
-                                bHasData = true;
-                            }
+                        if(dict is not null)
+                            foreach (var key in dict.Keys)
+                                if (data.Columns.Contains(key.ToString()))
+                                {
+                                    dataRow[key.ToString()] = dict[key];
+                                    bHasData = true;
+                                }
                     }
 
 
@@ -1186,24 +1190,29 @@ namespace PRSDesktop
 
         private void DataGrid_CellDoubleTapped(object sender, Syncfusion.UI.Xaml.Grid.GridCellDoubleTappedEventArgs e)
         {
-            if (e.RowColumnIndex.RowIndex == 0)
+            if (e.RowColumnIndex.RowIndex < 2)
                 return;
+            var rowOffset = -2;
+
             var table = (DataGrid.ItemsSource as DataTable)!;
-            var formid = (Guid)table.Rows[e.RowColumnIndex.RowIndex - 1]["Form_ID"];
-            var formdata = (string)table.Rows[e.RowColumnIndex.RowIndex - 1]["FormData"];
-            var id = (Guid)table.Rows[e.RowColumnIndex.RowIndex - 1]["ID"];
+            var formid = (Guid)table.Rows[e.RowColumnIndex.RowIndex + rowOffset]["Form_ID"];
+            var formdata = (string)table.Rows[e.RowColumnIndex.RowIndex + rowOffset]["FormData"];
+            var id = (Guid)table.Rows[e.RowColumnIndex.RowIndex + rowOffset]["ID"];
 
             if (FormType is null) return;
 
             if (IsQAForm)
             {
-                var formData = Serialization.Deserialize<Dictionary<string, object>>(formdata);
                 var values = new Dictionary<Guid, object>();
-                foreach(var (idStr, value) in formData)
+                var formData = Serialization.Deserialize<Dictionary<string, object>>(formdata);
+                if(formData is not null)
                 {
-                    if(Guid.TryParse(idStr, out var codeID))
+                    foreach (var (idStr, value) in formData)
                     {
-                        values[codeID] = value;
+                        if (Guid.TryParse(idStr, out var codeID))
+                        {
+                            values[codeID] = value;
+                        }
                     }
                 }
 

+ 15 - 2
prs.desktop/Grids/KanbanGrid.cs

@@ -159,8 +159,21 @@ namespace PRSDesktop
             else if (name == "Private")
             {
                 var enabled = !Equals(value, true);
-                editor.FindEditor("EmployeeLink.ID").IsEnabled = enabled;
-                editor.FindEditor("ManagerLink.ID").IsEnabled = enabled;
+                var employeeEditor = editor.FindEditor("EmployeeLink.ID");
+                var managerEditor = editor.FindEditor("ManagerLink.ID");
+                employeeEditor.IsEnabled = enabled;
+                managerEditor.IsEnabled = enabled;
+                if (!enabled)
+                {
+                    employeeEditor.SetValue(MyID);
+                    managerEditor.SetValue(MyID);
+
+                    foreach(var item in items)
+                    {
+                        item.EmployeeLink.ID = MyID;
+                        item.ManagerLink.ID = MyID;
+                    }
+                }
             }
 
             return result;

+ 1 - 1
prs.desktop/MainWindow.xaml

@@ -1008,7 +1008,7 @@
 
                 <LayoutRoot.LeftSide>
                     <LayoutAnchorSide>
-                        <LayoutAnchorGroup>
+                        <LayoutAnchorGroup x:Name="DockGroup">
 
                             <LayoutAnchorable
                                 x:Name="ContactDock"

+ 148 - 126
prs.desktop/MainWindow.xaml.cs

@@ -1015,9 +1015,19 @@ namespace PRSDesktop
         private void SetupDock<TSecurityDescriptor>(LayoutAnchorable layout, IDockPanel dock) 
             where TSecurityDescriptor : ISecurityDescriptor, new()
         {
-            layout.IsVisible = Security.IsAllowed<TSecurityDescriptor>();
-            if (layout.IsVisible && (ClientFactory.UserGuid != Guid.Empty))
-                dock.Setup();
+            if (Security.IsAllowed<TSecurityDescriptor>())
+            {
+                if(!DockGroup.Children.Any(x => x == layout))
+                {
+                    DockGroup.Children.Add(layout);
+                }
+                if (layout.IsVisible && (ClientFactory.UserGuid != Guid.Empty))
+                    dock.Setup();
+            }
+            else
+            {
+                DockGroup.RemoveChild(layout);
+            }
         }
 
         private void LoadApplicationState()
@@ -1432,6 +1442,7 @@ namespace PRSDesktop
                 {
                     ExecuteLogout();
                 }
+            ClearTrackingKanban();
 
             ClientFactory.InvalidateUser();
             ConfigureMainScreen();
@@ -1547,6 +1558,88 @@ namespace PRSDesktop
         private void Window_Loaded(object sender, RoutedEventArgs e)
         {
         }
+        private void UnloadWindow()
+        {
+            if (CurrentPanel != null)
+            {
+                Heartbeat(DateTime.Now - CurrentPanel_Ticks, true);
+                try
+                {
+                    CurrentPanel.Shutdown();
+                }
+                catch (Exception e)
+                {
+                    Logger.Send(LogType.Error, ClientFactory.UserID, string.Format("Error in UnloadWindow(): {0}\n{1}", e.Message, e.StackTrace));
+                }
+
+                CurrentPanel_Ticks = DateTime.MinValue;
+                CurrentPanel_Label = "";
+                CurrentPanel_Clicks = 0;
+                CurrentPanel_Keys = 0;
+
+                Title =
+                    $"{CurrentPanel_Label} - {(String.Equals(App.Profile?.ToUpper(), "DEFAULT") ? "PRS Desktop" : App.Profile)} (Release {CoreUtils.GetVersion()})";
+
+                if (CurrentTab != null)
+                {
+                    var border = VisualUtils.EnumChildrenOfType(CurrentTab, typeof(Border)).LastOrDefault();
+                    if (border != null)
+                    {
+                        ((Border)border).Background = new SolidColorBrush(Colors.Transparent);
+                        ((Border)border).BorderBrush = new SolidColorBrush(Colors.Transparent);
+                    }
+
+                    var ReportsBar = FindRibbonBar(CurrentTab, x => x.Header.Equals("Print"));
+                    if (ReportsBar is not null)
+                    {
+                        ReportsBar.Items.Clear();
+                        ReportsBar.Visibility = Visibility.Collapsed;
+                        ReportsBar.IsLauncherVisible = false;
+                    }
+
+                    var ActionBar = FindRibbonBar(CurrentTab, x => x.Header.Equals("Actions"));
+                    if (ActionBar is not null)
+                    {
+                        ActionBar.IsLauncherVisible = false;
+                        foreach (var module in CurrentModules)
+                            ActionBar.Items.Remove(module);
+                    }
+                }
+            }
+
+            CurrentTab = null;
+            CurrentButton = null;
+            CurrentPanel = null;
+            ContentControl.Content = null;
+        }
+
+        private void SecondaryWindow_Click(object sender, RoutedEventArgs e)
+        {
+            if (CurrentPanel == null)
+                return;
+            var id = Guid.NewGuid();
+            var window = new Tuple<string, string, double, double, double, double>(
+                CurrentPanel.GetType().EntityName(),
+                CurrentPanel_Label,
+                Left + 100,
+                Top + 100,
+                Width - 200,
+                Height - 200
+            );
+            App.DatabaseSettings.SecondaryWindows[id] = window;
+            new LocalConfiguration<DatabaseSettings>(App.Profile).Save(App.DatabaseSettings);
+            _secondarywindows[id] = new SecondaryWindow(
+                id,
+                window.Item1,
+                window.Item2,
+                window.Item3,
+                window.Item4,
+                window.Item5,
+                window.Item6
+            );
+            _secondarywindows[id].Show();
+        }
+
 
         private void RibbonWindow_Activated(object sender, EventArgs e)
         {
@@ -1701,88 +1794,6 @@ namespace PRSDesktop
             return null;
         }
 
-        private void UnloadWindow()
-        {
-            if (CurrentPanel != null)
-            {
-                Heartbeat(DateTime.Now - CurrentPanel_Ticks, true);
-                try
-                {
-                    CurrentPanel.Shutdown();
-                }
-                catch (Exception e)
-                {
-                    Logger.Send(LogType.Error, ClientFactory.UserID, string.Format("Error in UnloadWindow(): {0}\n{1}", e.Message, e.StackTrace));
-                }
-
-                CurrentPanel_Ticks = DateTime.MinValue;
-                CurrentPanel_Label = "";
-                CurrentPanel_Clicks = 0;
-                CurrentPanel_Keys = 0;
-
-                Title =
-                    $"{CurrentPanel_Label} - {(String.Equals(App.Profile?.ToUpper(), "DEFAULT") ? "PRS Desktop" : App.Profile)} (Release {CoreUtils.GetVersion()})";
-
-                if (CurrentTab != null)
-                {
-                    var border = VisualUtils.EnumChildrenOfType(CurrentTab, typeof(Border)).LastOrDefault();
-                    if (border != null)
-                    {
-                        ((Border)border).Background = new SolidColorBrush(Colors.Transparent);
-                        ((Border)border).BorderBrush = new SolidColorBrush(Colors.Transparent);
-                    }
-
-                    var ReportsBar = FindRibbonBar(CurrentTab, x => x.Header.Equals("Print"));
-                    if(ReportsBar is not null)
-                    {
-                        ReportsBar.Items.Clear();
-                        ReportsBar.Visibility = Visibility.Collapsed;
-                        ReportsBar.IsLauncherVisible = false;
-                    }
-
-                    var ActionBar = FindRibbonBar(CurrentTab, x => x.Header.Equals("Actions"));
-                    if(ActionBar is not null)
-                    {
-                        ActionBar.IsLauncherVisible = false;
-                        foreach (var module in CurrentModules)
-                            ActionBar.Items.Remove(module);
-                    }
-                }
-            }
-
-            CurrentTab = null;
-            CurrentButton = null;
-            CurrentPanel = null;
-            ContentControl.Content = null;
-        }
-
-        private void SecondaryWindow_Click(object sender, RoutedEventArgs e)
-        {
-            if (CurrentPanel == null)
-                return;
-            var id = Guid.NewGuid();
-            var window = new Tuple<string, string, double, double, double, double>(
-                CurrentPanel.GetType().EntityName(),
-                CurrentPanel_Label,
-                Left + 100,
-                Top + 100,
-                Width - 200,
-                Height - 200
-            );
-            App.DatabaseSettings.SecondaryWindows[id] = window;
-            new LocalConfiguration<DatabaseSettings>(App.Profile).Save(App.DatabaseSettings);
-            _secondarywindows[id] = new SecondaryWindow(
-                id,
-                window.Item1,
-                window.Item2,
-                window.Item3,
-                window.Item4,
-                window.Item5,
-                window.Item6
-            );
-            _secondarywindows[id].Show();
-        }
-
         //private Style tabselected = null;
         //private Style tabunselected = null;
 
@@ -3548,7 +3559,9 @@ namespace PRSDesktop
         }
 
         #endregion
-        
+
+        #region Tracking Kanban
+
         private void SelectTask_Click(object sender, RoutedEventArgs e)
         {
             ContextMenu menu = new ContextMenu();
@@ -3586,6 +3599,50 @@ namespace PRSDesktop
 
         private Assignment? _kanbantrackingassignment = null;
 
+        private void SetTrackingKanban(Guid kanbanID, string header)
+        {
+            SelectedTaskName.Content = header;
+
+            var createNewAssignment = false;
+
+            if (_kanbantrackingassignment is not null)
+            {
+
+                if (_kanbantrackingassignment.Finish < DateTime.Now.TimeOfDay)
+                {
+                    _kanbantrackingassignment.Finish = DateTime.Now.TimeOfDay;
+                    new Client<Assignment>().Save(_kanbantrackingassignment, "");
+                }
+
+                // Update Existing Kanban
+                if (kanbanID == Guid.Empty)
+                    _kanbantrackingassignment = null;
+                else if (_kanbantrackingassignment.Task.ID != kanbanID)
+                {
+                    createNewAssignment = true;
+                }
+            }
+            else if (kanbanID != Guid.Empty)
+            {
+                createNewAssignment = true;
+            }
+
+            if(createNewAssignment)
+            {
+                _kanbantrackingassignment = new Assignment();
+                _kanbantrackingassignment.Task.ID = kanbanID;
+                _kanbantrackingassignment.EmployeeLink.ID = App.EmployeeID;
+                _kanbantrackingassignment.Title = header;
+                _kanbantrackingassignment.Date = DateTime.Today;
+                _kanbantrackingassignment.Start = DateTime.Now.TimeOfDay;
+                _kanbantrackingassignment.Finish = DateTime.Now.TimeOfDay.Add(new TimeSpan(0, 2, 0));
+                new Client<Assignment>().Save(_kanbantrackingassignment, "");
+            }
+        }
+
+        private void ClearTrackingKanban()
+            => SetTrackingKanban(Guid.Empty, "(No Task Selected)");
+
         private void CreateTaskMenu(ItemCollection items, String title, Guid id)
         {
             var item = new MenuItem()
@@ -3597,48 +3654,13 @@ namespace PRSDesktop
             {
                 if (o is not MenuItem menu) return;
 
-                Guid id = (Guid)item.Tag;
-                SelectedTaskName.Content = menu.Header;
-                
-                if (_kanbantrackingassignment is not null)
-                {
-                    
-                    if (_kanbantrackingassignment.Finish < DateTime.Now.TimeOfDay)
-                    {
-                        _kanbantrackingassignment.Finish = DateTime.Now.TimeOfDay;
-                        new Client<Assignment>().Save(_kanbantrackingassignment, "");
-                    }
-
-                    // Update Existing Kanban
-                    if (id == Guid.Empty)
-                        _kanbantrackingassignment = null;
-                    else if (_kanbantrackingassignment.Task.ID != id)
-                    {
-                        _kanbantrackingassignment = new Assignment();
-                        _kanbantrackingassignment.Task.ID = id;
-                        _kanbantrackingassignment.EmployeeLink.ID = App.EmployeeID;
-                        _kanbantrackingassignment.Title = menu.Header.ToString() ?? "";
-                        _kanbantrackingassignment.Date = DateTime.Today;
-                        _kanbantrackingassignment.Start = DateTime.Now.TimeOfDay;
-                        _kanbantrackingassignment.Finish = DateTime.Now.TimeOfDay.Add(new TimeSpan(0,2,0));
-                        new Client<Assignment>().Save(_kanbantrackingassignment, "");
-                    }
-                } 
-                else if (id != Guid.Empty)
-                {
-                    _kanbantrackingassignment = new Assignment();
-                    _kanbantrackingassignment.Task.ID = id;
-                    _kanbantrackingassignment.EmployeeLink.ID = App.EmployeeID;
-                    _kanbantrackingassignment.Title = menu.Header.ToString() ?? "";
-                    _kanbantrackingassignment.Date = DateTime.Today;
-                    _kanbantrackingassignment.Start = DateTime.Now.TimeOfDay;
-                    _kanbantrackingassignment.Finish = DateTime.Now.TimeOfDay.Add(new TimeSpan(0,2,0));
-                    new Client<Assignment>().Save(_kanbantrackingassignment, "");
-                }
+                SetTrackingKanban((Guid)item.Tag, (menu.Header as string) ?? "");
             };
             items.Add(item);
         }
-        
+
+        #endregion
+
         private void DockPanel_OnIsActiveChanged(object? sender, EventArgs e)
         {
             var layout = sender as LayoutAnchorable;
@@ -3650,7 +3672,7 @@ namespace PRSDesktop
             var dock = content is IDockPanel panel ? panel : content?.FindVisualChildren<IDockPanel>().FirstOrDefault();
             if (dock == null)
                 return;
-            if (layout.IsActive)
+            if (layout.IsActive && layout.IsVisible)
                 dock.Refresh();
         }
         

+ 35 - 31
prs.desktop/Panels/Factory/FactoryPanel.xaml.cs

@@ -2244,14 +2244,13 @@ namespace PRSDesktop
 
         private void ReloadPackets(bool reloaddata)
         {
+            using var profiler = new Profiler(true);
             using (new WaitCursor())
             {
                 if (reloaddata)
                 {
                     var sectionid = CurrentSection != null ? CurrentSection.ID : CoreUtils.FullGuid;
 
-                    var query = new MultiQuery();
-
                     var stageflt = new Filter<ManufacturingPacketStage>(x => x.Completed).IsEqualTo(DateTime.MinValue)
                         .Or(x => x.ManufacturingSectionLink.ID).IsEqualTo(CurrentSection.ID);
                     stageflt.Ands.Add(
@@ -2259,7 +2258,7 @@ namespace PRSDesktop
                             .Or(x => x.Parent.Distributed).IsEqualTo(true)
                     );
 
-                    query.Add(
+                    var stageQuery = new KeyedQueryDef<ManufacturingPacketStage>(
                         stageflt,
                         new Columns<ManufacturingPacketStage>(x => x.ID)
                             .Add(x => x.Parent.ID)
@@ -2275,8 +2274,7 @@ namespace PRSDesktop
                             .Add(x => x.Sequence)
                             .Add(x => x.QualityNotes)
                             .Add(x => x.SectionID)
-                            .Add(x => x.ManufacturingSectionLink.ID)
-                    );
+                            .Add(x => x.ManufacturingSectionLink.ID));
 
                     var pktfilter = new Filter<ManufacturingPacket>(x => x.Completed).IsLessThan(DateTime.MinValue.AddDays(1))
                         .And(x => x.Archived).IsLessThan(DateTime.MinValue.AddDays(1))
@@ -2347,50 +2345,56 @@ namespace PRSDesktop
                             .Select(x => x.Name).ToArray()
                         );
 
-                    query.Add(
+                    var pktQuery = new KeyedQueryDef<ManufacturingPacket>(
                         pktfilter,
                         pktcolumns,
-                        new SortOrder<ManufacturingPacket>(x => x.Priority, SortDirection.Descending).ThenBy(x => x.SetoutLink.Number)
-                    );
-
-                    query.Add(
-                        new Filter<DeliveryItem>(x => x.DeliveredDate).IsEqualTo(DateTime.MinValue)
-                            .And(x => x.ManufacturingPacketLink).LinkValid(),
-                        new Columns<DeliveryItem>(
-                            x => x.ID,
-                            x => x.Barcode,
-                            x => x.ManufacturingPacketLink.ID,
-                            x => x.ManufacturingPacketLink.Serial,
-                            x => x.Description,
-                            x => x.ShipmentLink.ID)
-                    );
-
-                    query.Query();
-
-                    Stages = query.Get<ManufacturingPacketStage>();
-                    Packets = query.Get<ManufacturingPacket>();
-                    DeliveryItems = query.Get<DeliveryItem>();
+                        new SortOrder<ManufacturingPacket>(x => x.Priority, SortDirection.Descending)
+                            .ThenBy(x => x.SetoutLink.Number));
+
+                    var results = Client.QueryMultiple(
+                        stageQuery,
+                        pktQuery,
+                        new KeyedQueryDef<DeliveryItem>(
+                            new Filter<DeliveryItem>(x => x.DeliveredDate).IsEqualTo(DateTime.MinValue)
+                                .And(x => x.ManufacturingPacketLink).LinkValid(),
+                            new Columns<DeliveryItem>(
+                                x => x.ID,
+                                x => x.Barcode,
+                                x => x.ManufacturingPacketLink.ID,
+                                x => x.ManufacturingPacketLink.Serial,
+                                x => x.Description,
+                                x => x.ShipmentLink.ID)));
+
+                    Stages = results.Get<ManufacturingPacketStage>();
+                    Packets = results.Get<ManufacturingPacket>();
+                    DeliveryItems = results.Get<DeliveryItem>();
                 }
 
                 var checks = Kanbans.Where(x => x.Checked).Select(x => x.ID).ToArray();
                 Kanbans.Clear();
 
+                var stages = Stages.Rows
+                    .Select(x => new Tuple<Guid, Guid>(
+                        x.Get<ManufacturingPacketStage, Guid>(x => x.Parent.ID),
+                        x.Get<ManufacturingPacketStage, Guid>(x => x.ManufacturingSectionLink.ID)
+                        )).ToList();
                 foreach (var pktrow in Packets.Rows)
                 {
                     var id = pktrow.Get<ManufacturingPacket, Guid>(c => c.ID);
                     var distributed = pktrow.Get<ManufacturingPacket, bool>(c => c.Distributed);
 
-                    var stagerow = Stages.Rows.FirstOrDefault(r => r.Get<ManufacturingPacketStage, Guid>(c => c.Parent.ID).Equals(id)
-                                                                   && r.Get<ManufacturingPacketStage, Guid>(c => c.ManufacturingSectionLink.ID)
-                                                                       .Equals(settings.Section));
+                    var stageIndex = stages.FindIndex(x => x.Item1 == id && x.Item2 == settings.Section);
+                    var stageRow = stageIndex >= 0 ? Stages.Rows[stageIndex] : null;
 
                     //this was commented out previously - leading to the distributed packet issue. Uncommented and tested to work by Nick. Was there a reason for commenting this out?
                     bool bOK = true;
                     if (distributed)
-                        bOK = stagerow?.Get<ManufacturingPacketStage, DateTime>(c => c.Completed).IsEmpty() == true;
+                        bOK = stageRow?.Get<ManufacturingPacketStage, DateTime>(c => c.Completed).IsEmpty() == true;
 
                     if (bOK)
-                        CreateKanban(pktrow, stagerow, checks.Contains(id.ToString()));
+                    {
+                        CreateKanban(pktrow, stageRow!, checks.Contains(id.ToString()));
+                    }
                 }
 
                 var sorted = Kanbans.OrderBy(x => x.Assignee).ThenByDescending(x => x.Tags.Length).ThenBy(x => x.DueDate).ThenBy(x => x.JobName);

+ 3 - 1
prs.desktop/Panels/Products/Locations/StockHoldingGrid.cs

@@ -82,6 +82,7 @@ namespace PRSDesktop
             HiddenColumns.Add(x => x.Dimensions.Width);
             HiddenColumns.Add(x => x.Dimensions.Height);
             HiddenColumns.Add(x => x.Dimensions.Quantity);
+            HiddenColumns.Add(x => x.Dimensions.Value);
 
 
             _employeeid = GetEmployeeID();
@@ -360,8 +361,9 @@ namespace PRSDesktop
             movement.Style.ID = holding.Style.ID;
             movement.Style.Code = holding.Style.Code;
             movement.Employee.ID = _employeeid;
+            // Must happen before Received gets set so that OnPropertyChanged has stuff to work with and thus Qty is not zero.
+            movement.Dimensions.CopyFrom(holding.Dimensions); 
             movement.Received = holding.Units;
-            movement.Dimensions.CopyFrom(holding.Dimensions);
             movement.IsTransfer = true;
 
             movement.CommitChanges();

+ 2 - 2
prs.desktop/Panels/Products/Locations/StockMovementGrid.cs

@@ -123,7 +123,7 @@ namespace PRSDesktop
             return true;
         }
 
-        protected override void Reload(Filters<StockMovement> criteria, Columns<StockMovement> columns, ref SortOrder<StockMovement> sort,
+        protected override void Reload(Filters<StockMovement> criteria, Columns<StockMovement> columns, ref SortOrder<StockMovement>? sort,
             Action<CoreTable, Exception> action)
         {
             if (!AllowNullLocation && (Location == null || Location.ID == Guid.Empty))
@@ -155,7 +155,7 @@ namespace PRSDesktop
                 criteria.Add(new Filter<StockMovement>(x => x.Date).IsGreaterThanOrEqualTo(StartDate));
 
             if (!DateTime.Equals(EndDate, DateTime.MaxValue))
-                criteria.Add(new Filter<StockMovement>(x => x.Date).IsGreaterThanOrEqualTo(StartDate));
+                criteria.Add(new Filter<StockMovement>(x => x.Date).IsLessThan(EndDate.Date.AddDays(1)));
 
             sort = new SortOrder<StockMovement>(x => x.Date, SortDirection.Descending).ThenBy(x => x.System);
             base.Reload(criteria, columns, ref sort, action);

+ 21 - 5
prs.desktop/Panels/Tasks/TasksByUserControl.xaml.cs

@@ -509,6 +509,11 @@ namespace PRSDesktop
                 Items = Items.Where(x => x.Search(searches));
             }
 
+            if(object.Equals(Kanban.ItemsSource, Items))
+            {
+                // Triggers a refresh.
+                Kanban.ItemsSource = null;
+            }
             Kanban.ItemsSource = Items;
         }
 
@@ -588,19 +593,30 @@ namespace PRSDesktop
             {
                 var target = e.TargetColumn.Categories;
                 var targetCategory = e.TargetKey;
-                var models = SelectedModels(e.SelectedCard.Content as TaskModel).Where(x => !Equals(x.Category, target)).ToArray();
+                var models = SelectedModels(e.SelectedCard.Content as TaskModel).Where(x => !Equals(x.Category, target)).ToList();
                 if (!models.Any())
                     return;
-                var kanbans = Host.LoadKanbans(models, new Columns<Kanban>(x => x.ID, x => x.EmployeeLink.ID));
+                var kanbans = Host.LoadKanbans(models, new Columns<Kanban>(x => x.ID, x => x.EmployeeLink.ID, x => x.Private, x => x.Number));
                 var subscribers = new KanbanSubscriberSet(kanbans.Select(x => x.ID));
                 var targetID = Guid.Parse(target);
+
+                var updated = new List<Kanban>();
                 foreach (var kanban in kanbans)
                 {
-                    kanban.EmployeeLink.ID = targetID;
-                    subscribers.EnsureAssignee(kanban.ID, kanban.EmployeeLink.ID);
+                    if (!kanban.Private)
+                    {
+                        kanban.EmployeeLink.ID = targetID;
+                        subscribers.EnsureAssignee(kanban.ID, kanban.EmployeeLink.ID);
+                        updated.Add(kanban);
+                    }
+                    else
+                    {
+                        MessageBox.Show($"Cannot change assignee for task {kanban.Number} because it is private.");
+                        models.RemoveAll(x => x.ID == kanban.ID.ToString());
+                    }
                 }
 
-                new Client<Kanban>().Save(kanbans, string.Format("Task Employee Updated to {0}", target), (o, err) => { });
+                new Client<Kanban>().Save(updated, string.Format("Task Employee Updated to {0}", target), (o, err) => { });
                 subscribers.Save(false);
                 foreach (var model in models)
                 {