|
@@ -0,0 +1,346 @@
|
|
|
+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.ID;
|
|
|
+ }
|
|
|
+ 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.ID);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ 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
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|