using System; using System.Collections.Generic; using System.ComponentModel.Design; using System.Linq; using System.Text; using System.Threading.Tasks; using Comal.Classes; using InABox.Core; using InABox.Mobile; using Xamarin.Essentials; using Xamarin.Forms; using Xamarin.Forms.Xaml; using ZXing; namespace PRS.Mobile { public class RequisitionItemScannerHoldingMatchConverter : AbstractConverter { public RequisitionItemScannerViewModel ViewModel { get; set; } protected override Color Convert(StockHoldingShell? value, object? parameter = null) { bool bMatched = false; if (value != null) { if (ViewModel.SaveArgs != null) bMatched = value.ID == ViewModel.SaveArgs.Holding.ID; else if (ViewModel.Item != null) { bMatched = value.LocationID == ViewModel.Item.LocationID && value.ProductID == ViewModel.Item.ProductID && value.StyleID == ViewModel.Item.StyleID && value.DimensionsUnitID == ViewModel.Item.DimensionsUnitID && value.DimensionsUnitSize == ViewModel.Item.DimensionsUnitSize; } } return bMatched ? Color.LightGreen : Color.LightYellow; } } public class RequisitionItemScannerViewModel : BindableObject { private RequisitionItemShell? _item; private RequisitionItemScannerSaveArgs? _saveArgs; public RequisitionItemShell? Item { get => _item; set { if (Equals(value, _item)) return; _item = value; OnPropertyChanged(); OnPropertyChanged(nameof(HasItem)); } } public bool HasItem => Item != null; public RequisitionItemScannerSaveArgs? SaveArgs { get => _saveArgs; set { if (Equals(value, _saveArgs)) return; _saveArgs = value; OnPropertyChanged(); OnPropertyChanged(nameof(HasSaveArgs)); } } public bool HasSaveArgs => SaveArgs != null; public StockHoldingModel Holdings { get; private set; } public String FoundItem { get; set; } public RequisitionItemScannerViewModel() { Holdings = new StockHoldingModel(App.Data, () => new Filter().None()); } } public class RequisitionItemScannerSaveArgs : EventArgs { public StockHoldingShell Holding { get; private set; } public Guid JobID { get; private set; } public Guid JobRequisitionItemID { get; private set; } public double Quantity { get; set; } public RequisitionItemScannerSaveArgs(StockHoldingShell holding, Guid jobid, Guid jobrequisitionitemid, double quantity) { Holding = holding; JobID = jobid; JobRequisitionItemID = jobrequisitionitemid; Quantity = quantity; } } public delegate void RequisitionItemScannerSaveEvent(object sender, RequisitionItemScannerSaveArgs args); [XamlCompilation(XamlCompilationOptions.Compile)] public partial class RequisitionItemScanner : MobilePage { public event RequisitionItemScannerSaveEvent? OnSave; public RequisitionItemScanner(RequisitionItemShell? item) { InitializeComponent(); HoldingMatchConverter.ViewModel = _viewModel; _viewModel.Item = item; var options = new ZXing.Mobile.MobileBarcodeScanningOptions() { PossibleFormats = new List() { ZXing.BarcodeFormat.QR_CODE }, AutoRotate = false, TryInverted = true, TryHarder = true, }; _scanView.Options = options; _scanView.IsAnalyzing = false; _scanView.IsScanning = true; if ((item?.ProductID ?? Guid.Empty) != Guid.Empty) SearchProductID(item!.ProductID); } protected override void OnAppearing() { base.OnAppearing(); _scanView.IsAnalyzing = true; } protected override void OnDisappearing() { _scanView.IsAnalyzing = false; base.OnDisappearing(); } private bool bProcessing = false; private void ScanView_OnScanResult(ZXing.Result result) { if (bProcessing) return; if (!Guid.TryParse(result.Text, out Guid id) || id == Guid.Empty) { _viewModel.Holdings.Filter = () => new Filter().None(); _viewModel.Holdings.Refresh(true); return; } bProcessing = true; Vibration.Vibrate(); var producttask = Task.Run(() => { SearchProductID(id); }); var locationtask = Task.Run(() => { SearchLocationID(id); }); Task.WaitAll(producttask,locationtask); bProcessing = false; } private void SearchLocationID(Guid id) { App.Data.StockLocations.Refresh(false); var location = App.Data.StockLocations.FirstOrDefault(x => Guid.Equals(x.ID,id)); if (location != null) { _viewModel.Holdings.Filter = () => new Filter(x => x.Location.ID).IsEqualTo(location.ID); _viewModel.Holdings.Refresh(true, () => Dispatcher.BeginInvokeOnMainThread(() => { _items.ItemTemplate = _locationTemplate; _viewModel.FoundItem = location.Description; }) ); } } private void SearchProductID(Guid id) { App.Data.Products.Refresh(false); var product = App.Data.Products.FirstOrDefault(x => Guid.Equals(x.ID,id)); if (product != null) { _viewModel.Holdings.Filter = () => new Filter(x => x.Product.ID).IsEqualTo(product.ID); _viewModel.Holdings.Refresh(true, () => Dispatcher.BeginInvokeOnMainThread(() => { _items.ItemTemplate = _productTemplate; _viewModel.FoundItem = product.Name; }) ); } } private void ProductSearch_Clicked(object sender, MobileButtonClickEventArgs args) { ShowPopup(() => SelectionView.Execute( columns => { columns.Add(new MobileGridTextColumn() { Column = x => x.Code, Width = 100 }); columns.Add(new MobileGridTextColumn() { Column = x => x.Name, Width = GridLength.Star }); }, refresh => App.Data.Products.Refresh(false), products => { SearchProductID(products.FirstOrDefault()?.ID ?? Guid.Empty); DismissPopup(); }) ); } private void LocationSearch_Clicked(object sender, MobileButtonClickEventArgs args) { ShowPopup(() => SelectionView.Execute( columns => { columns.Add(new MobileGridTextColumn() { Column = x => x.Code, Width = 100 }); columns.Add(new MobileGridTextColumn() { Column = x => x.Description, Width = GridLength.Star }); }, refresh => App.Data.StockLocations.Refresh(false), locations => { SearchLocationID(locations.FirstOrDefault()?.ID ?? Guid.Empty); DismissPopup(); }) ); } private void SelectFromHolding_Click(object sender, EventArgs e) { var holding = (sender as MobileCard)?.BindingContext as StockHoldingShell; if (holding == null) return; ShowPopup(() => { var editor = new SelectFromHoldingView(holding, _viewModel.Item?.Quantity ?? 0.0F); editor.OnSave += (o, args) => { if (!_viewModel.HasItem) OnSave?.Invoke(this, args); else _viewModel.SaveArgs = args; _viewModel.Holdings.Refresh(false); DismissPopup(); }; editor.OnCancel += (o, args) => DismissPopup(); return editor; }, new PopupManagerConfiguration() { RequestedHeight = Math.Min(700,500 + (holding.Allocations.Length * 55)) }); } private void SaveItem_Clicked(object sender, MobileMenuButtonClickedEventArgs args) { if (_viewModel.HasSaveArgs) { OnSave?.Invoke(this, _viewModel.SaveArgs); Navigation.PopAsync(); } } } }