Преглед на файлове

Added StockMovementType enum and fixed some StockMovement creators.

Kenric Nugteren преди 1 година
родител
ревизия
3654942a3e

+ 4 - 2
prs.classes/Entities/Stock/StockMovement.cs

@@ -1,6 +1,5 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.Linq;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Linq.Expressions;
 using InABox.Core;
 using InABox.Core;
@@ -138,6 +137,9 @@ namespace Comal.Classes
         [MemoEditor]
         [MemoEditor]
         [EditorSequence(10)]
         [EditorSequence(10)]
         public string Notes { get; set; }
         public string Notes { get; set; }
+
+        [EnumLookupEditor(typeof(StockMovementType))]
+        public StockMovementType Type { get; set; }
         
         
         [NullEditor]
         [NullEditor]
         public Guid Transaction { get; set; } = Guid.NewGuid();
         public Guid Transaction { get; set; } = Guid.NewGuid();
@@ -219,7 +221,7 @@ namespace Comal.Classes
             else if (issued.IsEqualTo(name))
             else if (issued.IsEqualTo(name))
             {
             {
                 bChanging = true;
                 bChanging = true;
-                Units = (Received - (double)after);
+                Units = Received - (double)after;
                 Qty = Units * Dimensions.Value;
                 Qty = Units * Dimensions.Value;
                 bChanging = false;
                 bChanging = false;
             }
             }

+ 42 - 0
prs.classes/Entities/Stock/StockMovementType.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Comal.Classes
+{
+    public enum StockMovementType
+    {
+        /// <summary>
+        /// Stock is being received into the system.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="StockMovement.Received"/> should not be zero.
+        /// </remarks>
+        Receive,
+        /// <summary>
+        /// Stock is being issued out of the system.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="StockMovement.Issued"/> should not be zero.
+        /// </remarks>
+        Issue,
+        /// <summary>
+        /// Stock is being transferred out of this holding to another.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="StockMovement.Issued"/> should not be zero.
+        /// </remarks>
+        TransferOut,
+        /// <summary>
+        /// Stock is being transferred into this holding from another.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="StockMovement.Received"/> should not be zero.
+        /// </remarks>
+        TransferIn,
+        /// <summary>
+        /// Stock is being updated based on a stocktake.
+        /// </summary>
+        StockTake
+    }
+}

+ 16 - 7
prs.desktop/Panels/Products/Locations/StockHoldingGrid.cs

@@ -128,12 +128,11 @@ namespace PRSDesktop
             return employee.Rows.Any() ? employee.Rows.First().Get<Employee, Guid>(x => x.ID) : Guid.Empty;
             return employee.Rows.Any() ? employee.Rows.First().Get<Employee, Guid>(x => x.ID) : Guid.Empty;
         }
         }
 
 
-        private Dictionary<string, object?> StockMovementValueChanged(object sender, string name, object value)
+        private Dictionary<string, object?> StockMovementValueChanged(IDynamicEditorForm form, string name, object value)
         {
         {
-            var result = new Dictionary<string, object>();
+            var result = new Dictionary<string, object?>();
             if (name.Equals("Location.Job.ID"))
             if (name.Equals("Location.Job.ID"))
             {
             {
-                var form = sender as IDynamicEditorForm;
                 var editor = form.FindEditor("Job.ID");
                 var editor = form.FindEditor("Job.ID");
                 if (!value.Equals(Guid.Empty))
                 if (!value.Equals(Guid.Empty))
                     result = DynamicGridUtils.UpdateEditorValue(form.Items, "Job.ID", value);
                     result = DynamicGridUtils.UpdateEditorValue(form.Items, "Job.ID", value);
@@ -256,6 +255,7 @@ namespace PRSDesktop
             movement.Date = DateTime.Now;
             movement.Date = DateTime.Now;
             movement.IsTransfer = false;
             movement.IsTransfer = false;
             movement.Employee.ID = _employeeid;
             movement.Employee.ID = _employeeid;
+            movement.Type = StockMovementType.Receive;
 
 
             movement.CommitChanges();
             movement.CommitChanges();
 
 
@@ -306,8 +306,10 @@ namespace PRSDesktop
             // var stylecode = rows.First().Get<StockHolding, string>(x => x.Style.Code);
             // var stylecode = rows.First().Get<StockHolding, string>(x => x.Style.Code);
             // var size = rows.First().Get<StockHolding, double>(x => x.UnitSize);
             // var size = rows.First().Get<StockHolding, double>(x => x.UnitSize);
 
 
-            var movement = new StockMovement();
-            movement.Date = DateTime.Now;
+            var movement = new StockMovement
+            {
+                Date = DateTime.Now
+            };
             movement.Location.ID = Location.ID;
             movement.Location.ID = Location.ID;
             movement.Location.Code = Location.Code;
             movement.Location.Code = Location.Code;
             movement.Location.Description = Location.Description;
             movement.Location.Description = Location.Description;
@@ -320,6 +322,7 @@ namespace PRSDesktop
             movement.IsTransfer = false;
             movement.IsTransfer = false;
             movement.Employee.ID = _employeeid;
             movement.Employee.ID = _employeeid;
             movement.Cost = holding.AverageValue;
             movement.Cost = holding.AverageValue;
+            movement.Type = StockMovementType.Issue;
 
 
             movement.CommitChanges();
             movement.CommitChanges();
 
 
@@ -336,8 +339,10 @@ namespace PRSDesktop
             if (result && holding.Job.ID != movement.Job.ID)
             if (result && holding.Job.ID != movement.Job.ID)
             {
             {
                 // Issue from Old Job (Hidden)
                 // Issue from Old Job (Hidden)
-                var issue = new StockMovement();
-                issue.Date = movement.Date;
+                var issue = new StockMovement
+                {
+                    Date = movement.Date
+                };
                 issue.Product.ID = holding.Product.ID;
                 issue.Product.ID = holding.Product.ID;
                 issue.Job.ID = holding.Job.ID;
                 issue.Job.ID = holding.Job.ID;
                 issue.Location.ID = Location.ID;
                 issue.Location.ID = Location.ID;
@@ -350,6 +355,7 @@ namespace PRSDesktop
                 issue.Notes = string.Format("Transferred from {0}", holding.Job.ID.Equals(Guid.Empty) ? "General Stock" : "Job " + holding.Job.JobNumber);
                 issue.Notes = string.Format("Transferred from {0}", holding.Job.ID.Equals(Guid.Empty) ? "General Stock" : "Job " + holding.Job.JobNumber);
                 issue.System = true;
                 issue.System = true;
                 issue.Cost = holding.AverageValue;
                 issue.Cost = holding.AverageValue;
+                issue.Type = StockMovementType.TransferOut;
 
 
                 // Receive to New Job (Hidden)
                 // Receive to New Job (Hidden)
                 var receive = new StockMovement();
                 var receive = new StockMovement();
@@ -367,6 +373,7 @@ namespace PRSDesktop
                     !movement.Job.IsValid() ? "General Stock" : "Job " + movement.Job.JobNumber);
                     !movement.Job.IsValid() ? "General Stock" : "Job " + movement.Job.JobNumber);
                 receive.System = true;
                 receive.System = true;
                 receive.Cost = holding.AverageValue;
                 receive.Cost = holding.AverageValue;
+                receive.Type = StockMovementType.TransferIn;
 
 
                 new Client<StockMovement>().Save(new[] { issue, receive }, "");
                 new Client<StockMovement>().Save(new[] { issue, receive }, "");
                 mvts.Add(issue);
                 mvts.Add(issue);
@@ -412,6 +419,7 @@ namespace PRSDesktop
             movement.Received = holding.Units;
             movement.Received = holding.Units;
             movement.IsTransfer = true;
             movement.IsTransfer = true;
             movement.Cost = holding.AverageValue;
             movement.Cost = holding.AverageValue;
+            movement.Type = StockMovementType.TransferIn;
 
 
             movement.CommitChanges();
             movement.CommitChanges();
 
 
@@ -442,6 +450,7 @@ namespace PRSDesktop
                 other.Employee.ID = movement.Employee.ID;
                 other.Employee.ID = movement.Employee.ID;
                 other.Dimensions.CopyFrom(holding.Dimensions);
                 other.Dimensions.CopyFrom(holding.Dimensions);
                 other.IsTransfer = true;
                 other.IsTransfer = true;
+                other.Type = StockMovementType.TransferOut;
 
 
                 var changes = new List<string>();
                 var changes = new List<string>();
                 if (movement.Location.ID != other.Location.ID)
                 if (movement.Location.ID != other.Location.ID)

+ 11 - 6
prs.desktop/Panels/Products/Locations/StockTakeWindow.xaml.cs

@@ -396,9 +396,9 @@ namespace PRSDesktop
         #region Stock Movements
         #region Stock Movements
         private void CreateMovements()
         private void CreateMovements()
         {
         {
-            StockMovementBatch batch = CreateBatch();
+            var batch = CreateBatch();
 
 
-            List<StockMovement> movements = CompareHoldingsAndCreateMovements(batch.ID);
+            var movements = CompareHoldingsAndCreateMovements(batch.ID);
 
 
             new Client<StockMovement>().Save(movements, "Created on Desktop Stocktake");
             new Client<StockMovement>().Save(movements, "Created on Desktop Stocktake");
         }
         }
@@ -432,14 +432,14 @@ namespace PRSDesktop
 
 
         private StockMovement CreateMovement(StockTakeHolding holding, double qty, Guid batchID)
         private StockMovement CreateMovement(StockTakeHolding holding, double qty, Guid batchID)
         {
         {
-            StockMovement movement = CreateBaseMovement(holding, batchID);
+            var movement = CreateBaseMovement(holding, batchID);
 
 
             return DetermineMovementType(movement, qty);
             return DetermineMovementType(movement, qty);
         }
         }
 
 
         private StockMovement CreateBaseMovement(StockTakeHolding holding, Guid batchID)
         private StockMovement CreateBaseMovement(StockTakeHolding holding, Guid batchID)
         {
         {
-            StockMovement movement = new StockMovement();
+            var movement = new StockMovement();
 
 
             movement.Batch.ID = batchID;
             movement.Batch.ID = batchID;
             movement.IsTransfer = false;
             movement.IsTransfer = false;
@@ -454,11 +454,12 @@ namespace PRSDesktop
             movement.Date = DateTime.Now;
             movement.Date = DateTime.Now;
             movement.Location.ID = holding.Location.ID;
             movement.Location.ID = holding.Location.ID;
             movement.IsRemnant = false;
             movement.IsRemnant = false;
+            movement.Type = StockMovementType.StockTake;
 
 
             return movement;
             return movement;
         }
         }
 
 
-        private StockMovement CopyDimensions(StockMovement movement, StockTakeHolding holding)
+        private static StockMovement CopyDimensions(StockMovement movement, StockTakeHolding holding)
         {
         {
             movement.Dimensions.Unit.ID = holding.Dimensions.Unit.ID;
             movement.Dimensions.Unit.ID = holding.Dimensions.Unit.ID;
             movement.Dimensions.Unit.HasQuantity = holding.Dimensions.Unit.HasQuantity;
             movement.Dimensions.Unit.HasQuantity = holding.Dimensions.Unit.HasQuantity;
@@ -479,13 +480,17 @@ namespace PRSDesktop
             return movement;
             return movement;
         }
         }
 
 
-        private StockMovement DetermineMovementType(StockMovement movement, double qty)
+        private static StockMovement DetermineMovementType(StockMovement movement, double qty)
         {
         {
             if (qty < 0)
             if (qty < 0)
+            {
                 movement.Issued = 0 - qty;
                 movement.Issued = 0 - qty;
+            }
 
 
             if (qty > 0)
             if (qty > 0)
+            {
                 movement.Received = qty;
                 movement.Received = qty;
+            }
 
 
             if (movement.Issued != 0 || movement.Received != 0)
             if (movement.Issued != 0 || movement.Received != 0)
                 movement.Notes = string.IsNullOrWhiteSpace(movement.Notes) ? "Updated Qty on Stocktake" : movement.Notes + ". Updated Qty on Stocktake";
                 movement.Notes = string.IsNullOrWhiteSpace(movement.Notes) ? "Updated Qty on Stocktake" : movement.Notes + ". Updated Qty on Stocktake";

+ 6 - 14
prs.desktop/Panels/Products/Reservation Management/JobRequisitionReviewGrid.cs

@@ -285,7 +285,7 @@ namespace PRSDesktop
 
 
         private void MarkReserved_Clicked(CoreRow? row)
         private void MarkReserved_Clicked(CoreRow? row)
         {
         {
-            JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
+            JobRequisitionItem item = row?.ToObject<JobRequisitionItem>();
             if (CheckValidAction(item, false))
             if (CheckValidAction(item, false))
             {
             {
                 SaveRow(row, JobRequisitionItemStatus.Allocated, "Line marked as Reserved by " + empName + " on " + DateTime.Now.ToString("dd MMM yy"));
                 SaveRow(row, JobRequisitionItemStatus.Allocated, "Line marked as Reserved by " + empName + " on " + DateTime.Now.ToString("dd MMM yy"));
@@ -366,11 +366,9 @@ namespace PRSDesktop
             JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
             JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
             if (!CheckValidAction(item, true))
             if (!CheckValidAction(item, true))
                 return;
                 return;
-            CoreTable table = new Client<StockMovement>().Query
-                (
+            var table = Client.Query(
                 new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(item.ID),
                 new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(item.ID),
-                new Columns<StockMovement>(x => x.ID)
-                );
+                new Columns<StockMovement>(x => x.ID));
             if (table.Rows.Any())
             if (table.Rows.Any())
             {
             {
                 var result = MessageBox.Show("This will reverse stock movements already created for this Requisition Item. Proceed?", "Alert", MessageBoxButton.YesNo);
                 var result = MessageBox.Show("This will reverse stock movements already created for this Requisition Item. Proceed?", "Alert", MessageBoxButton.YesNo);
@@ -383,17 +381,11 @@ namespace PRSDesktop
                     default:
                     default:
                         return;
                         return;
                 }
                 }
-                List<StockMovement> movements = new List<StockMovement>();
-                foreach (CoreRow stockmovementRow in table.Rows)
-                {
-                    StockMovement movement = new StockMovement();
-                    movement.ID = Guid.Parse(stockmovementRow.Values[0].ToString());
-                    movements.Add(movement);
-                }
-                new Client<StockMovement>().Delete(movements, "Stock movements reversed from Job Requisition Item Review Dashboard");
+                var movements = table.ToObjects<StockMovement>().ToList();
+                Client.Delete(movements, "Stock movements reversed from Job Requisition Item Review Dashboard");
                 extraMessage = " and Stock Movements Reversed ";
                 extraMessage = " and Stock Movements Reversed ";
             }
             }
-            SaveRow(row, JobRequisitionItemStatus.NotChecked, "Line marked as Not Checked by " + empName + extraMessage + " on " + DateTime.Now.ToString("dd MMM yy"));
+            SaveRow(row, JobRequisitionItemStatus.NotChecked, $"Line marked as Not Checked by {empName + extraMessage} on {DateTime.Now:dd MMM yy}");
         }
         }
 
 
         private bool CreatePurchaseOrder(Button btn, CoreRow[] rows)
         private bool CreatePurchaseOrder(Button btn, CoreRow[] rows)

+ 11 - 6
prs.desktop/Panels/Products/Reservation Management/StockSelectionPage.xaml.cs

@@ -88,27 +88,32 @@ namespace PRSDesktop
 
 
         private void CreateStockMovements(StockSelectionViewModel model)
         private void CreateStockMovements(StockSelectionViewModel model)
         {
         {
-            StockMovementBatch batch = new StockMovementBatch();
-            batch.TimeStamp = DateTime.Now;
-            batch.Type = StockMovementBatchType.Transfer;
-            batch.Notes = "Allocated to Job " + Item.Job.JobNumber;
+            var batch = new StockMovementBatch
+            {
+                TimeStamp = DateTime.Now,
+                Type = StockMovementBatchType.Transfer,
+                Notes = "Allocated to Job " + Item.Job.JobNumber
+            };
             new Client<StockMovementBatch>().Save(batch, "Created for requisitioning stock");
             new Client<StockMovementBatch>().Save(batch, "Created for requisitioning stock");
 
 
             var issuing = CreateBaseMovement(model, batch.ID);
             var issuing = CreateBaseMovement(model, batch.ID);
             issuing.Job.ID = IssuingJobID;
             issuing.Job.ID = IssuingJobID;
             issuing.Issued = model.ChosenUnits;
             issuing.Issued = model.ChosenUnits;
+            issuing.Type = StockMovementType.TransferOut;
 
 
             var receiving = CreateBaseMovement(model, batch.ID);
             var receiving = CreateBaseMovement(model, batch.ID);
             receiving.Job.ID = Item.Job.ID;
             receiving.Job.ID = Item.Job.ID;
             receiving.Received = model.ChosenUnits;
             receiving.Received = model.ChosenUnits;
             receiving.JobRequisitionItem.ID = Item.ID;
             receiving.JobRequisitionItem.ID = Item.ID;
+            receiving.Type = StockMovementType.TransferIn;
+            receiving.Transaction = issuing.Transaction;
 
 
-            new Client<StockMovement>().Save(new StockMovement[] { issuing, receiving }, "Created from Reservation Management Screen");
+            Client.Save(new StockMovement[] { issuing, receiving }, "Created from Reservation Management Screen");
         }
         }
 
 
         private StockMovement CreateBaseMovement(StockSelectionViewModel model, Guid batchid)
         private StockMovement CreateBaseMovement(StockSelectionViewModel model, Guid batchid)
         {
         {
-            StockMovement mvt = new StockMovement();
+            var mvt = new StockMovement();
             mvt.Style.ID = model.Holding.Style.ID;
             mvt.Style.ID = model.Holding.Style.ID;
             mvt.Location.ID = model.Holding.Location.ID;
             mvt.Location.ID = model.Holding.Location.ID;
             mvt.Dimensions.CopyFrom(model.Holding.Dimensions);
             mvt.Dimensions.CopyFrom(model.Holding.Dimensions);

+ 0 - 6
prs.server/Engines/GPS/GPSEngine.cs

@@ -14,13 +14,7 @@ using System.Net;
 using System.Net.Sockets;
 using System.Net.Sockets;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using Comal.Classes;
-using InABox.Clients;
-using InABox.Core;
-using InABox.DigitalMatter;
-using InABox.IPC;
 using InABox.Rpc;
 using InABox.Rpc;
-using PRSServer.Engines;
 using System.Timers;
 using System.Timers;
 using PRS.Shared;
 using PRS.Shared;
 
 

+ 6 - 8
prs.server/Engines/WebEngine/WebListener.cs

@@ -305,7 +305,7 @@ namespace PRSServer
         
         
         private class TwoFARequest
         private class TwoFARequest
         {
         {
-            public string Code { get; set; }
+            public string? Code { get; set; }
         }
         }
 
 
         private IResponseBuilder Handle2FA(IRequest request)
         private IResponseBuilder Handle2FA(IRequest request)
@@ -1009,7 +1009,10 @@ Model.LoadModel(
             );
             );
             if (documentTable.Rows.Count == 0) return null;
             if (documentTable.Rows.Count == 0) return null;
             var row = documentTable.Rows[0];
             var row = documentTable.Rows[0];
-            return new DocumentData(row["Data"] as byte[], row["FileName"] as string, (bool)row["Private"]);
+            return new DocumentData(
+                row.Get<Document, byte[]>(x => x.Data),
+                row.Get<Document, string>(x => x.FileName),
+                row.Get<Document, bool>(x => x.Private));
         }
         }
 
 
         private IResponseBuilder HandleDocument(IRequest request)
         private IResponseBuilder HandleDocument(IRequest request)
@@ -1023,12 +1026,7 @@ Model.LoadModel(
 
 
             if (documentId != null)
             if (documentId != null)
             {
             {
-                Guid guid;
-                try
-                {
-                    guid = Guid.Parse(documentId);
-                }
-                catch (FormatException e)
+                if(!Guid.TryParse(documentId, out var guid))
                 {
                 {
                     Logger.Send(LogType.Error, "", "Invalid GUID format '" + documentId + "'");
                     Logger.Send(LogType.Error, "", "Invalid GUID format '" + documentId + "'");
                     return request.Respond().Status(ResponseStatus.BadRequest);
                     return request.Respond().Status(ResponseStatus.BadRequest);

+ 1 - 1
prs.server/Forms/Console/Console.xaml.cs

@@ -206,7 +206,7 @@ namespace PRSServer
                 {
                 {
                     searchRegex = new Regex(Search.Text, RegexOptions.Compiled, regexTimeOut);
                     searchRegex = new Regex(Search.Text, RegexOptions.Compiled, regexTimeOut);
                 }
                 }
-                catch (ArgumentException ex)
+                catch (ArgumentException)
                 {
                 {
                     searchRegex = null;
                     searchRegex = null;
                 }
                 }

+ 23 - 40
prs.stores/ConsignmentStore.cs

@@ -17,8 +17,6 @@ namespace Comal.Stores
         {
         {
             base.AfterSave(entity);
             base.AfterSave(entity);
 
 
-            Guid purchaseOrderID = Guid.Empty;
-
             //consignment has to be newly completed (usually done via receivals module) - checks further down as well to ensure no repeated saving of documents / batches
             //consignment has to be newly completed (usually done via receivals module) - checks further down as well to ensure no repeated saving of documents / batches
             if (entity.ActualWarehouseArrival == DateTime.MinValue)
             if (entity.ActualWarehouseArrival == DateTime.MinValue)
                 return;
                 return;
@@ -26,22 +24,20 @@ namespace Comal.Stores
                 return;
                 return;
 
 
             //find previously saved PO Items attached to this consignment
             //find previously saved PO Items attached to this consignment
-            CoreTable purchaseOrderItemTable = Provider.Query<PurchaseOrderItem>(
+            var purchaseOrderItemTable = Provider.Query<PurchaseOrderItem>(
                 new Filter<PurchaseOrderItem>(x => x.Consignment.ID).IsEqualTo(entity.ID),
                 new Filter<PurchaseOrderItem>(x => x.Consignment.ID).IsEqualTo(entity.ID),
                 new Columns<PurchaseOrderItem>(x => x.ID, x => x.PurchaseOrderLink.ID)
                 new Columns<PurchaseOrderItem>(x => x.ID, x => x.PurchaseOrderLink.ID)
                 );
                 );
 
 
-            if (!purchaseOrderItemTable.Rows.Any())
+            var firstPOItem = purchaseOrderItemTable.Rows.FirstOrDefault();
+            if (firstPOItem is null) // i.e., there are no PO Items, return
                 return;
                 return;
 
 
-            List<Guid> consignmentDocIDs = new List<Guid>();
+            var consignmentDocIDs = new List<Guid>();
 
 
-            if (purchaseOrderItemTable.Rows.FirstOrDefault().Values[1] == null)
-                purchaseOrderID = Guid.Empty;
-            else
-                purchaseOrderID = Guid.Parse(purchaseOrderItemTable.Rows.FirstOrDefault().Values[1].ToString());
+            var purchaseOrderID = firstPOItem.Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.ID);
 
 
-            CoreTable table = Provider.Query<ConsignmentDocument>
+            var table = Provider.Query<ConsignmentDocument>
             (
             (
                 new Filter<ConsignmentDocument>(x => x.EntityLink.ID).IsEqualTo(entity.ID),
                 new Filter<ConsignmentDocument>(x => x.EntityLink.ID).IsEqualTo(entity.ID),
                 new Columns<ConsignmentDocument>(x => x.DocumentLink.ID)
                 new Columns<ConsignmentDocument>(x => x.DocumentLink.ID)
@@ -52,17 +48,10 @@ namespace Comal.Stores
             }
             }
 
 
             //build filter for querying stock movements attached to PO Items on this consignment
             //build filter for querying stock movements attached to PO Items on this consignment
-            Filter<StockMovement> filter =
-                new Filter<StockMovement>(x => x.OrderItem.ID).IsEqualTo(Guid.Parse(purchaseOrderItemTable.Rows.FirstOrDefault().Values[0].ToString()));
-            foreach (CoreRow row in purchaseOrderItemTable.Rows)
-            {
-                if (row != purchaseOrderItemTable.Rows.FirstOrDefault())
-                {
-                    List<object> list = row.Values;
-                    filter = filter.Or(x => x.OrderItem.ID).IsEqualTo(Guid.Parse(list[0].ToString()));
-                }
-            }
-            CoreTable stockMovementTable = Provider.Query<StockMovement>(
+            var filter =
+                new Filter<StockMovement>(x => x.OrderItem.ID).InList(purchaseOrderItemTable.Rows.Select(x => x.Get<PurchaseOrderItem, Guid>(x => x.ID)).ToArray());
+            
+            var stockMovementTable = Provider.Query<StockMovement>(
                 filter,
                 filter,
                 new Columns<StockMovement>(
                 new Columns<StockMovement>(
                     x => x.ID,
                     x => x.ID,
@@ -73,24 +62,19 @@ namespace Comal.Stores
             if (stockMovementTable.Rows.Any())
             if (stockMovementTable.Rows.Any())
             {
             {
                 //check if movements already have a batch.id - means photos would have already been saved
                 //check if movements already have a batch.id - means photos would have already been saved
-                if (Guid.Parse(stockMovementTable.Rows.FirstOrDefault().Values[2].ToString()) != Guid.Empty)
+                var batchID = stockMovementTable.Rows.First().Get<StockMovement, Guid>(x => x.Batch.ID);
+                if (batchID != Guid.Empty)
                     return;
                     return;
 
 
                 //create new stockmovementbatch to attach new stockmovements to (movements created by server)
                 //create new stockmovementbatch to attach new stockmovements to (movements created by server)
-                StockMovementBatch batch = new StockMovementBatch();
+                var batch = new StockMovementBatch();
                 batch.Type = StockMovementBatchType.Receipt;
                 batch.Type = StockMovementBatchType.Receipt;
                 Provider.Save(batch);
                 Provider.Save(batch);
 
 
                 //add found stockmovements to batch, add stockmovements to save
                 //add found stockmovements to batch, add stockmovements to save
-                List<StockMovement> movements = new List<StockMovement>();
-                foreach (CoreRow row in stockMovementTable.Rows)
+                var movements = new List<StockMovement>();
+                foreach (var movement in stockMovementTable.ToObjects<StockMovement>())
                 {
                 {
-                    List<object> list1 = row.Values;
-                    StockMovement movement = new StockMovement
-                    {
-                        ID = Guid.Parse(list1[0].ToString()),
-                        Notes = list1[1].ToString()
-                    };
                     movement.Batch.ID = batch.ID;
                     movement.Batch.ID = batch.ID;
                     movement.Employee.ID = entity.Employee.ID;
                     movement.Employee.ID = entity.Employee.ID;
                     movement.Notes = movement.Notes + " / Consignment " + entity.Number;
                     movement.Notes = movement.Notes + " / Consignment " + entity.Number;
@@ -98,8 +82,8 @@ namespace Comal.Stores
                 }
                 }
                 Provider.Save(movements);
                 Provider.Save(movements);
 
 
-                List<StockMovementBatchDocument> stockMovementBatchDocuments = new List<StockMovementBatchDocument>();
-                foreach (Guid id in consignmentDocIDs)
+                var stockMovementBatchDocuments = new List<StockMovementBatchDocument>();
+                foreach (var id in consignmentDocIDs)
                 {
                 {
                     var smd = new StockMovementBatchDocument();
                     var smd = new StockMovementBatchDocument();
                     smd.EntityLink.ID = batch.ID;
                     smd.EntityLink.ID = batch.ID;
@@ -112,17 +96,16 @@ namespace Comal.Stores
 
 
         private List<Guid> SavePurchaseOrderDocuments(CoreTable table, Guid purchaseOrderID)
         private List<Guid> SavePurchaseOrderDocuments(CoreTable table, Guid purchaseOrderID)
         {
         {
-            List<Guid> consignmentDocIDs = new List<Guid>();
-            List<PurchaseOrderDocument> purchaseOrderDocuments = new List<PurchaseOrderDocument>();
-            foreach (CoreRow row in table.Rows)
+            var consignmentDocIDs = new List<Guid>();
+            var purchaseOrderDocuments = new List<PurchaseOrderDocument>();
+            foreach (var row in table.Rows)
             {
             {
-                List<object> list = row.Values;
-                Guid docID = Guid.Parse(list[0].ToString());
+                var docID = row.Get<ConsignmentDocument, Guid>(x => x.DocumentLink.ID);
                 consignmentDocIDs.Add(docID);
                 consignmentDocIDs.Add(docID);
-                PurchaseOrderDocument PODocument = new PurchaseOrderDocument();
+                var PODocument = new PurchaseOrderDocument();
                 PODocument.DocumentLink.ID = docID;
                 PODocument.DocumentLink.ID = docID;
                 PODocument.EntityLink.ID = purchaseOrderID;
                 PODocument.EntityLink.ID = purchaseOrderID;
-                CoreTable existingPODocs = Provider.Query<PurchaseOrderDocument>(
+                var existingPODocs = Provider.Query<PurchaseOrderDocument>(
                     new Filter<PurchaseOrderDocument>(x => x.DocumentLink.ID).IsEqualTo(docID), //check that PO document doesn't already exist
                     new Filter<PurchaseOrderDocument>(x => x.DocumentLink.ID).IsEqualTo(docID), //check that PO document doesn't already exist
                     new Columns<PurchaseOrderDocument>(x => x.ID));
                     new Columns<PurchaseOrderDocument>(x => x.ID));
                 if (existingPODocs.Rows.Count == 0)
                 if (existingPODocs.Rows.Count == 0)

+ 10 - 4
prs.stores/EmployeeProductStore.cs

@@ -28,6 +28,8 @@ namespace Comal.Stores
                     movement.Date = entity.Issued;
                     movement.Date = entity.Issued;
                     movement.Issued = entity.Quantity;
                     movement.Issued = entity.Quantity;
                     movement.Received = 0.0F;
                     movement.Received = 0.0F;
+
+                    movement.Type = StockMovementType.Issue;
                     
                     
                     movement.Dimensions.Unit.ID = entity.Product.Dimensions.Unit.ID;
                     movement.Dimensions.Unit.ID = entity.Product.Dimensions.Unit.ID;
                     movement.Dimensions.Unit.Synchronise(entity.Product.Dimensions);
                     movement.Dimensions.Unit.Synchronise(entity.Product.Dimensions);
@@ -44,16 +46,19 @@ namespace Comal.Stores
                 else
                 else
                 {
                 {
                     var movement = Provider.Load(new Filter<StockMovement>(x => x.ID).IsEqualTo(entity.IssuedMovement.ID)).FirstOrDefault();
                     var movement = Provider.Load(new Filter<StockMovement>(x => x.ID).IsEqualTo(entity.IssuedMovement.ID)).FirstOrDefault();
-                    if (movement == null)
-                        movement = new StockMovement();
+                    movement ??= new StockMovement();
                     movement.Product.ID = entity.Product.ID;
                     movement.Product.ID = entity.Product.ID;
                     movement.Dimensions.CopyFrom(entity.Product.Dimensions);
                     movement.Dimensions.CopyFrom(entity.Product.Dimensions);
                     movement.Location.ID = entity.Product.DefaultLocation.ID;
                     movement.Location.ID = entity.Product.DefaultLocation.ID;
                     movement.Date = entity.Issued;
                     movement.Date = entity.Issued;
                     movement.Issued = entity.Quantity;
                     movement.Issued = entity.Quantity;
                     movement.Received = 0.0F;
                     movement.Received = 0.0F;
+
+                    movement.Type = StockMovementType.Issue;
+
                     movement.Qty = 0.0F - movement.Issued * movement.Dimensions.Value;
                     movement.Qty = 0.0F - movement.Issued * movement.Dimensions.Value;
                     movement.Notes = string.Format("Issued to " + entity.Employee.Name);
                     movement.Notes = string.Format("Issued to " + entity.Employee.Name);
+
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Issue Updated");
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Issue Updated");
                     entity.IssuedMovement.ID = movement.ID;
                     entity.IssuedMovement.ID = movement.ID;
                 }
                 }
@@ -82,6 +87,7 @@ namespace Comal.Stores
                     movement.Date = entity.Returned;
                     movement.Date = entity.Returned;
                     movement.Issued = 0.0F;
                     movement.Issued = 0.0F;
                     movement.Received = entity.Quantity;
                     movement.Received = entity.Quantity;
+                    movement.Type = StockMovementType.Receive;
                     movement.Qty = movement.Received * movement.Dimensions.Value;
                     movement.Qty = movement.Received * movement.Dimensions.Value;
                     movement.Notes = string.Format("Returned by " + entity.Employee.Name);
                     movement.Notes = string.Format("Returned by " + entity.Employee.Name);
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Return Created");
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Return Created");
@@ -90,14 +96,14 @@ namespace Comal.Stores
                 else
                 else
                 {
                 {
                     var movement = Provider.Load(new Filter<StockMovement>(x => x.ID).IsEqualTo(entity.ReturnedMovement.ID)).FirstOrDefault();
                     var movement = Provider.Load(new Filter<StockMovement>(x => x.ID).IsEqualTo(entity.ReturnedMovement.ID)).FirstOrDefault();
-                    if (movement == null)
-                        movement = new StockMovement();
+                    movement ??= new StockMovement();
                     movement.Product.ID = entity.Product.ID;
                     movement.Product.ID = entity.Product.ID;
                     movement.Dimensions.CopyFrom(entity.Product.Dimensions);
                     movement.Dimensions.CopyFrom(entity.Product.Dimensions);
                     movement.Location.ID = entity.Product.DefaultLocation.ID;
                     movement.Location.ID = entity.Product.DefaultLocation.ID;
                     movement.Date = entity.Returned;
                     movement.Date = entity.Returned;
                     movement.Issued = 0.0F;
                     movement.Issued = 0.0F;
                     movement.Received = entity.Quantity;
                     movement.Received = entity.Quantity;
+                    movement.Type = StockMovementType.Receive;
                     movement.Qty = movement.Received * movement.Dimensions.Value;
                     movement.Qty = movement.Received * movement.Dimensions.Value;
                     movement.Notes = string.Format("Returned by " + entity.Employee.Name);
                     movement.Notes = string.Format("Returned by " + entity.Employee.Name);
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Return Updated");
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Return Updated");

+ 1 - 0
prs.stores/PurchaseOrderItemStore.cs

@@ -222,6 +222,7 @@ namespace Comal.Stores
                 movement.Style.Description = entity.Style.Description;
                 movement.Style.Description = entity.Style.Description;
                 movement.Notes = string.Format("Received on PO {0}", entity.PurchaseOrderLink.PONumber);
                 movement.Notes = string.Format("Received on PO {0}", entity.PurchaseOrderLink.PONumber);
                 movement.Cost = entity.Cost;
                 movement.Cost = entity.Cost;
+                movement.Type = StockMovementType.Receive;
                 movement.Dimensions.Unit.ID = entity.Dimensions.Unit.ID;
                 movement.Dimensions.Unit.ID = entity.Dimensions.Unit.ID;
                 movement.Dimensions.Height = entity.Dimensions.Height;
                 movement.Dimensions.Height = entity.Dimensions.Height;
                 movement.Dimensions.Length = entity.Dimensions.Length;
                 movement.Dimensions.Length = entity.Dimensions.Length;

+ 11 - 8
prs.stores/RequisitionStore.cs

@@ -225,7 +225,7 @@ namespace Comal.Stores
 
 
         #region StockMovements
         #region StockMovements
 
 
-        private void CreateStockMovement(List<StockMovement> updates, Guid employeeid, DateTime date, Guid batchid, Guid productid, Guid locationid,
+        private StockMovement CreateStockMovement(Guid employeeid, DateTime date, Guid batchid, Guid productid, Guid locationid,
             Guid styleid, Guid jobid, double qty, IDimensions dimensions, Guid txnid, bool system, string note)
             Guid styleid, Guid jobid, double qty, IDimensions dimensions, Guid txnid, bool system, string note)
         {
         {
             var movement = new StockMovement();
             var movement = new StockMovement();
@@ -236,6 +236,9 @@ namespace Comal.Stores
             movement.Job.ID = jobid;
             movement.Job.ID = jobid;
             movement.Issued = qty < 0.0F ? Math.Abs(qty) : 0.0F;
             movement.Issued = qty < 0.0F ? Math.Abs(qty) : 0.0F;
             movement.Received = qty > 0.0F ? qty : 0.0F;
             movement.Received = qty > 0.0F ? qty : 0.0F;
+
+            movement.Type = movement.Issued > 0 ? StockMovementType.TransferOut : StockMovementType.TransferIn;
+
             movement.Qty = qty;
             movement.Qty = qty;
             movement.Units = qty;
             movement.Units = qty;
             movement.Dimensions.CopyFrom(dimensions);
             movement.Dimensions.CopyFrom(dimensions);
@@ -244,7 +247,7 @@ namespace Comal.Stores
             movement.Notes = note;
             movement.Notes = note;
             movement.Date = date;
             movement.Date = date;
             movement.Employee.ID = employeeid;
             movement.Employee.ID = employeeid;
-            updates.Add(movement);
+            return movement;
         }
         }
 
 
         private void CreateStockBatch(Requisition entity, ref IEnumerable<RequisitionItem> items)
         private void CreateStockBatch(Requisition entity, ref IEnumerable<RequisitionItem> items)
@@ -299,15 +302,15 @@ namespace Comal.Stores
                 if (jobid != holdingjobid)
                 if (jobid != holdingjobid)
                 {
                 {
                     txnid = Guid.NewGuid();
                     txnid = Guid.NewGuid();
-                    CreateStockMovement(updates, entity.Employee.ID, DateTime.Now, batch.ID, productid, locationid, styleid, holdingjobid,
-                        0.0F - qty, dimensions, txnid, true, string.Format("Requisition #{0} Internal Transfer", entity.Number));
-                    CreateStockMovement(updates, entity.Employee.ID, DateTime.Now, batch.ID, productid, locationid, styleid, jobid, qty, dimensions, txnid, true,
-                        string.Format("Requisition #{0} Internal Transfer", entity.Number));
+                    updates.Add(CreateStockMovement(entity.Employee.ID, DateTime.Now, batch.ID, productid, locationid, styleid, holdingjobid,
+                        -qty, dimensions, txnid, true, string.Format("Requisition #{0} Internal Transfer", entity.Number)));
+                    updates.Add(CreateStockMovement(entity.Employee.ID, DateTime.Now, batch.ID, productid, locationid, styleid, jobid, qty, dimensions, txnid, true,
+                        string.Format("Requisition #{0} Internal Transfer", entity.Number)));
                 }
                 }
 
 
-                CreateStockMovement(updates, entity.Employee.ID, DateTime.Now, batch.ID, productid, locationid, styleid, jobid, 0.0F - qty, dimensions, txnid,
+                updates.Add(CreateStockMovement(entity.Employee.ID, DateTime.Now, batch.ID, productid, locationid, styleid, jobid, 0.0F - qty, dimensions, txnid,
                     false,
                     false,
-                    string.Format("Requisition #{0}", entity.Number));
+                    string.Format("Requisition #{0}", entity.Number)));
             }
             }
 
 
             FindSubStore<StockMovement>().Save(updates, "");
             FindSubStore<StockMovement>().Save(updates, "");