|  | @@ -37,10 +37,9 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |      //Button ReserveButton = null;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private Button TransferButton;
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  |      private Button RecalculateButton;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      private Button AdjustValueButton;
 | 
	
		
			
				|  |  | +    private Button RelocateButton;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public StockHoldingGrid() : base()
 | 
	
		
			
				|  |  |      {         
 | 
	
	
		
			
				|  | @@ -66,6 +65,9 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          TransferButton.Margin = new Thickness(20, TransferButton.Margin.Top, TransferButton.Margin.Right, TransferButton.Margin.Bottom);
 | 
	
		
			
				|  |  |          TransferButton.IsEnabled = false;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        RelocateButton = AddButton("Relocate", PRSDesktop.Resources.box.AsBitmapImage(), RelocateStock);
 | 
	
		
			
				|  |  | +        RelocateButton.IsEnabled = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          AdjustValueButton = AddButton("Adjust Value", PRSDesktop.Resources.receipt.AsBitmapImage(), AdjustValues,
 | 
	
		
			
				|  |  |              DynamicGridButtonPosition.Right);
 | 
	
		
			
				|  |  |          AdjustValueButton.Margin = new Thickness(AdjustValueButton.Margin.Left, AdjustValueButton.Margin.Top, 10, AdjustValueButton.Margin.Bottom);
 | 
	
	
		
			
				|  | @@ -144,7 +146,6 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          return false;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  |      private bool RecalculateHoldings(Button arg1, CoreRow[] arg2)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          Dictionary<String, int> messages = new();
 | 
	
	
		
			
				|  | @@ -281,8 +282,6 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          options.FilterRows = true;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      private void BuildMenu(DynamicMenuColumn column, CoreRow? row)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          if (row is null) return;
 | 
	
	
		
			
				|  | @@ -335,6 +334,45 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private void DoTransfer(StockHolding holding, IList<JobRequisitionItem> requiitems, Func<JobRequisitionItem, double?> getQuantity, Action<JobRequisitionItem, StockMovement, StockMovement> modify)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        var updates = new List<StockMovement>();
 | 
	
		
			
				|  |  | +        DoTransfer(holding, requiitems, getQuantity, modify, updates);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        SaveBatch(StockMovementBatchType.Transfer, updates);
 | 
	
		
			
				|  |  | +        DoChanged();
 | 
	
		
			
				|  |  | +        Refresh(false, true);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static void DoTransfer(StockHolding holding, IList<JobRequisitionItem> requiitems, Func<JobRequisitionItem, double?> getQuantity, Action<JobRequisitionItem, StockMovement, StockMovement> modify, List<StockMovement> updates)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        foreach(var requi in requiitems)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            var qty = getQuantity(requi);
 | 
	
		
			
				|  |  | +            if (!qty.HasValue || qty.Value <= 0) continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            var mout = holding.CreateMovement();
 | 
	
		
			
				|  |  | +            mout.Issued = qty.Value;
 | 
	
		
			
				|  |  | +            mout.Cost = holding.AverageValue;
 | 
	
		
			
				|  |  | +            mout.Date = DateTime.Now;
 | 
	
		
			
				|  |  | +            mout.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  | +            mout.Type = StockMovementType.TransferOut;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            var min = mout.CreateMovement();
 | 
	
		
			
				|  |  | +            min.Received = qty.Value;
 | 
	
		
			
				|  |  | +            min.Cost = holding.AverageValue;
 | 
	
		
			
				|  |  | +            min.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  | +            min.Type = StockMovementType.TransferIn;
 | 
	
		
			
				|  |  | +            min.Date = mout.Date;
 | 
	
		
			
				|  |  | +            min.Transaction = mout.Transaction;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            modify(requi, mout, min);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            updates.Add(mout);
 | 
	
		
			
				|  |  | +            updates.Add(min);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private void ReleaseAllocatedStock_Click(StockHolding holding)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          var requiitems = holding.LoadRequisitionItems(true).Where(x => x.ID != Guid.Empty).ToList();
 | 
	
	
		
			
				|  | @@ -343,35 +381,14 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var quantities = win.GetQuantities();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var updates = new List<StockMovement>();
 | 
	
		
			
				|  |  | -            foreach(var requi in requiitems)
 | 
	
		
			
				|  |  | +            DoTransfer(holding, requiitems, x => quantities.TryGetValue(x.ID, out var value) ? value : null, (requi, mout, min) =>
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                if (!quantities.TryGetValue(requi.ID, out var qty) || qty <= 0) continue;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                var mout = holding.CreateMovement();
 | 
	
		
			
				|  |  | -                mout.Issued = qty;
 | 
	
		
			
				|  |  | -                mout.Cost = holding.AverageValue;
 | 
	
		
			
				|  |  |                  mout.JobRequisitionItem.ID = requi.ID;
 | 
	
		
			
				|  |  | -                mout.Date = DateTime.Now;
 | 
	
		
			
				|  |  | -                mout.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  |                  mout.Notes = $"Released from Job Requisition {requi.Requisition.Number}: {requi.Requisition.Description} for Job {requi.Job.JobNumber}";
 | 
	
		
			
				|  |  | -                mout.Type = StockMovementType.TransferOut;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                var min = mout.CreateMovement();
 | 
	
		
			
				|  |  | -                min.Received = qty;
 | 
	
		
			
				|  |  | -                min.Cost = holding.AverageValue;
 | 
	
		
			
				|  |  |                  min.JobRequisitionItem.ID = Guid.Empty;
 | 
	
		
			
				|  |  | -                min.Date = DateTime.Now;
 | 
	
		
			
				|  |  | -                min.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  |                  min.Notes = $"Released from Job Requisition {requi.Requisition.Number}: {requi.Requisition.Description} for Job {requi.Job.JobNumber}";
 | 
	
		
			
				|  |  | -                min.Type = StockMovementType.TransferIn;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                updates.Add(mout);
 | 
	
		
			
				|  |  | -                updates.Add(min);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            SaveBatch(StockMovementBatchType.Transfer, updates);
 | 
	
		
			
				|  |  | -            DoChanged();
 | 
	
		
			
				|  |  | -            Refresh(false, true);
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      
 | 
	
	
		
			
				|  | @@ -397,39 +414,17 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |              var quantities = win.GetQuantities();
 | 
	
		
			
				|  |  |              var target = win.GetTargetLocation();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var updates = new List<StockMovement>();
 | 
	
		
			
				|  |  | -            foreach (var requiitem in requiitems)
 | 
	
		
			
				|  |  | +            DoTransfer(holding, requiitems, x => quantities.TryGetValue(x.ID, out var qty) ? qty : null, (requi, mout, min) =>
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                if (!quantities.TryGetValue(requiitem.ID, out var qty)) continue;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                var mout = holding.CreateMovement();
 | 
	
		
			
				|  |  | -                mout.Issued = qty;
 | 
	
		
			
				|  |  | -                mout.Cost = holding.AverageValue;
 | 
	
		
			
				|  |  | -                mout.JobRequisitionItem.ID = requiitem.ID;
 | 
	
		
			
				|  |  | -                mout.Type = StockMovementType.TransferOut;
 | 
	
		
			
				|  |  | -                mout.Date = DateTime.Now;
 | 
	
		
			
				|  |  | -                mout.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  | +                mout.JobRequisitionItem.ID = requi.ID;
 | 
	
		
			
				|  |  |                  mout.Notes = $"Moved to {target.Code} by {App.EmployeeName}";
 | 
	
		
			
				|  |  | -                updates.Add(mout);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                var min = holding.CreateMovement();
 | 
	
		
			
				|  |  |                  min.Location.Clear();
 | 
	
		
			
				|  |  |                  min.Location.ID = target.ID;
 | 
	
		
			
				|  |  |                  min.Job.CopyFrom(win.Job ?? new());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                min.Received = mout.Issued;
 | 
	
		
			
				|  |  | -                min.Cost = holding.AverageValue;
 | 
	
		
			
				|  |  | -                min.JobRequisitionItem.ID = requiitem.ID;
 | 
	
		
			
				|  |  | -                min.Transaction = mout.Transaction;
 | 
	
		
			
				|  |  | -                min.Type = StockMovementType.TransferIn;
 | 
	
		
			
				|  |  | -                min.Date = mout.Date;
 | 
	
		
			
				|  |  | -                min.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  | +                min.JobRequisitionItem.ID = requi.ID;
 | 
	
		
			
				|  |  |                  min.Notes = $"Moved From {holding.Location.Code} by {App.EmployeeName}";
 | 
	
		
			
				|  |  | -                updates.Add(min);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            SaveBatch(StockMovementBatchType.Transfer, updates);
 | 
	
		
			
				|  |  | -            DoChanged();
 | 
	
		
			
				|  |  | -            Refresh(false, true);
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -486,23 +481,6 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |             
 | 
	
		
			
				|  |  |          return result;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    private static void SaveBatch(StockMovementBatchType type, IList<StockMovement> movements)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        var batch = new StockMovementBatch();
 | 
	
		
			
				|  |  | -        batch.Type = type;
 | 
	
		
			
				|  |  | -        batch.Notes = batch.Type + " batch created from Desktop Stock Location Screen";
 | 
	
		
			
				|  |  | -        batch.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  | -        new Client<StockMovementBatch>().Save(batch, "created from Desktop Stock Location Screen");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        foreach (var mvt in movements)
 | 
	
		
			
				|  |  | -        { 
 | 
	
		
			
				|  |  | -            mvt.Batch.ID = batch.ID;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        new Client<StockMovement>().Save(movements, "Updating batch from Desktop Stock Location Screen");
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      private bool IssueStock(Button arg1, CoreRow[] rows)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          if (rows?.Length != 1)
 | 
	
	
		
			
				|  | @@ -594,6 +572,57 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          return false;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private bool RelocateStock(Button btn, CoreRow[] rows)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        StockLocation? target = null;
 | 
	
		
			
				|  |  | +        while(true)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            target = StockHoldingRelocationWindow.LookupLocation();
 | 
	
		
			
				|  |  | +            if(target is null)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                return false;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else if(target.ID == Location.ID)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                MessageWindow.ShowMessage($"These items are already in {target.Code}; please select a different location.", "Invalid transfer");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        var holdings = rows.ToArray<StockHolding>();
 | 
	
		
			
				|  |  | +        var updates = new List<StockMovement>();
 | 
	
		
			
				|  |  | +        foreach(var holding in holdings)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            var items = holding.LoadRequisitionItems(true).AsIList();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            var rIDs = items.Select(x => x.ID).Where(x => x != Guid.Empty).ToArray();
 | 
	
		
			
				|  |  | +            var quantities = Client.Query(
 | 
	
		
			
				|  |  | +                StockHolding.GetFilter(holding)
 | 
	
		
			
				|  |  | +                    .Combine(new Filter<StockMovement>(x => x.JobRequisitionItem.ID).InList(rIDs)),
 | 
	
		
			
				|  |  | +                Columns.None<StockMovement>().Add(x => x.Units).Add(x => x.JobRequisitionItem.ID))
 | 
	
		
			
				|  |  | +                .ToObjects<StockMovement>().GroupBy(x => x.JobRequisitionItem.ID).ToDictionary(x => x.Key, x => x.Sum(x => x.Units));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            DoTransfer(holding, items, x => x.ID == Guid.Empty ? x.Qty : quantities.GetValueOrDefault(x.ID), (requi, mout, min) =>
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                mout.JobRequisitionItem.ID = requi.ID;
 | 
	
		
			
				|  |  | +                mout.Notes = $"Moved to {target.Code} by {App.EmployeeName}";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                min.JobRequisitionItem.ID = requi.ID;
 | 
	
		
			
				|  |  | +                min.Notes = $"Moved to {target.Code} by {App.EmployeeName}";
 | 
	
		
			
				|  |  | +                min.Location.Clear();
 | 
	
		
			
				|  |  | +                min.Location.ID = target.ID;
 | 
	
		
			
				|  |  | +            }, updates);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        SaveBatch(StockMovementBatchType.Transfer, updates);
 | 
	
		
			
				|  |  | +        DoChanged();
 | 
	
		
			
				|  |  | +        Refresh(false, true);
 | 
	
		
			
				|  |  | +        return true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      protected override void DoEdit()
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          var holding = SelectedRows.FirstOrDefault()?.ToObject<StockHolding>();
 | 
	
	
		
			
				|  | @@ -647,6 +676,55 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          Refresh(false, true);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    public IStockLocation Location { get; set; }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    protected override void SelectItems(CoreRow[]? rows)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        base.SelectItems(rows);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        var nRows = rows?.Length ?? 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        ReceiveButton.IsEnabled = Location != null && Location.ID != Guid.Empty;
 | 
	
		
			
				|  |  | +        IssueButton.IsEnabled = Location != null && Location.ID != Guid.Empty && nRows > 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(Location is null || Location.ID == Guid.Empty || nRows == 0)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            TransferButton.IsEnabled = false;
 | 
	
		
			
				|  |  | +            RelocateButton.IsEnabled = false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if(nRows == 1)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            TransferButton.IsEnabled = true;
 | 
	
		
			
				|  |  | +            RelocateButton.IsEnabled = true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            TransferButton.IsEnabled = false;
 | 
	
		
			
				|  |  | +            RelocateButton.IsEnabled = true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        var _groups = rows?.GroupBy(x => new Tuple<Guid, double>(
 | 
	
		
			
				|  |  | +            x.Get<StockHolding, Guid>(c => c.Product.ID),
 | 
	
		
			
				|  |  | +            x.Get<StockHolding, double>(c => c.Dimensions.Value))
 | 
	
		
			
				|  |  | +        );
 | 
	
		
			
				|  |  | +        AdjustValueButton.IsEnabled = Location != null && Location.ID != Guid.Empty && _groups?.Count() == 1;
 | 
	
		
			
				|  |  | +        RecalculateButton.IsEnabled = Location != null && Location.ID != Guid.Empty;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    protected override void Reload(
 | 
	
		
			
				|  |  | +    	Filters<StockHolding> criteria, Columns<StockHolding> columns, ref SortOrder<StockHolding>? sort,
 | 
	
		
			
				|  |  | +    	CancellationToken token, Action<CoreTable?, Exception?> action)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        ReceiveButton.IsEnabled = Location != null && Location.ID != Guid.Empty;
 | 
	
		
			
				|  |  | +        if (Location == null)
 | 
	
		
			
				|  |  | +            criteria.Add(new Filter<StockHolding>().None());
 | 
	
		
			
				|  |  | +        else
 | 
	
		
			
				|  |  | +            criteria.Add(new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(Location.ID));
 | 
	
		
			
				|  |  | +        base.Reload(criteria, columns, ref sort, token, action);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    #region Internal Utilities
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private StockMovement CreateMovementFromHolding(StockHolding holding)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          var movement = new StockMovement();
 | 
	
	
		
			
				|  | @@ -665,23 +743,28 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          movement.CommitChanges();
 | 
	
		
			
				|  |  |          return movement;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    public IStockLocation Location { get; set; }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    protected override void SelectItems(CoreRow[]? rows)
 | 
	
		
			
				|  |  | +    private static void SaveBatch(StockMovementBatchType type, IList<StockMovement> movements)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -        base.SelectItems(rows);
 | 
	
		
			
				|  |  | +        var batch = new StockMovementBatch();
 | 
	
		
			
				|  |  | +        batch.Type = type;
 | 
	
		
			
				|  |  | +        batch.Notes = batch.Type + " batch created from Desktop Stock Location Screen";
 | 
	
		
			
				|  |  | +        batch.Employee.ID = App.EmployeeID;
 | 
	
		
			
				|  |  | +        new Client<StockMovementBatch>().Save(batch, "created from Desktop Stock Location Screen");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        ReceiveButton.IsEnabled = Location != null && Location.ID != Guid.Empty;
 | 
	
		
			
				|  |  | -        IssueButton.IsEnabled = Location != null && Location.ID != Guid.Empty && rows?.Any() == true;
 | 
	
		
			
				|  |  | -        TransferButton.IsEnabled = Location != null && Location.ID != Guid.Empty && rows?.Any() == true;
 | 
	
		
			
				|  |  | -        var _groups = rows?.GroupBy(x => new Tuple<Guid, double>(
 | 
	
		
			
				|  |  | -            x.Get<StockHolding, Guid>(c => c.Product.ID),
 | 
	
		
			
				|  |  | -            x.Get<StockHolding, double>(c => c.Dimensions.Value))
 | 
	
		
			
				|  |  | -        );
 | 
	
		
			
				|  |  | -        AdjustValueButton.IsEnabled = Location != null && Location.ID != Guid.Empty && _groups?.Count() == 1;
 | 
	
		
			
				|  |  | -        RecalculateButton.IsEnabled = Location != null && Location.ID != Guid.Empty;
 | 
	
		
			
				|  |  | +        foreach (var mvt in movements)
 | 
	
		
			
				|  |  | +        { 
 | 
	
		
			
				|  |  | +            mvt.Batch.ID = batch.ID;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        new Client<StockMovement>().Save(movements, "Updating batch from Desktop Stock Location Screen");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    #endregion
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    #region StockMovementGrid
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private DynamicDataGrid<StockMovement> CheckStockMovementGrid(MovementAction action, StockHolding holding)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          _action = action;
 | 
	
	
		
			
				|  | @@ -790,17 +873,5 @@ public class StockHoldingGrid : DynamicDataGrid<StockHolding>
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    protected override void Reload(
 | 
	
		
			
				|  |  | -    	Filters<StockHolding> criteria, Columns<StockHolding> columns, ref SortOrder<StockHolding>? sort,
 | 
	
		
			
				|  |  | -    	CancellationToken token, Action<CoreTable?, Exception?> action)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        ReceiveButton.IsEnabled = Location != null && Location.ID != Guid.Empty;
 | 
	
		
			
				|  |  | -        if (Location == null)
 | 
	
		
			
				|  |  | -            criteria.Add(new Filter<StockHolding>().None());
 | 
	
		
			
				|  |  | -        else
 | 
	
		
			
				|  |  | -            criteria.Add(new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(Location.ID));
 | 
	
		
			
				|  |  | -        base.Reload(criteria, columns, ref sort, token, action);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +    #endregion
 | 
	
		
			
				|  |  |  }
 |