123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Core;
- using InABox.DynamicGrid;
- using InABox.WPF;
- using Motorola.Snapi;
- using Motorola.Snapi.Constants.Enums;
- using Motorola.Snapi.EventArguments;
- namespace PRSDesktop
- {
- /// Notes for Motorola Barcode Scanners
- /// 1) Install Scanner Driver (CoreScanner)
- /// 2) Ensure Scanner is set to SNAPI-NoImaging
- /// <summary>
- /// Interaction logic for ShippingPanel.xaml
- /// </summary>
- public partial class DispatchPanel : UserControl, IPanel<Shipment>
- {
- private bool _updatingItems;
- private readonly Dictionary<CodeStatus, BeepPattern> BeepList = new()
- {
- { CodeStatus.Initialized, BeepPattern.FastWarble },
- { CodeStatus.Opened, BeepPattern.ThreeHighShort },
- { CodeStatus.Closed, BeepPattern.ThreeLowShort },
- { CodeStatus.Added, BeepPattern.LowHigh },
- { CodeStatus.Removed, BeepPattern.HighLow },
- { CodeStatus.NotFound, BeepPattern.FourLowLong },
- { CodeStatus.Error, BeepPattern.FourLowShort }
- };
- private bool? Item;
- private CoreTable ItemCache;
- private DateTime Last = DateTime.MinValue;
- private bool? Product;
- private CoreTable ProductCache;
- private bool? Requi;
- public List<IMotorolaBarcodeScanner> Scanners = new();
- private bool? Shipment;
- //Shipment[] ShipmentList = new Shipment[] { };
- //private Shipment CurrentShipment = null;
- //private DispatcherTimer timer = new DispatcherTimer();
- //private DateTime lastselection = DateTime.MaxValue;
- //private DispatcherTimer processing = new DispatcherTimer();
- public DispatchPanel()
- {
- InitializeComponent();
- Shipments.OnSelectItem += Shipments_OnSelectItem;
- //timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
- //timer.Tick += Timer_Tick;
- //timer.IsEnabled = true;
- //processing.Interval = new TimeSpan(0, 0, 1);
- //processing.Tick += (o, e) => WaitBeep();
- }
- public bool IsReady { get; set; }
- public Dictionary<string, object[]> Selected()
- {
- return new Dictionary<string, object[]>
- {
- { typeof(Shipment).EntityName(), Shipments.SelectedRows },
- { typeof(DeliveryItem).EntityName(), Items.SelectedRows }
- };
- }
- public void Setup()
- {
- SetupScanner();
- UpdateLayout();
- Shipments.Refresh(true, false);
- Shipments.SelectedRows = new CoreRow[] { }; //CurrentRow = -1;
- Items.CurrentShipmentID = Guid.Empty;
- Items.Refresh(true, false);
- RefreshCache();
- }
- public void Shutdown()
- {
- foreach (var scanner in Scanners)
- scanner.Actions.ToggleLed(LedMode.GreenOff);
- BarcodeScannerManager.Instance.DataReceived -= Instance_DataReceived;
- BarcodeScannerManager.Instance.Close();
- }
- public event DataModelUpdateEvent OnUpdateDataModel;
- public void CreateToolbarButtons(IPanelHost host)
- {
- //host.CreatePanelAction(new PanelAction() { Caption = "Mark As Delivered", OnExecute = MarkAsDelivered, Image = PRSDesktop.Resources.barcode });
- }
- //private void MarkAsDelivered(PanelAction obj)
- //{
- // Shipment shipment = new Client<Shipment>().Load(new Filter<Shipment>(x => x.ID).IsEqualTo(Items.CurrentShipmentID)).FirstOrDefault();
- // if (shipment == null)
- // {
- // MessageBox.Show("Please select a shipment!");
- // return;
- // }
- // var rc = MessageBox.Show("This will mark all the items on this rack as delivered.\n\nDo you also want to empty the rack of all items?", "Confirmation", MessageBoxButton.YesNoCancel);
- // if (rc != MessageBoxResult.Cancel)
- // {
- // DeliveryNotification notification = new DeliveryNotification();
- // notification.ShipmentLink.ID = shipment.ID;
- // notification.Location.Latitude = shipment.TrackerLink.Location.Latitude;
- // notification.Location.Longitude = shipment.TrackerLink.Location.Longitude;
- // notification.Location.Timestamp = shipment.TrackerLink.Location.Timestamp;
- // if (rc == MessageBoxResult.No)
- // {
- // foreach (CoreRow row in Items.Data.Rows)
- // notification.RetainedItems.Add(row.Get<DeliveryItem, Guid>(x => x.ID));
- // }
- // using (new WaitCursor())
- // {
- // new Client<DeliveryNotification>().Save(notification, "Manual Delivery Notification");
- // Refresh();
- // }
- // MessageBox.Show("Rack Updated");
- // }
- //}
- public void Refresh()
- {
- Shipments.Refresh(false, true);
- }
- public string SectionName => "Shipping";
- public DataModel DataModel(Selection selection)
- {
- var ids = Shipments.ExtractValues(x => x.ID, selection).ToArray();
- return new ShipmentDataModel(new Filter<Shipment>(x => x.ID).InList(ids));
- }
- public void Heartbeat(TimeSpan time)
- {
- }
- private void RefreshCache()
- {
- ClientFactory.MultiQuery(
- new IQueryDef[]
- {
- new QueryDef<Product>(
- null,
- new Columns<Product>(
- x => x.ID,
- x => x.Code,
- x => x.Name
- ),
- null
- ),
- new QueryDef<DeliveryItem>(
- new Filter<DeliveryItem>(x => x.DeliveredDate).IsEqualTo(DateTime.MinValue)
- .And(x => x.ManufacturingPacketLink).LinkValid(),
- Items.DataColumns(),
- null
- )
- },
- results =>
- {
- Dispatcher.Invoke(() =>
- {
- ProductCache = results[0];
- ItemCache = results[1];
- });
- }
- );
- }
- private void SetupScanner()
- {
- // From Motorola Documentation
- // May not be complete?
- var scannermodes = new Dictionary<string, string>
- {
- { "XUA-45001-1", "IBM HID" },
- { "XUA-45001-2", "IBM TABLETOP HID" },
- { "XUA-45001-3", "HID KEYBOARD" },
- { "XUA-45001-8", "OPOS" },
- { "XUA-45001-9", "SNAPI w/o Imaging" },
- { "XUA-45001-10", "SNAPI with Imaging" },
- { "XUA-45001-11", "CDC Serial Emulation" }
- };
- Scanners.Clear();
- BarcodeScannerManager.Instance.Open();
- BarcodeScannerManager.Instance.RegisterForEvents(EventType.Barcode, EventType.Pnp, EventType.Image, EventType.Other, EventType.Rmd);
- BarcodeScannerManager.Instance.GetDevices();
- foreach (var scanner in BarcodeScannerManager.Instance.GetDevices())
- {
- var mode = scanner.Info.UsbHostMode;
- if (string.Equals(mode, "XUA-45001-9"))
- {
- try
- {
- scanner.Actions.ToggleLed(LedMode.RedOn);
- Scanners.Add(scanner);
- }
- catch (Exception e)
- {
- Logger.Send(LogType.Error, "",
- string.Format("Exception initialising scanner #{0}: {1}\n{2}", scanner.Info.ScannerId, e.Message, e.StackTrace));
- }
- }
- else
- {
- var value = scannermodes.ContainsKey(mode) ? scannermodes[mode] : string.Format("Unknown ({0})", mode);
- MessageBox.Show(string.Format(
- "Scanner #{0} is set to [{1}]!\n\nPlease set it to [SNAPI w/o Imaging] by scanning the appropriate setup barcode.",
- scanner.Info.SerialNumber, value));
- }
- }
- if (Scanners.Any())
- {
- Beep(CodeStatus.Initialized);
- BarcodeScannerManager.Instance.DataReceived += Instance_DataReceived;
- }
- else
- {
- MessageBox.Show(
- "Cannot find any valid scanners!\n\nPlease make sure that the scanner is turned on, connected to the PC, and set to SNAPI (w/o Imaging).");
- }
- }
- private void Beep(CodeStatus status)
- {
- foreach (var scanner in Scanners)
- {
- if (status == CodeStatus.Opened)
- scanner.Actions.ToggleLed(LedMode.GreenOn);
- else if (status == CodeStatus.Closed)
- scanner.Actions.ToggleLed(LedMode.RedOn);
- scanner.Actions.SoundBeeper(BeepList[status]);
- }
- }
- private void WaitBeep()
- {
- foreach (var scanner in Scanners)
- {
- scanner.Actions.ToggleLed(LedMode.YellowOn);
- scanner.Actions.SoundBeeper(BeepPattern.OneHighShort);
- }
- }
- private void Instance_DataReceived(object sender, BarcodeScanEventArgs e)
- {
- var scanner = Scanners.FirstOrDefault(x => x.Info.ScannerId == (int)e.ScannerId);
- if (scanner != null)
- Dispatcher.Invoke(() => { CheckCode(scanner, e.Data); });
- }
- //WaitCursor waiting = null;
- //private void StartWaiting()
- //{
- // if (waiting == null)
- // waiting = new WaitCursor();
- //}
- //private void StopWaiting()
- //{
- // if (waiting != null)
- // waiting.Dispose();
- // waiting = null;
- //}
- private void CheckCode(IMotorolaBarcodeScanner scanner, string code)
- {
- using (new WaitCursor())
- {
- Product = null;
- Item = null;
- Shipment = null;
- Requi = null;
- var row = CheckShipmentLocalCache(code);
- if (row == null)
- row = CheckShipmentOnServer(code);
-
- if (row != null)
- {
- Shipments.ScrollIntoView(row);
- Shipments.SelectedRows = new[] { row };
- Beep(CodeStatus.Opened);
- LoadShipment();
- //lastselection = DateTime.Now;
- return;
- }
- if (Shipments.SelectedRows.Any())
- {
- var item = CheckItem(code);
- if (item != null)
- {
- var icount = Shipments.SelectedRows.First().Get<Shipment, int>(x => x.ItemCount);
- var itemrow = Items.Data.Rows.Where(r => r.Get<DeliveryItem, string>(c => c.Barcode) == item.Barcode).FirstOrDefault();
- if (itemrow != null)
- {
- item.ShipmentCode = "";
- item.ShipmentLink.ID = Guid.Empty;
- item.Delivery.ID = Guid.Empty;
- Items.DeleteRow(itemrow);
- icount--;
- }
- else
- {
- item.ShipmentLink.ID = Items.CurrentShipmentID;
- item.Delivery.ID = Shipments.SelectedRows.First().Get<Shipment, Guid>(x => x.Delivery.ID);
- item.ShipmentCode = Shipments.SelectedRows.First().Get<Shipment, string>(x => x.Code);
- Items.AddRow(item);
- icount++;
- }
- _updatingItems = true;
- Shipments.UpdateRow<Shipment, int>(Shipments.SelectedRows.First(), x => x.ItemCount, icount);
- _updatingItems = false;
- new Client<DeliveryItem>().Save(
- item,
- string.Format("Item {0} Rack {1}", !item.ShipmentLink.IsValid() ? "removed from" : "added to",
- Shipments.SelectedRows.First().Get<Shipment, string>(x => x.Code)),
- (o, e) => { }
- );
- Beep(itemrow != null ? CodeStatus.Removed : CodeStatus.Added);
- return;
- //StopWaiting();
- }
- }
- Beep(CodeStatus.Error);
- }
- }
- private CoreRow CheckShipmentLocalCache(string code)
- {
- var row = Shipments.MasterData.Rows.FirstOrDefault(r => r.Get<Shipment, string>(c => c.BarCode).Equals(code));
- if (row != null)
- return row;
- return null;
- }
- private CoreRow? CheckShipmentOnServer(string code)
- {
- var row = new Client<Shipment>().Query(new Filter<Shipment>(x => x.BarCode).IsEqualTo(code))
- .Rows.FirstOrDefault();
- if (row != null)
- {
- Shipments.AddRow(row);
- return row;
- }
- return null;
- }
- private DeliveryItem CheckItem(string code)
- {
- var row = ItemCache.Rows.FirstOrDefault(r => String.Equals(r.Get<DeliveryItem, string>(c => c.Barcode),code));
- return row != null ? row.ToObject<DeliveryItem>() : null;
- }
- //private void Timer_Tick(object sender, EventArgs e)
- //{
- // if (lastselection < DateTime.Now.AddMilliseconds(-500))
- // {
- // timer.IsEnabled = false;
- // try
- // {
- // lastselection = DateTime.MaxValue;
- // LoadShipment();
- // }
- // finally
- // {
- // timer.IsEnabled = true;
- // }
- // }
- //}
- private void LoadShipment()
- {
- RefreshCache();
- var row = Shipments.SelectedRows.FirstOrDefault();
- foreach (var scanner in Scanners)
- scanner.Actions.ToggleLed(row != null ? LedMode.GreenOn : LedMode.RedOn);
- var shipid = row != null ? row.Get<Shipment, Guid>(x => x.ID) : Guid.Empty;
- if (shipid != Items.CurrentShipmentID)
- {
- Items.CurrentShipmentID = shipid;
- Items.Refresh(false, true);
- }
- }
- private void Shipments_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
- {
- LoadShipment();
- //if (!_updatingItems && IsReady)
- // lastselection = DateTime.Now;
- }
- public Type DataType()
- {
- return typeof(Shipment);
- }
- public Dictionary<Type, CoreTable> DataEnvironment()
- {
- var env = new Dictionary<Type, CoreTable>();
- env[typeof(Shipment)] = Shipments.Data;
- env[typeof(DeliveryItem)] = new Client<DeliveryItem>().Query(new Filter<DeliveryItem>(x => x.ShipmentLink).LinkValid());
- return env;
- }
- private enum CodeStatus
- {
- Initialized,
- Opened,
- Closed,
- Added,
- Removed,
- Error,
- NotFound
- }
- }
- }
|