Jelajahi Sumber

Added StockMovementType enum and fixed some StockMovement creators.

Kenric Nugteren 1 tahun lalu
induk
melakukan
3654942a3e

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

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.Linq;
 using System.Linq.Expressions;
 using InABox.Core;
@@ -138,6 +137,9 @@ namespace Comal.Classes
         [MemoEditor]
         [EditorSequence(10)]
         public string Notes { get; set; }
+
+        [EnumLookupEditor(typeof(StockMovementType))]
+        public StockMovementType Type { get; set; }
         
         [NullEditor]
         public Guid Transaction { get; set; } = Guid.NewGuid();
@@ -219,7 +221,7 @@ namespace Comal.Classes
             else if (issued.IsEqualTo(name))
             {
                 bChanging = true;
-                Units = (Received - (double)after);
+                Units = Received - (double)after;
                 Qty = Units * Dimensions.Value;
                 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;
         }
 
-        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"))
             {
-                var form = sender as IDynamicEditorForm;
                 var editor = form.FindEditor("Job.ID");
                 if (!value.Equals(Guid.Empty))
                     result = DynamicGridUtils.UpdateEditorValue(form.Items, "Job.ID", value);
@@ -256,6 +255,7 @@ namespace PRSDesktop
             movement.Date = DateTime.Now;
             movement.IsTransfer = false;
             movement.Employee.ID = _employeeid;
+            movement.Type = StockMovementType.Receive;
 
             movement.CommitChanges();
 
@@ -306,8 +306,10 @@ namespace PRSDesktop
             // var stylecode = rows.First().Get<StockHolding, string>(x => x.Style.Code);
             // 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.Code = Location.Code;
             movement.Location.Description = Location.Description;
@@ -320,6 +322,7 @@ namespace PRSDesktop
             movement.IsTransfer = false;
             movement.Employee.ID = _employeeid;
             movement.Cost = holding.AverageValue;
+            movement.Type = StockMovementType.Issue;
 
             movement.CommitChanges();
 
@@ -336,8 +339,10 @@ namespace PRSDesktop
             if (result && holding.Job.ID != movement.Job.ID)
             {
                 // 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.Job.ID = holding.Job.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.System = true;
                 issue.Cost = holding.AverageValue;
+                issue.Type = StockMovementType.TransferOut;
 
                 // Receive to New Job (Hidden)
                 var receive = new StockMovement();
@@ -367,6 +373,7 @@ namespace PRSDesktop
                     !movement.Job.IsValid() ? "General Stock" : "Job " + movement.Job.JobNumber);
                 receive.System = true;
                 receive.Cost = holding.AverageValue;
+                receive.Type = StockMovementType.TransferIn;
 
                 new Client<StockMovement>().Save(new[] { issue, receive }, "");
                 mvts.Add(issue);
@@ -412,6 +419,7 @@ namespace PRSDesktop
             movement.Received = holding.Units;
             movement.IsTransfer = true;
             movement.Cost = holding.AverageValue;
+            movement.Type = StockMovementType.TransferIn;
 
             movement.CommitChanges();
 
@@ -442,6 +450,7 @@ namespace PRSDesktop
                 other.Employee.ID = movement.Employee.ID;
                 other.Dimensions.CopyFrom(holding.Dimensions);
                 other.IsTransfer = true;
+                other.Type = StockMovementType.TransferOut;
 
                 var changes = new List<string>();
                 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
         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");
         }
@@ -432,14 +432,14 @@ namespace PRSDesktop
 
         private StockMovement CreateMovement(StockTakeHolding holding, double qty, Guid batchID)
         {
-            StockMovement movement = CreateBaseMovement(holding, batchID);
+            var movement = CreateBaseMovement(holding, batchID);
 
             return DetermineMovementType(movement, qty);
         }
 
         private StockMovement CreateBaseMovement(StockTakeHolding holding, Guid batchID)
         {
-            StockMovement movement = new StockMovement();
+            var movement = new StockMovement();
 
             movement.Batch.ID = batchID;
             movement.IsTransfer = false;
@@ -454,11 +454,12 @@ namespace PRSDesktop
             movement.Date = DateTime.Now;
             movement.Location.ID = holding.Location.ID;
             movement.IsRemnant = false;
+            movement.Type = StockMovementType.StockTake;
 
             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.HasQuantity = holding.Dimensions.Unit.HasQuantity;
@@ -479,13 +480,17 @@ namespace PRSDesktop
             return movement;
         }
 
-        private StockMovement DetermineMovementType(StockMovement movement, double qty)
+        private static StockMovement DetermineMovementType(StockMovement movement, double qty)
         {
             if (qty < 0)
+            {
                 movement.Issued = 0 - qty;
+            }
 
             if (qty > 0)
+            {
                 movement.Received = qty;
+            }
 
             if (movement.Issued != 0 || movement.Received != 0)
                 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)
         {
-            JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
+            JobRequisitionItem item = row?.ToObject<JobRequisitionItem>();
             if (CheckValidAction(item, false))
             {
                 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>();
             if (!CheckValidAction(item, true))
                 return;
-            CoreTable table = new Client<StockMovement>().Query
-                (
+            var table = Client.Query(
                 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())
             {
                 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:
                         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 ";
             }
-            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)

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

@@ -88,27 +88,32 @@ namespace PRSDesktop
 
         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");
 
             var issuing = CreateBaseMovement(model, batch.ID);
             issuing.Job.ID = IssuingJobID;
             issuing.Issued = model.ChosenUnits;
+            issuing.Type = StockMovementType.TransferOut;
 
             var receiving = CreateBaseMovement(model, batch.ID);
             receiving.Job.ID = Item.Job.ID;
             receiving.Received = model.ChosenUnits;
             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)
         {
-            StockMovement mvt = new StockMovement();
+            var mvt = new StockMovement();
             mvt.Style.ID = model.Holding.Style.ID;
             mvt.Location.ID = model.Holding.Location.ID;
             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.Text;
 using System.Threading.Tasks;
-using Comal.Classes;
-using InABox.Clients;
-using InABox.Core;
-using InABox.DigitalMatter;
-using InABox.IPC;
 using InABox.Rpc;
-using PRSServer.Engines;
 using System.Timers;
 using PRS.Shared;
 

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

@@ -305,7 +305,7 @@ namespace PRSServer
         
         private class TwoFARequest
         {
-            public string Code { get; set; }
+            public string? Code { get; set; }
         }
 
         private IResponseBuilder Handle2FA(IRequest request)
@@ -1009,7 +1009,10 @@ Model.LoadModel(
             );
             if (documentTable.Rows.Count == 0) return null;
             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)
@@ -1023,12 +1026,7 @@ Model.LoadModel(
 
             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 + "'");
                     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);
                 }
-                catch (ArgumentException ex)
+                catch (ArgumentException)
                 {
                     searchRegex = null;
                 }

+ 23 - 40
prs.stores/ConsignmentStore.cs

@@ -17,8 +17,6 @@ namespace Comal.Stores
         {
             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
             if (entity.ActualWarehouseArrival == DateTime.MinValue)
                 return;
@@ -26,22 +24,20 @@ namespace Comal.Stores
                 return;
 
             //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 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;
 
-            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 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
-            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,
                 new Columns<StockMovement>(
                     x => x.ID,
@@ -73,24 +62,19 @@ namespace Comal.Stores
             if (stockMovementTable.Rows.Any())
             {
                 //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;
 
                 //create new stockmovementbatch to attach new stockmovements to (movements created by server)
-                StockMovementBatch batch = new StockMovementBatch();
+                var batch = new StockMovementBatch();
                 batch.Type = StockMovementBatchType.Receipt;
                 Provider.Save(batch);
 
                 //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.Employee.ID = entity.Employee.ID;
                     movement.Notes = movement.Notes + " / Consignment " + entity.Number;
@@ -98,8 +82,8 @@ namespace Comal.Stores
                 }
                 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();
                     smd.EntityLink.ID = batch.ID;
@@ -112,17 +96,16 @@ namespace Comal.Stores
 
         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);
-                PurchaseOrderDocument PODocument = new PurchaseOrderDocument();
+                var PODocument = new PurchaseOrderDocument();
                 PODocument.DocumentLink.ID = docID;
                 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 Columns<PurchaseOrderDocument>(x => x.ID));
                 if (existingPODocs.Rows.Count == 0)

+ 10 - 4
prs.stores/EmployeeProductStore.cs

@@ -28,6 +28,8 @@ namespace Comal.Stores
                     movement.Date = entity.Issued;
                     movement.Issued = entity.Quantity;
                     movement.Received = 0.0F;
+
+                    movement.Type = StockMovementType.Issue;
                     
                     movement.Dimensions.Unit.ID = entity.Product.Dimensions.Unit.ID;
                     movement.Dimensions.Unit.Synchronise(entity.Product.Dimensions);
@@ -44,16 +46,19 @@ namespace Comal.Stores
                 else
                 {
                     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.Dimensions.CopyFrom(entity.Product.Dimensions);
                     movement.Location.ID = entity.Product.DefaultLocation.ID;
                     movement.Date = entity.Issued;
                     movement.Issued = entity.Quantity;
                     movement.Received = 0.0F;
+
+                    movement.Type = StockMovementType.Issue;
+
                     movement.Qty = 0.0F - movement.Issued * movement.Dimensions.Value;
                     movement.Notes = string.Format("Issued to " + entity.Employee.Name);
+
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Issue Updated");
                     entity.IssuedMovement.ID = movement.ID;
                 }
@@ -82,6 +87,7 @@ namespace Comal.Stores
                     movement.Date = entity.Returned;
                     movement.Issued = 0.0F;
                     movement.Received = entity.Quantity;
+                    movement.Type = StockMovementType.Receive;
                     movement.Qty = movement.Received * movement.Dimensions.Value;
                     movement.Notes = string.Format("Returned by " + entity.Employee.Name);
                     FindSubStore<StockMovement>().Save(movement, "Employee/Product Return Created");
@@ -90,14 +96,14 @@ namespace Comal.Stores
                 else
                 {
                     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.Dimensions.CopyFrom(entity.Product.Dimensions);
                     movement.Location.ID = entity.Product.DefaultLocation.ID;
                     movement.Date = entity.Returned;
                     movement.Issued = 0.0F;
                     movement.Received = entity.Quantity;
+                    movement.Type = StockMovementType.Receive;
                     movement.Qty = movement.Received * movement.Dimensions.Value;
                     movement.Notes = string.Format("Returned by " + entity.Employee.Name);
                     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.Notes = string.Format("Received on PO {0}", entity.PurchaseOrderLink.PONumber);
                 movement.Cost = entity.Cost;
+                movement.Type = StockMovementType.Receive;
                 movement.Dimensions.Unit.ID = entity.Dimensions.Unit.ID;
                 movement.Dimensions.Height = entity.Dimensions.Height;
                 movement.Dimensions.Length = entity.Dimensions.Length;

+ 11 - 8
prs.stores/RequisitionStore.cs

@@ -225,7 +225,7 @@ namespace Comal.Stores
 
         #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)
         {
             var movement = new StockMovement();
@@ -236,6 +236,9 @@ namespace Comal.Stores
             movement.Job.ID = jobid;
             movement.Issued = qty < 0.0F ? Math.Abs(qty) : 0.0F;
             movement.Received = qty > 0.0F ? qty : 0.0F;
+
+            movement.Type = movement.Issued > 0 ? StockMovementType.TransferOut : StockMovementType.TransferIn;
+
             movement.Qty = qty;
             movement.Units = qty;
             movement.Dimensions.CopyFrom(dimensions);
@@ -244,7 +247,7 @@ namespace Comal.Stores
             movement.Notes = note;
             movement.Date = date;
             movement.Employee.ID = employeeid;
-            updates.Add(movement);
+            return movement;
         }
 
         private void CreateStockBatch(Requisition entity, ref IEnumerable<RequisitionItem> items)
@@ -299,15 +302,15 @@ namespace Comal.Stores
                 if (jobid != holdingjobid)
                 {
                     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,
-                    string.Format("Requisition #{0}", entity.Number));
+                    string.Format("Requisition #{0}", entity.Number)));
             }
 
             FindSubStore<StockMovement>().Save(updates, "");