Browse Source

PRS MOBILE - refactor of site manufacturing search, changed site requis to load holdings on demand instead of cache

Nick 2 years ago
parent
commit
6f24088f45

+ 2 - 1
prs.mobile/comal.timesheets.Android/Resources/Resource.designer.cs

@@ -14,7 +14,7 @@ namespace comal.timesheets.Droid
 {
 	
 	
-	[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.0.0.73")]
+	[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.1.0.5")]
 	public partial class Resource
 	{
 		
@@ -25,6 +25,7 @@ namespace comal.timesheets.Droid
 		
 		public static void UpdateIdValues()
 		{
+			global::InABox.Mobile.AppVersion.Android.Resource.String.library_name = global::comal.timesheets.Droid.Resource.String.library_name;
 			global::Lottie.Forms.Resource.Animation.abc_fade_in = global::comal.timesheets.Droid.Resource.Animation.abc_fade_in;
 			global::Lottie.Forms.Resource.Animation.abc_fade_out = global::comal.timesheets.Droid.Resource.Animation.abc_fade_out;
 			global::Lottie.Forms.Resource.Animation.abc_grow_fade_in_from_bottom = global::comal.timesheets.Droid.Resource.Animation.abc_grow_fade_in_from_bottom;

+ 2 - 1
prs.mobile/comal.timesheets/Main/MainPage.xaml.cs

@@ -110,7 +110,8 @@ namespace comal.timesheets
             string latestChanges = "";
             List<string> changes = new List<string>
             {
-                "- Upgrade to Setouts Module"
+                "- Improvement to Site Manufacturing search",
+                "- Improve speed + fixes to Store Requis"
             };
             foreach (string s in changes)
             {

+ 0 - 0
prs.mobile/comal.timesheets/SiteManufacturing.xaml → prs.mobile/comal.timesheets/Site/SiteManufacturing.xaml


+ 66 - 52
prs.mobile/comal.timesheets/SiteManufacturing.xaml.cs → prs.mobile/comal.timesheets/Site/SiteManufacturing.xaml.cs

@@ -16,7 +16,7 @@ namespace comal.timesheets
     public partial class SiteManufacturing : ContentPage
     {
         #region Constructor / Fields
-        List<MiniManufacturingPacket> packets = new List<MiniManufacturingPacket>();
+        List<SiteManufacturingPacketShell> packets = new List<SiteManufacturingPacketShell>();
         Guid JobID = new Guid();
 
         public SiteManufacturing(Guid jobid = new Guid())
@@ -136,7 +136,7 @@ namespace comal.timesheets
 
         private void CreateAndAddPacket(CoreRow row)
         {
-            packets.Add(new MiniManufacturingPacket
+            packets.Add(new SiteManufacturingPacketShell
             {
                 ID = row.Get<ManufacturingPacket, Guid>(x => x.ID),
                 OrderID = row.Get<ManufacturingPacket, Guid>(x => x.OrderItem.ID),
@@ -157,7 +157,7 @@ namespace comal.timesheets
         {
             try
             {
-                MiniManufacturingPacket packet = listView.SelectedItem as MiniManufacturingPacket;
+                SiteManufacturingPacketShell packet = listView.SelectedItem as SiteManufacturingPacketShell;
                 ManufacturingPacketPopup popup = new ManufacturingPacketPopup(packet.ID, packet.OrderID);
                 Navigation.PushAsync(popup);
             }
@@ -171,7 +171,7 @@ namespace comal.timesheets
         {
             try
             {
-                var item = ((TappedEventArgs)e).Parameter as MiniManufacturingPacket;
+                var item = ((TappedEventArgs)e).Parameter as SiteManufacturingPacketShell;
                 if (item == null) return;
 
                 Dictionary<string, Guid> fileNameIDS = new Dictionary<string, Guid>();
@@ -205,29 +205,42 @@ namespace comal.timesheets
         #endregion
 
         #region Searching
+        List<SiteManufacturingPacketShell> serialSearchList = new List<SiteManufacturingPacketShell>();
+        List<SiteManufacturingPacketShell> locationSearchList = new List<SiteManufacturingPacketShell>();
+        List<SiteManufacturingPacketShell> setoutSearchList = new List<SiteManufacturingPacketShell>();
 
-        List<MiniManufacturingPacket> locationSearchList = new List<MiniManufacturingPacket>();
-        List<MiniManufacturingPacket> serialSearchList = new List<MiniManufacturingPacket>();
-        List<MiniManufacturingPacket> setoutSearchList = new List<MiniManufacturingPacket>();
+        bool bSerialSearch = false;
+        bool bLocationSearch = false;
+        bool bSetoutSearch = false;
 
-        private void LocationSearchEnt_Changed(object sender, EventArgs e)
+        private void SerialSearchEnt_Changed(object sender, EventArgs e)
         {
-            locationSearchList.Clear();
+            serialSearchList.Clear();
 
-            if (!string.IsNullOrWhiteSpace(locationSearchEnt.Text))
-                locationSearchList = CreateLocationSearchList(packets);
+            if (!string.IsNullOrWhiteSpace(serialSearchEnt.Text))
+            {
+                bSerialSearch = true;
+                serialSearchList = CreateSerialSearchList(packets);
+            }
+            else
+                bSerialSearch = false;
 
-            RunSearch(locationSearchEnt.Text);
+            RunSearch();
         }
 
-        private void SerialSearchEnt_Changed(object sender, EventArgs e)
+        private void LocationSearchEnt_Changed(object sender, EventArgs e)
         {
-            serialSearchList.Clear();
+            locationSearchList.Clear();
 
-            if (!string.IsNullOrWhiteSpace(serialSearchEnt.Text))
-                serialSearchList = CreateSerialSearchList(packets);
+            if (!string.IsNullOrWhiteSpace(locationSearchEnt.Text))
+            {
+                bLocationSearch = true;
+                locationSearchList = CreateLocationSearchList(packets);
+            }
+            else
+                bLocationSearch = false;
 
-            RunSearch(serialSearchEnt.Text);
+            RunSearch();
         }
 
         private void SetoutSearchEnt_Changed(object sender, EventArgs e)
@@ -235,59 +248,60 @@ namespace comal.timesheets
             setoutSearchList.Clear();
 
             if (!string.IsNullOrWhiteSpace(setoutSearchEnt.Text))
+            {
+                bSetoutSearch = true;
                 setoutSearchList = CreateSetoutSearchList(packets);
+            }
+            else
+                bSetoutSearch = false;
 
-            RunSearch(setoutSearchEnt.Text);
+            RunSearch();
         }
 
-        private void RunSearch(string search)
+        private void RunSearch()
         {
-            List<MiniManufacturingPacket> searchList = new List<MiniManufacturingPacket>();
+            List<SiteManufacturingPacketShell> searchList = new List<SiteManufacturingPacketShell>();
 
-            if (locationSearchList.Count > 0 && serialSearchList.Count > 0 && setoutSearchList.Count > 0)
+            if (bSerialSearch && bLocationSearch && bSetoutSearch)
             {
-                searchList = CreateLocationSearchList(packets);
-                searchList = CreateSerialSearchList(searchList);
+                searchList = serialSearchList;
+                searchList = CreateLocationSearchList(searchList);
                 searchList = CreateSetoutSearchList(searchList);
             }
-            else if (locationSearchList.Count > 0 && serialSearchList.Count > 0)
+            else if (bSerialSearch && bLocationSearch && !bSetoutSearch)
             {
-                searchList = CreateLocationSearchList(packets);
-                searchList = CreateSerialSearchList(searchList);
+                searchList = serialSearchList;
+                searchList = CreateLocationSearchList(searchList);
             }
-            else if (locationSearchList.Count > 0 && setoutSearchList.Count > 0)
+            else if (bSerialSearch && !bLocationSearch && bSetoutSearch)
             {
-                searchList = CreateLocationSearchList(packets);
+                searchList = serialSearchList;
                 searchList = CreateSetoutSearchList(searchList);
             }
-            else if (serialSearchList.Count > 0 && setoutSearchList.Count > 0)
+            else if (!bSerialSearch && bLocationSearch && bSetoutSearch)
             {
-                searchList = CreateSerialSearchList(packets);
+                searchList = locationSearchList;
                 searchList = CreateSetoutSearchList(searchList);
             }
-            else if (locationSearchList.Count > 0 && serialSearchList.Count == 0 && setoutSearchList.Count == 0)
-            {
-                searchList = CreateLocationSearchList(packets);
-            }
-            else if (serialSearchList.Count > 0 && locationSearchList.Count == 0 && setoutSearchList.Count == 0)
-            {
-                searchList = CreateSerialSearchList(packets);
-            }
-            else if (setoutSearchList.Count > 0 && serialSearchList.Count == 0 && locationSearchList.Count == 0)
-            {
-                searchList = CreateSetoutSearchList(packets);
-            }
+            else if (bSerialSearch && !bLocationSearch && !bSetoutSearch)
+                searchList = serialSearchList;
+
+            else if (!bSerialSearch && bLocationSearch && !bSetoutSearch)
+                searchList = locationSearchList;
 
-            if (searchList.Count > 0)
+            else if (!bSerialSearch && !bLocationSearch && bSetoutSearch)
+                searchList = setoutSearchList;
+            
+            if (bSerialSearch || bLocationSearch || bSetoutSearch)
                 RefreshOnListChange(searchList);
             else
                 RefreshOnListChange(packets);
         }
 
-        private List<MiniManufacturingPacket> CreateLocationSearchList(List<MiniManufacturingPacket> sublist)
+        private List<SiteManufacturingPacketShell> CreateLocationSearchList(List<SiteManufacturingPacketShell> sublist)
         {
             string search = locationSearchEnt.Text;
-            List<MiniManufacturingPacket> returnList = new List<MiniManufacturingPacket>();
+            List<SiteManufacturingPacketShell> returnList = new List<SiteManufacturingPacketShell>();
             var list = sublist.Where(
                    x => x.Location.Contains(search)
                    || x.Location.Contains(SearchUtils.UpperCaseFirst(search))
@@ -303,10 +317,10 @@ namespace comal.timesheets
             return returnList;
         }
 
-        private List<MiniManufacturingPacket> CreateSerialSearchList(List<MiniManufacturingPacket> sublist)
+        private List<SiteManufacturingPacketShell> CreateSerialSearchList(List<SiteManufacturingPacketShell> sublist)
         {
             string search = serialSearchEnt.Text;
-            List<MiniManufacturingPacket> returnList = new List<MiniManufacturingPacket>();
+            List<SiteManufacturingPacketShell> returnList = new List<SiteManufacturingPacketShell>();
             var list = sublist.Where(
                 x => x.Serial.Contains(search)
                 || x.Serial.Contains(SearchUtils.UpperCaseFirst(search))
@@ -322,10 +336,10 @@ namespace comal.timesheets
             return returnList;
         }
 
-        private List<MiniManufacturingPacket> CreateSetoutSearchList(List<MiniManufacturingPacket> sublist)
+        private List<SiteManufacturingPacketShell> CreateSetoutSearchList(List<SiteManufacturingPacketShell> sublist)
         {
             string search = setoutSearchEnt.Text;
-            List<MiniManufacturingPacket> returnList = new List<MiniManufacturingPacket>();
+            List<SiteManufacturingPacketShell> returnList = new List<SiteManufacturingPacketShell>();
             var list = sublist.Where(
                 x => x.Setout.Contains(search)
                 || x.Setout.Contains(SearchUtils.UpperCaseFirst(search))
@@ -341,7 +355,7 @@ namespace comal.timesheets
             return returnList;
         }
 
-        private void RefreshOnListChange(IEnumerable<MiniManufacturingPacket> list)
+        private void RefreshOnListChange(IEnumerable<SiteManufacturingPacketShell> list)
         {
             listView.ItemsSource = null;
             listView.ItemsSource = list;
@@ -354,7 +368,7 @@ namespace comal.timesheets
     /// <summary>
     /// ViewModel class for SiteManufacturing Module
     /// </summary>
-    public class MiniManufacturingPacket
+    public class SiteManufacturingPacketShell
     {
         public Guid ID { get; set; }
         public Guid OrderID { get; set; }
@@ -362,7 +376,7 @@ namespace comal.timesheets
         public string Serial { get; set; }
         public string Location { get; set; }
         public string Setout { get; set; }
-        public MiniManufacturingPacket()
+        public SiteManufacturingPacketShell()
         {
             ID = Guid.Empty;
             OrderID = Guid.Empty;

+ 4 - 55
prs.mobile/comal.timesheets/StoreRequis/RequiItems.cs

@@ -12,12 +12,12 @@ namespace comal.timesheets
     {
         public static List<StoreRequiItem> NewRequisitionRows { get; set; }
         public static List<RequisitionItem> OldRequisitionItems { get; set; }
-        public static List<HoldingsCacheShell> holdingsCache { get; set; }
+        public static List<StoreRequiIHoldingShell> holdingsCache { get; set; }
         public static bool HoldingsLoaded { get; set; }
 
 
         [DoNotPersist]
-        public class HoldingsCacheShell : Entity
+        public class StoreRequiIHoldingShell : Entity
         {
             public Guid LocationID { get; set; }
             public Guid ProductID { get; set; }
@@ -31,7 +31,7 @@ namespace comal.timesheets
             public string StyleDescription { get; set; }
             public StockDimensions Dimensions { get; set; }
 
-            public HoldingsCacheShell()
+            public StoreRequiIHoldingShell()
             {
                 LocationID = Guid.Empty;
                 ProductID = Guid.Empty;
@@ -44,58 +44,7 @@ namespace comal.timesheets
                 StyleCode = "";
                 StyleDescription = "";
                 Dimensions = new StockDimensions(() => this);
-            }
-
-            /// <summary>
-            /// For Display Purposes, and save loading time until Dimensions are needed
-            /// </summary>
-            public void UpdateDimensionsAndLocationName()
-            {
-                if (ProductID != Guid.Empty)
-                {
-                    CoreTable table = new Client<Product>().Query(new Filter<Product>(x => x.ID).IsEqualTo(ProductID),
-                        new Columns<Product>(
-                            x => x.Dimensions.Unit.ID,
-                            x => x.Dimensions.Unit.HasQuantity,
-                            x => x.Dimensions.Unit.HasLength,
-                            x => x.Dimensions.Unit.HasHeight,
-                            x => x.Dimensions.Unit.HasWeight,
-                            x => x.Dimensions.Unit.HasWidth,
-                            x => x.Dimensions.Quantity,
-                            x => x.Dimensions.Length,
-                            x => x.Dimensions.Height,
-                            x => x.Dimensions.Weight,
-                            x => x.Dimensions.Width,
-                            x => x.Dimensions.Unit.Format,
-                            x => x.Dimensions.Unit.Formula,
-                            x => x.Dimensions.UnitSize
-                            ));
-                    Product product = table.Rows.FirstOrDefault().ToObject<Product>();
-
-                    Dimensions.Unit.ID = product.Dimensions.Unit.ID;
-                    Dimensions.Unit.HasQuantity = product.Dimensions.Unit.HasQuantity;
-                    Dimensions.Unit.HasLength = product.Dimensions.Unit.HasLength;
-                    Dimensions.Unit.HasHeight = product.Dimensions.Unit.HasHeight;
-                    Dimensions.Unit.HasWeight = product.Dimensions.Unit.HasWeight;
-                    Dimensions.Unit.HasWidth = product.Dimensions.Unit.HasWidth;
-
-                    Dimensions.Quantity = product.Dimensions.Quantity;
-                    Dimensions.Length = product.Dimensions.Length;
-                    Dimensions.Height = product.Dimensions.Height;
-                    Dimensions.Weight = product.Dimensions.Weight;
-                    Dimensions.Width = product.Dimensions.Width;
-
-                    Dimensions.Unit.Format = product.Dimensions.Unit.Format;
-                    Dimensions.Unit.Formula = product.Dimensions.Unit.Formula;
-
-                    Dimensions.UnitSize = product.Dimensions.UnitSize;
-                }
-
-                LocationName = LocationName + " (Units: " + Units + ")" +
-                            Environment.NewLine + "Style: " + StyleDescription
-                            + Environment.NewLine + "Job: " + JobNumber
-                            + Environment.NewLine + "Size: " + Dimensions.UnitSize;
-            }
+            }            
         }
 
     }

+ 3 - 89
prs.mobile/comal.timesheets/StoreRequis/StoreRequiList.xaml.cs

@@ -20,7 +20,8 @@ namespace comal.timesheets.StoreRequis
         public StoreRequiList()
         {
             InitializeComponent();
-            LoadHoldingsCache();
+            //LoadHoldingsCache();
+            HoldingsLoaded = true;
             if (Device.RuntimePlatform.Equals(Device.iOS))
             {
                 imageBtn0.Margin = new Thickness(0);
@@ -105,94 +106,7 @@ namespace comal.timesheets.StoreRequis
         {
             StoreRequiConfirmationPage storeRequiConfirmationPage = new StoreRequiConfirmationPage();
             Navigation.PushAsync(storeRequiConfirmationPage);
-        }
-
-        #region Utilities
-        private async void LoadHoldingsCache()
-        {
-            await Task.Run(() =>
-            {
-                holdingsCache = new List<HoldingsCacheShell>();
-                CoreTable table = new Client<StockHolding>().Query(
-                        new Filter<StockHolding>(x => x.Qty).IsGreaterThan(0),
-                        new Columns<StockHolding>(
-                            x => x.ID,
-                            x => x.Product.ID,
-                            x => x.Location.ID,
-                            x => x.Location.Description,
-                            x => x.Units,
-                            x => x.Job.ID,
-                            x => x.Job.JobNumber,
-                            x => x.Job.Name,
-                            x => x.Style.ID,
-                            x => x.Style.Code,
-                            x => x.Style.Description,
-                            x => x.Dimensions.Unit.ID,
-                            x => x.Dimensions.Unit.HasQuantity,
-                            x => x.Dimensions.Unit.HasLength,
-                            x => x.Dimensions.Unit.HasHeight,
-                            x => x.Dimensions.Unit.HasWeight,
-                            x => x.Dimensions.Unit.HasWidth,
-                            x => x.Dimensions.Quantity,
-                            x => x.Dimensions.Length,
-                            x => x.Dimensions.Height,
-                            x => x.Dimensions.Weight,
-                            x => x.Dimensions.Width,
-                            x => x.Dimensions.Unit.Format,
-                            x => x.Dimensions.Unit.Formula,
-                            x => x.Dimensions.UnitSize
-                            )
-                        );
-                foreach (CoreRow row in table.Rows)
-                {
-                    if (row.Get<StockHolding, double>(x => x.Units) == 0.0)
-                        continue;
-
-                    HoldingsCacheShell holding = new HoldingsCacheShell()
-                    {
-                        ProductID = row.Get<StockHolding, Guid>(x => x.Product.ID),
-                        LocationID = row.Get<StockHolding, Guid>(x => x.Location.ID),
-                        LocationName = row.Get<StockHolding, string>(x => x.Location.Description),
-                        Units = row.Get<StockHolding, double>(x => x.Units).ToString(),
-                        JobID = row.Get<StockHolding, Guid>(x => x.Job.ID),
-                        JobNumber = row.Get<StockHolding, string>(x => x.Job.JobNumber),
-                        JobName = row.Get<StockHolding, string>(x => x.Job.Name),
-                        StyleID = row.Get<StockHolding, Guid>(x => x.Style.ID),
-                        StyleCode = row.Get<StockHolding, string>(x => x.Style.Code),
-                        StyleDescription = row.Get<StockHolding, string>(x => x.Style.Description)
-                    };
-
-                    holding.Dimensions.Unit.ID = row.Get<StockHolding, Guid>(x => x.Dimensions.Unit.ID);
-                    holding.Dimensions.Unit.HasQuantity = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasQuantity);
-                    holding.Dimensions.Unit.HasLength = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasLength);
-                    holding.Dimensions.Unit.HasHeight = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasHeight);
-                    holding.Dimensions.Unit.HasWeight = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasWeight);
-                    holding.Dimensions.Unit.HasWidth = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasWidth);
-
-                    holding.Dimensions.Quantity = row.Get<StockHolding, double>(x => x.Dimensions.Quantity);
-                    holding.Dimensions.Length = row.Get<StockHolding, double>(x => x.Dimensions.Length);
-                    holding.Dimensions.Height = row.Get<StockHolding, double>(x => x.Dimensions.Height);
-                    holding.Dimensions.Weight = row.Get<StockHolding, double>(x => x.Dimensions.Weight);
-                    holding.Dimensions.Width = row.Get<StockHolding, double>(x => x.Dimensions.Width);
-
-                    holding.Dimensions.Unit.Format = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Format);
-                    holding.Dimensions.Unit.Formula = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Formula);
-
-                    holding.Dimensions.UnitSize = row.Get<StockHolding, string>(x => x.Dimensions.UnitSize);
-
-                    holding.LocationName = holding.LocationName + " (Units: " + holding.Units + ")" +
-                           Environment.NewLine + "Style: " + holding.StyleDescription
-                           + Environment.NewLine + "Job: " + holding.JobNumber
-                           + Environment.NewLine + "Size: " + holding.Dimensions.UnitSize;
-
-                    holdingsCache.Add(holding);
-                }
-;
-                RequiItems.HoldingsLoaded = true;
-            });
-        }
-
-        #endregion
+        }       
     }
 
     public class RequiShell

+ 126 - 36
prs.mobile/comal.timesheets/StoreRequis/StoreRequiScannerPage.xaml.cs

@@ -1,19 +1,18 @@
-using System;
+using comal.timesheets.StoreRequis;
+using Comal.Classes;
+using InABox.Clients;
+using InABox.Core;
+using Javax.Xml.Transform.Sax;
+using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using Xamarin.Essentials;
 using Xamarin.Forms;
 using Xamarin.Forms.Xaml;
-using Comal.Classes;
-using InABox.Core;
-using InABox.Clients;
-using System.Threading;
-using static comal.timesheets.RequiItems;
 using XF.Material.Forms.UI.Dialogs;
-using comal.timesheets.StoreRequis;
-using ZXing.PDF417.Internal;
+using static comal.timesheets.RequiItems;
 
 namespace comal.timesheets
 {
@@ -288,38 +287,20 @@ namespace comal.timesheets
                 //lookup product in productshells cache
                 ProductShell product = GlobalVariables.ProductShells.Find(x => x.Code.Equals(processedResultQtyTuple.Item1));
 
-                string itemLocation = "";
-                Guid locationID = Guid.Empty;
-
                 //lookup holding for product in holdings cache
                 try
                 {
-                    List<HoldingsCacheShell> list = holdingsCache.Where(x => x.ProductID.Equals(product.ID)).ToList();
+                    var list = CreateHoldingsList(product.ID);
+
                     if (list.Count == 1) //one stockholding - auto choose holding
-                        AddShell(list.First(), product, rawResult, processedResultQtyTuple);
+                        AddStoreRequiItemShell(list.First(), product, rawResult, processedResultQtyTuple);
+
+                    else if (list.Count > 1)  //more than one stockholding - user choose shelf                    
+                        UserSelectFromList(list, product, rawResult, processedResultQtyTuple);
                     
-                    else if (list.Count > 1)  //more than one stockholding - user choose shelf
-                    {
-                        Dictionary<string, Guid> holdingLocationIDs = new Dictionary<string, Guid>();
-                        foreach (HoldingsCacheShell holding in list)
-                        {
-                            if (!holdingLocationIDs.ContainsKey(holding.LocationName))
-                                holdingLocationIDs.Add(holding.LocationName, holding.LocationID);
-                        }
-                        List<string> options = holdingLocationIDs.Keys.ToList();
-                        ListSelectionPage page = new ListSelectionPage(options);
-                        page.OnSimpleListTapped += (locationName) =>
-                        {
-                            AddShell(list.Find(x => x.LocationName == locationName),product, rawResult, processedResultQtyTuple);
-                        };
-                        Navigation.PushAsync(page);
-                    }
-                    else if (list.Count == 0)
-                    {
+                    else if (list.Count == 0)                   
                         DisplayAlert("No Holdings Found for Product", "", "OK");
-                        loading = false;
-                        return;
-                    }
+                    
                     loading = false;
                 }
                 catch (Exception e)
@@ -331,7 +312,116 @@ namespace comal.timesheets
             });
         }
 
-        private void AddShell(HoldingsCacheShell holding, ProductShell product, string rawResult, Tuple<string, double> processedResultQtyTuple)
+        private void UserSelectFromList(List<StoreRequiIHoldingShell> list, ProductShell product, string rawResult, Tuple<string, double> processedResultQtyTuple)
+        {
+            Dictionary<string, Guid> holdingLocationIDs = new Dictionary<string, Guid>();
+            foreach (StoreRequiIHoldingShell holding in list)
+            {
+                if (!holdingLocationIDs.ContainsKey(holding.LocationName))
+                    holdingLocationIDs.Add(holding.LocationName, holding.LocationID);
+            }
+            List<string> options = holdingLocationIDs.Keys.ToList();
+            ListSelectionPage page = new ListSelectionPage(options);
+            page.OnSimpleListTapped += (locationName) =>
+            {
+                AddStoreRequiItemShell(list.Find(x => x.LocationName == locationName), product, rawResult, processedResultQtyTuple);
+            };
+            Navigation.PushAsync(page);
+        }
+
+        private List<StoreRequiIHoldingShell> CreateHoldingsList(Guid productID)
+        {
+            List<StoreRequiIHoldingShell> list = new List<StoreRequiIHoldingShell>();
+
+            CoreTable table = DoHoldingsQuery(productID);
+
+            foreach (CoreRow row in table.Rows)
+            {
+                if (row.Get<StockHolding, double>(x => x.Units) == 0.0)
+                    continue;
+                
+                list.Add(CreateHoldingShell(row));
+            }
+            return list;
+        }
+
+        private CoreTable DoHoldingsQuery(Guid productID)
+        { 
+            return new Client<StockHolding>().Query(
+                new Filter<StockHolding>(x => x.Product.ID).IsEqualTo(productID),
+                new Columns<StockHolding>(
+                    x => x.ID,
+                    x => x.Product.ID,
+                    x => x.Location.ID,
+                    x => x.Location.Description,
+                    x => x.Units,
+                    x => x.Job.ID,
+                    x => x.Job.JobNumber,
+                    x => x.Job.Name,
+                    x => x.Style.ID,
+                    x => x.Style.Code,
+                    x => x.Style.Description,
+                    x => x.Dimensions.Unit.ID,
+                    x => x.Dimensions.Unit.HasQuantity,
+                    x => x.Dimensions.Unit.HasLength,
+                    x => x.Dimensions.Unit.HasHeight,
+                    x => x.Dimensions.Unit.HasWeight,
+                    x => x.Dimensions.Unit.HasWidth,
+                    x => x.Dimensions.Quantity,
+                    x => x.Dimensions.Length,
+                    x => x.Dimensions.Height,
+                    x => x.Dimensions.Weight,
+                    x => x.Dimensions.Width,
+                    x => x.Dimensions.Unit.Format,
+                    x => x.Dimensions.Unit.Formula,
+                    x => x.Dimensions.UnitSize
+                    )
+                );
+        }
+
+        private StoreRequiIHoldingShell CreateHoldingShell(CoreRow row)
+        {
+            StoreRequiIHoldingShell holding = new StoreRequiIHoldingShell()
+            {
+                ProductID = row.Get<StockHolding, Guid>(x => x.Product.ID),
+                LocationID = row.Get<StockHolding, Guid>(x => x.Location.ID),
+                LocationName = row.Get<StockHolding, string>(x => x.Location.Description),
+                Units = row.Get<StockHolding, double>(x => x.Units).ToString(),
+                JobID = row.Get<StockHolding, Guid>(x => x.Job.ID),
+                JobNumber = row.Get<StockHolding, string>(x => x.Job.JobNumber),
+                JobName = row.Get<StockHolding, string>(x => x.Job.Name),
+                StyleID = row.Get<StockHolding, Guid>(x => x.Style.ID),
+                StyleCode = row.Get<StockHolding, string>(x => x.Style.Code),
+                StyleDescription = row.Get<StockHolding, string>(x => x.Style.Description)
+            };
+
+            holding.Dimensions.Unit.ID = row.Get<StockHolding, Guid>(x => x.Dimensions.Unit.ID);
+            holding.Dimensions.Unit.HasQuantity = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasQuantity);
+            holding.Dimensions.Unit.HasLength = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasLength);
+            holding.Dimensions.Unit.HasHeight = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasHeight);
+            holding.Dimensions.Unit.HasWeight = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasWeight);
+            holding.Dimensions.Unit.HasWidth = row.Get<StockHolding, bool>(x => x.Dimensions.Unit.HasWidth);
+
+            holding.Dimensions.Quantity = row.Get<StockHolding, double>(x => x.Dimensions.Quantity);
+            holding.Dimensions.Length = row.Get<StockHolding, double>(x => x.Dimensions.Length);
+            holding.Dimensions.Height = row.Get<StockHolding, double>(x => x.Dimensions.Height);
+            holding.Dimensions.Weight = row.Get<StockHolding, double>(x => x.Dimensions.Weight);
+            holding.Dimensions.Width = row.Get<StockHolding, double>(x => x.Dimensions.Width);
+
+            holding.Dimensions.Unit.Format = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Format);
+            holding.Dimensions.Unit.Formula = row.Get<StockHolding, string>(x => x.Dimensions.Unit.Formula);
+
+            holding.Dimensions.UnitSize = row.Get<StockHolding, string>(x => x.Dimensions.UnitSize);
+
+            holding.LocationName = holding.LocationName + " (Units: " + holding.Units + ")" +
+                   Environment.NewLine + "Style: " + holding.StyleDescription
+                   + Environment.NewLine + "Job: " + holding.JobNumber
+                   + Environment.NewLine + "Size: " + holding.Dimensions.UnitSize;
+
+            return holding;
+        }
+
+        private void AddStoreRequiItemShell(StoreRequiIHoldingShell holding, ProductShell product, string rawResult, Tuple<string, double> processedResultQtyTuple)
         {
             StoreRequiItemShell shell = new StoreRequiItemShell
             {

+ 0 - 43
prs.mobile/comal.timesheets/StoreRequis/StoreRequisMainPage.xaml

@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
-             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms" xmlns:customcontrols="clr-namespace:comal.timesheets.CustomControls"
-             x:Class="comal.timesheets.StoreRequis.StoreRequisMainPage"
-             Title="Store Requis">
-    <ContentPage.ToolbarItems>
-        <ToolbarItem Text="Add" Clicked="Add_Clicked"/>
-        <ToolbarItem Text="   "/>
-        <ToolbarItem Text="Next" Clicked="NextBtn_Clicked"/>
-    </ContentPage.ToolbarItems>
-    <ContentPage.Content>
-
-        <Grid>
-            <Grid.RowDefinitions>
-                <RowDefinition Height="auto"/>
-                <RowDefinition Height="auto"/>
-                <RowDefinition Height="auto"/>
-            </Grid.RowDefinitions>
-            <zxing:ZXingScannerView x:Name="_scanView" Grid.Row="0" VerticalOptions="FillAndExpand" HeightRequest="100"/>
-            <zxing:ZXingDefaultOverlay x:Name="scannerOverlay" Grid.Row="0" BottomText="Scan Barcode" VerticalOptions="FillAndExpand" HeightRequest="100"/>
-
-            <Frame x:Name="requestFrame" IsVisible="false" Grid.Row="1" HasShadow="False"
-                       Padding="7" Margin="5,2,5,2" BorderColor="PaleVioletRed" CornerRadius="10">
-            </Frame>
-
-            <ScrollView x:Name="itemsScroller" VerticalOptions="FillAndExpand" Grid.Row="2">
-                <Grid>
-                    <Grid.RowDefinitions>
-                        <RowDefinition Height="auto"/>
-                        <RowDefinition Height="auto"/>
-                    </Grid.RowDefinitions>
-                    <StackLayout x:Name="itemRowsFlexlayout" Grid.Row="0"/>
-                    <Label Grid.Row="1" HeightRequest="1000"/>
-                </Grid>
-
-            </ScrollView>
-
-            
-
-        </Grid>
-
-    </ContentPage.Content>
-</ContentPage>

+ 0 - 346
prs.mobile/comal.timesheets/StoreRequis/StoreRequisMainPage.xaml.cs

@@ -1,346 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Xamarin.Essentials;
-using Xamarin.Forms;
-using ZXing;
-using ZXing;
-using Xamarin.Forms;
-using Xamarin.Forms.Xaml;
-using comal.timesheets.CustomControls;
-using Comal.Classes;
-using InABox.Core;
-using InABox.Clients;
-using System.Threading;
-using static comal.timesheets.RequiItems;
-
-namespace comal.timesheets.StoreRequis
-{
-    [XamlCompilation(XamlCompilationOptions.Compile)]
-    public partial class StoreRequisMainPage : ContentPage
-    {
-
-        public delegate bool OnScanEvent(object sender, String barcode);
-
-        public event OnScanEvent OnScan;
-
-        Dictionary<StoreRequiItem, string> itemRowScannerRawResultPairs;
-
-        Dictionary<StoreRequiItem, string> itemRowScannerProcessedResultPairs;
-
-        Dictionary<int, StoreRequiItem> idItemRowPairs;
-
-        bool choosingLocation;
-
-        Requisition requisition;
-
-        bool newRequisition;
-
-        int count;
-
-        int itemsCount;
-
-        #region Constructor, appearing and disappearing
-
-        public StoreRequisMainPage(Guid _requiID)
-        {
-            InitializeComponent();
-            var options = new ZXing.Mobile.MobileBarcodeScanningOptions()
-            {
-                PossibleFormats = new List<ZXing.BarcodeFormat>() { ZXing.BarcodeFormat.QR_CODE },
-                AutoRotate = false,
-                TryInverted = true,
-                TryHarder = true,
-            };
-            _scanView.Options = options;
-            _scanView.IsAnalyzing = false;
-            _scanView.IsScanning = true;
-            _scanView.OnScanResult += ScanView_OnScanResult;
-            count = 0;
-            choosingLocation = false;
-            itemRowScannerRawResultPairs = new Dictionary<StoreRequiItem, string>();
-            itemRowScannerProcessedResultPairs = new Dictionary<StoreRequiItem, string>();
-            idItemRowPairs = new Dictionary<int, StoreRequiItem>();
-
-            RequiItems.NewRequisitionRows = new List<StoreRequiItem>();
-            RequiItems.OldRequisitionItems = new List<RequisitionItem>();
-
-            if (_requiID != Guid.Empty)
-            {
-                Title = "Loading";
-                requisition = new Requisition();
-                requisition.ID = _requiID;
-                LoadExistingRequi();
-            }
-            else
-            {
-                Title = "Scan Items";
-                newRequisition = true;
-                requisition = new Requisition();
-            }
-        }
-        private async void LoadExistingRequi()
-        {
-            await Task.Run(() =>
-            {
-                requisition = new Client<Requisition>().Query(
-                    new Filter<Requisition>(x => x.ID).IsEqualTo(requisition.ID)
-                    ).Rows.FirstOrDefault().ToObject<Requisition>();
-                if (!string.IsNullOrWhiteSpace(requisition.Request))
-                {
-                    Label notesLbl = new Label()
-                    {
-                        Text = requisition.Request,
-                        Margin = 0,
-                        Padding = 0
-                    };
-                    
-                    
-                    Device.BeginInvokeOnMainThread(() =>
-                    {
-                        requestFrame.Content = notesLbl;
-                        requestFrame.IsVisible = true;
-                    });
-                }
-
-                if (RequiItems.OldRequisitionItems.Count > 0)
-                    RequiItems.OldRequisitionItems.Clear();
-                CoreTable table = new Client<RequisitionItem>().Query
-                    (
-                    new Filter<RequisitionItem>(x => x.RequisitionLink.ID).IsEqualTo(requisition.ID)
-                    );
-                if (table.Rows.Any())
-                {
-                    foreach (CoreRow row in table.Rows)
-                    {
-                        RequisitionItem requisitionItem = row.ToObject<RequisitionItem>();
-                        LoadProduct(new Tuple<string, double>(requisitionItem.Product.Code, requisitionItem.Quantity), requisitionItem.Product.Code, requisitionItem);
-                        RequiItems.OldRequisitionItems.Add(requisitionItem);
-                    }
-                }
-                Device.BeginInvokeOnMainThread(() =>
-                {
-                    Title = "Scan Items";
-                });
-
-            });
-        }
-
-        protected override void OnAppearing()
-        {
-            base.OnAppearing();
-            _scanView.IsAnalyzing = true;
-        }
-
-        protected override void OnDisappearing()
-        {
-            _scanView.IsAnalyzing = false;
-            base.OnDisappearing();
-        }
-
-        #endregion
-
-        #region Scan Complete and process results
-        private void ScanView_OnScanResult(ZXing.Result result)
-        {
-            Device.BeginInvokeOnMainThread(() =>
-            {
-                if (!choosingLocation)
-                {
-                    if (RequiItems.HoldingsLoaded)
-                    {
-                        bool bOK = true;
-                        if (OnScan != null)
-                            bOK = OnScan(this, result.Text);
-                        if (bOK)
-                        {
-                            if (!itemRowScannerRawResultPairs.Values.Contains(result.Text))
-                            {
-                                if (!itemRowScannerProcessedResultPairs.Values.Contains(result.Text))
-                                {
-                                    Vibration.Vibrate();
-                                    string rawResult = result.Text;
-                                    Tuple<string, double> tuple = ProcessResult(result.Text);
-                                    LoadProduct(tuple, rawResult, new RequisitionItem());
-                                }
-                            }
-                        }
-                    }
-                }
-            });
-        }
-
-        private Tuple<string, double> ProcessResult(string result)
-        {
-            double qty = 1;
-            if (result.Contains("*"))
-            {
-                try
-                {
-                    int i = result.IndexOf("*");
-                    string remainder = result.Substring(i);
-                    result = result.Remove(i);                    
-                    string s1 = remainder.Substring(1);
-                    qty = Convert.ToDouble(s1);
-                }
-                catch { }
-            }
-            Tuple<string, double> tuple = new Tuple<string, double>(result, qty);
-            return tuple;
-        }
-
-        private void LoadProduct(Tuple<string, double> processedResultQtyTuple, string rawResult, RequisitionItem requisitionItem)
-        {
-            Device.BeginInvokeOnMainThread(async () =>
-            {
-                //lookup product in productshells cache
-                ProductShell product = GlobalVariables.ProductShells.Find(x => x.Code.Equals(processedResultQtyTuple.Item1));
-
-                //lookup holding for product in holdings cache
-                //List<HoldingsCacheShell> list = new List<HoldingsCacheShell>();
-                string itemLocation = "";
-                Guid holdingID = Guid.Empty;
-
-                if (requisitionItem.ID == Guid.Empty)
-                {
-                    try
-                    {
-                        List<HoldingsCacheShell> list = holdingsCache.Where(x => x.ProductID.Equals(product.ID)).ToList();
-                        if (list.Count == 1) //one stockholding - auto choose shelf
-                        {
-                            HoldingsCacheShell holding = list.First();
-                            itemLocation = holding.LocationName;
-                            holdingID = holding.LocationID;
-                        }
-                        else if (list.Count > 1)  //more than one stockholding - choose shelf
-                        {
-                            choosingLocation = true;
-                            Dictionary<string, Guid> holdingIDLocations = new Dictionary<string, Guid>();
-                            foreach (HoldingsCacheShell holding in list)
-                            {
-                                if (!holdingIDLocations.ContainsKey(holding.LocationName + " (Qty: " + holding.Units + ")"))
-                                {
-                                    holdingIDLocations.Add(holding.LocationName + " (Qty: " + holding.Units + ")", holding.LocationID);
-                                }
-                            }
-                            string[] array = holdingIDLocations.Keys.ToArray();
-                            string chosenOption = await DisplayActionSheet("Choose Location", "Cancel", null, array);
-                            if (chosenOption != null && chosenOption != "Cancel")
-                            {
-                                itemLocation = chosenOption;
-                                holdingID = holdingIDLocations[chosenOption];
-                            }
-                            else
-                                return;
-                        }
-                        else if (list.Count == 0)
-                        {
-                            DisplayAlert("No Holdings Found for Product", "", "OK");
-                            return;
-                        }
-                    }
-                    catch(Exception e)
-                    {
-                        DisplayAlert("Error", e.Message, "OK");
-                        return;
-                    }
-                }
-                else
-                {
-                    itemLocation = requisitionItem.Location.Description;
-                    holdingID = requisitionItem.Location.ID;
-                }
-
-                StoreRequiItem storeRequiItem = new StoreRequiItem(product, processedResultQtyTuple.Item2, itemLocation, holdingID) //default qty is 1
-                {
-                    ID = count,
-                };
-                storeRequiItem.RequiItemID = requisitionItem.ID;
-                storeRequiItem.OnZeroSelected += StoreRequiItem_OnZeroSelected;
-                storeRequiItem.OnParseError += OnParseError;
-
-                idItemRowPairs.Add(count, storeRequiItem);
-                itemRowScannerRawResultPairs.Add(storeRequiItem, rawResult);
-                itemRowScannerProcessedResultPairs.Add(storeRequiItem, processedResultQtyTuple.Item1);
-                itemRowsFlexlayout.Children.Add(storeRequiItem);
-                count++;
-                itemsCount++;
-                Title = "Store Requis (" + itemsCount + ")";
-                choosingLocation = false;
-                itemsScroller.ScrollToAsync(storeRequiItem, ScrollToPosition.Center, true);
-            });
-        }
-        #endregion
-
-        #region Buttons Pressed
-        private void Add_Clicked(object sender, EventArgs e)
-        {
-            if (GlobalVariables.ProductsLoaded)
-            {
-                ProductList products = new ProductList(GlobalVariables.ProductShells, true);
-                products.OnProductSelected += ()=> 
-                {
-                    Tuple<string, double> tuple = new Tuple<string, double>(products.SelectedProduct.Code, 1);
-
-                    LoadProduct(new Tuple<string, double>(products.SelectedProduct.Code, 1), products.SelectedProduct.Code, new RequisitionItem());
-                };
-                Navigation.PushAsync(products);
-            }
-        }
-
-        private void NextBtn_Clicked(object sender, EventArgs e)
-        {
-            if (RequiItems.NewRequisitionRows.Count > 0)
-                RequiItems.NewRequisitionRows.Clear();
-
-            if (idItemRowPairs.Count > 0)
-            {
-                //RequiItems.NewRequisitionRows = idItemRowPairs.Values.ToList();
-                //StoreRequiConfirmationPage storeRequiConfirmationPage = new StoreRequiConfirmationPage(requisition);
-                //storeRequiConfirmationPage.OnSaveSelected += () => { Navigation.PopAsync(); };
-                //Navigation.PushAsync(storeRequiConfirmationPage);
-            }
-            else
-            {
-                DisplayAlert("Alert", "Please add items", "Cancel");
-            }
-        }
-        private async void StoreRequiItem_OnZeroSelected(int ID)
-        {
-            string chosenOption = await DisplayActionSheet("Remove Item?", "Cancel", null, "Yes", "No");
-            switch (chosenOption)
-            {
-                case "Cancel":
-                    return;
-                    break;
-                case "No":
-                    return;
-                    break;
-                case "Yes":
-                    break;
-                default:
-                    return;
-                    break;
-            }
-            StoreRequiItem storeRequiItem = idItemRowPairs[ID];
-            itemRowsFlexlayout.Children.Remove(storeRequiItem);
-            idItemRowPairs.Remove(ID);
-            itemRowScannerRawResultPairs.Remove(storeRequiItem);
-            itemRowScannerProcessedResultPairs.Remove(storeRequiItem);
-            itemsCount--;
-            Title = "Store Requis (" + itemsCount + ")";
-        }
-
-        private async void OnParseError()
-        {
-            DisplayAlert("Error", "Enter only numbers", "OK");
-        }
-
-        #endregion
-
-
-
-    }
-}

+ 2 - 12
prs.mobile/comal.timesheets/comal.timesheets.projitems

@@ -225,7 +225,7 @@
       <DependentUpon>PurchaseOrderModule.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="$(MSBuildThisFileDirectory)SiteManufacturing.xaml.cs">
+    <Compile Include="$(MSBuildThisFileDirectory)Site\SiteManufacturing.xaml.cs">
       <DependentUpon>SiteManufacturing.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
@@ -461,10 +461,6 @@
       <DependentUpon>StoreRequiList.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="$(MSBuildThisFileDirectory)StoreRequis\StoreRequisMainPage.xaml.cs">
-      <DependentUpon>StoreRequisMainPage.xaml</DependentUpon>
-      <SubType>Code</SubType>
-    </Compile>
     <Compile Include="$(MSBuildThisFileDirectory)Tasks\TasksList.xaml.cs">
       <DependentUpon>TasksList.xaml</DependentUpon>
       <SubType>Code</SubType>
@@ -647,12 +643,6 @@
       <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
     </EmbeddedResource>
   </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="$(MSBuildThisFileDirectory)StoreRequis\StoreRequisMainPage.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
-    </EmbeddedResource>
-  </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="$(MSBuildThisFileDirectory)Data Classes\StoreRequiItem.xaml">
       <SubType>Designer</SubType>
@@ -990,7 +980,7 @@
     </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
-    <EmbeddedResource Include="$(MSBuildThisFileDirectory)SiteManufacturing.xaml">
+    <EmbeddedResource Include="$(MSBuildThisFileDirectory)Site\SiteManufacturing.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
     </EmbeddedResource>