DeliveryBuilder.xaml.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows;
  5. using System.Windows.Media;
  6. using Comal.Classes;
  7. using InABox.Clients;
  8. using InABox.Core;
  9. using InABox.DynamicGrid;
  10. using InABox.Reports;
  11. using InABox.Core.Reports;
  12. using InABox.Wpf;
  13. using InABox.Wpf.Reports;
  14. using InABox.WPF;
  15. using Motorola.Snapi;
  16. using Motorola.Snapi.Constants.Enums;
  17. using Motorola.Snapi.EventArguments;
  18. namespace PRSDesktop
  19. {
  20. /// <summary>
  21. /// Interaction logic for DeliveryBuilder.xaml
  22. /// </summary>
  23. public partial class DeliveryBuilder : ThemableWindow
  24. {
  25. private Guid _deliveryid = Guid.Empty;
  26. private readonly Guid _me = Guid.Empty;
  27. private Guid _orderid = Guid.Empty;
  28. private readonly Dictionary<CodeStatus, BeepPattern> BeepList = new()
  29. {
  30. { CodeStatus.Initialized, BeepPattern.FastWarble },
  31. { CodeStatus.Opened, BeepPattern.ThreeHighShort },
  32. { CodeStatus.Closed, BeepPattern.ThreeLowShort },
  33. { CodeStatus.Added, BeepPattern.LowHigh },
  34. { CodeStatus.Removed, BeepPattern.HighLow },
  35. { CodeStatus.NotFound, BeepPattern.FourLowLong },
  36. { CodeStatus.Error, BeepPattern.FourLowShort }
  37. };
  38. private readonly CoreTable Deliveries;
  39. private CoreTable Order;
  40. private CoreTable OrderItems = null;
  41. public List<IMotorolaBarcodeScanner> Scanners = new();
  42. private DynamicGridRowStyle _rowStyle;
  43. public DeliveryBuilder(Guid deliveryid, Guid orderid)
  44. {
  45. InitializeComponent();
  46. var me = new Client<Employee>().Query(new Filter<Employee>(x => x.UserLink.ID).IsEqualTo(ClientFactory.UserGuid),
  47. new Columns<Employee>().Default(ColumnType.ExcludeVisible));
  48. _me = me.Rows.Any() ? me.Rows.First().Get<Employee, Guid>(x => x.ID) : Guid.Empty;
  49. Deliveries = new Client<Delivery>().Query(
  50. new Filter<Delivery>(x => x.Completed).IsEqualTo(DateTime.MinValue)
  51. );
  52. _deliveryid = deliveryid;
  53. _orderid = orderid;
  54. Items.OnChanged += ItemsChanged;
  55. Items.OnGetRowStyle += Items_GetStyle;
  56. }
  57. private DynamicGridStyle Items_GetStyle(CoreRow row, DynamicGridStyle defaultstyle)
  58. {
  59. if (_rowStyle == null)
  60. _rowStyle = new DynamicGridRowStyle(defaultstyle) { Background = new SolidColorBrush(Colors.LightYellow) };
  61. return _rowStyle;
  62. }
  63. private void ItemsChanged(IDynamicGrid sender)
  64. {
  65. PrintButton.IsEnabled = Items.DeliveryDocketReady();
  66. }
  67. private void Window_Loaded(object sender, RoutedEventArgs e)
  68. {
  69. BarcodeScannerManager.Instance.Open();
  70. BarcodeScannerManager.Instance.RegisterForEvents(EventType.Barcode, EventType.Pnp, EventType.Image, EventType.Other, EventType.Rmd);
  71. BarcodeScannerManager.Instance.GetDevices();
  72. foreach (var scanner in BarcodeScannerManager.Instance.GetDevices())
  73. {
  74. Scanners.Add(scanner);
  75. scanner.Actions.ToggleLed(LedMode.RedOn);
  76. }
  77. Beep(CodeStatus.Initialized);
  78. BarcodeScannerManager.Instance.DataReceived += Instance_DataReceived;
  79. if (_deliveryid != Guid.Empty && _orderid != Guid.Empty)
  80. {
  81. CheckCode(null, string.Format("Delivery{0}Order{1}", _deliveryid, _orderid));
  82. PrintButton.IsEnabled = Items.DeliveryDocketReady();
  83. }
  84. }
  85. private void Window_Unloaded(object sender, RoutedEventArgs e)
  86. {
  87. foreach (var scanner in Scanners) scanner.Actions.ToggleLed(LedMode.GreenOff);
  88. BarcodeScannerManager.Instance.DataReceived -= Instance_DataReceived;
  89. BarcodeScannerManager.Instance.Close();
  90. }
  91. private void Beep(CodeStatus status)
  92. {
  93. foreach (var scanner in BarcodeScannerManager.Instance.GetDevices())
  94. {
  95. if (status == CodeStatus.Opened)
  96. scanner.Actions.ToggleLed(LedMode.GreenOn);
  97. else if (status == CodeStatus.Closed)
  98. scanner.Actions.ToggleLed(LedMode.RedOn);
  99. scanner.Actions.SoundBeeper(BeepList[status]);
  100. }
  101. }
  102. private void WaitBeep()
  103. {
  104. foreach (var scanner in BarcodeScannerManager.Instance.GetDevices())
  105. {
  106. scanner.Actions.ToggleLed(LedMode.YellowOn);
  107. scanner.Actions.SoundBeeper(BeepPattern.OneHighShort);
  108. }
  109. }
  110. private void Instance_DataReceived(object sender, BarcodeScanEventArgs e)
  111. {
  112. Dispatcher.Invoke(() => { CheckCode(Scanners[(int)e.ScannerId], e.Data); });
  113. }
  114. private void CheckCode(IMotorolaBarcodeScanner scanner, string code)
  115. {
  116. if (code.Contains("Delivery") && code.Contains("Order"))
  117. {
  118. var barcodes = code.Split(new[] { "Delivery", "Order" }, StringSplitOptions.RemoveEmptyEntries);
  119. if (barcodes.Length != 2)
  120. {
  121. MessageBox.Show(string.Format("Bad Delivery Barcode: {0} -> {1}", code, string.Join(" / ", barcodes)));
  122. return;
  123. }
  124. if (!Guid.TryParse(barcodes[0], out var deliveryid))
  125. {
  126. MessageBox.Show(string.Format("Bad Delivery Guid: {0}", barcodes[0]));
  127. return;
  128. }
  129. _deliveryid = deliveryid;
  130. if (!Guid.TryParse(barcodes[1], out var orderid))
  131. {
  132. MessageBox.Show(string.Format("Bad Order Guid: {0}", barcodes[1]));
  133. return;
  134. }
  135. _orderid = orderid;
  136. var delrow = Deliveries.Rows.FirstOrDefault(row => row.Get<Delivery, Guid>(x => x.ID).Equals(deliveryid));
  137. if (delrow == null)
  138. {
  139. MessageBox.Show(string.Format("Cannot Find Delivery: {0}", deliveryid));
  140. return;
  141. }
  142. DeliveryNumber.Text = delrow.Get<Delivery, int>(x => x.Number).ToString();
  143. DeliveryNotes.Text = delrow.Get<Delivery, string>(x => x.Notes);
  144. Items.DeliveryID = delrow.Get<Delivery, Guid>(x => x.ID);
  145. Items.OrderID = orderid;
  146. new Client<PurchaseOrder>().Query(
  147. new Filter<PurchaseOrder>(x => x.ID).IsEqualTo(orderid),
  148. null,
  149. null,
  150. (o, e) =>
  151. {
  152. Dispatcher.Invoke(() =>
  153. {
  154. Order = o;
  155. var ordrow = o.Rows.FirstOrDefault();
  156. OrderNumber.Text = ordrow != null ? ordrow.Get<PurchaseOrder, string>(x => x.PONumber) : "";
  157. Supplier.Text = ordrow != null ? ordrow.Get<PurchaseOrder, string>(x => x.SupplierLink.Name) : "";
  158. });
  159. }
  160. );
  161. PrintButton.IsEnabled = Items.DeliveryDocketReady();
  162. }
  163. else if (code.Contains("OrderItem"))
  164. {
  165. var barcodes = code.Split(new[] { "OrderItem" }, StringSplitOptions.RemoveEmptyEntries);
  166. try
  167. {
  168. Items.CheckCode(Guid.Parse(barcodes.First()));
  169. Items.Refresh(false, true);
  170. }
  171. catch (Exception e)
  172. {
  173. MessageBox.Show(e.Message);
  174. }
  175. PrintButton.IsEnabled = Items.DeliveryDocketReady();
  176. }
  177. else
  178. {
  179. MessageBox.Show("Bad Code: " + code);
  180. }
  181. }
  182. private void PrintButton_Click(object sender, RoutedEventArgs e)
  183. {
  184. var model = new DeliveryDataModel(new Filter<Delivery>(x => x.ID).IsEqualTo(_deliveryid));
  185. var templatename = "Print Treatment Delivery Docket";
  186. var sectionName = "Factory Floor - Treatment PO";
  187. var template = new Client<ReportTemplate>()
  188. .Load(
  189. new Filter<ReportTemplate>(x => x.Name).IsEqualTo(templatename)
  190. .And(x => x.DataModel).IsEqualTo(model.Name)
  191. .And(x => x.Section).IsEqualTo(sectionName)
  192. ).FirstOrDefault();
  193. if (template == null)
  194. {
  195. template = new ReportTemplate
  196. {
  197. DataModel = model.Name,
  198. Section = sectionName,
  199. Name = templatename
  200. };
  201. new Client<ReportTemplate>().Save(template, "Auto Created Report Template");
  202. }
  203. var delrow = Deliveries.Rows.FirstOrDefault(r => r.Get<Delivery, Guid>(c => c.ID).Equals(_deliveryid));
  204. if (delrow == null)
  205. {
  206. Progress.Close();
  207. MessageBox.Show("Cannot Find Delivery!");
  208. return;
  209. }
  210. ReportUtils.PreviewReport(template, model, !Security.IsAllowed<CanDesignReports>(), Security.IsAllowed<CanDesignReports>());
  211. SendDeliveryNotification(delrow.Get<Delivery, int>(x => x.Number));
  212. }
  213. private void SendDeliveryNotification(int DeliveryNumber)
  214. {
  215. var updates = new List<Notification>();
  216. var roles = new Client<EmployeeRole>().Query(new Filter<EmployeeRole>(x => x.RoleLink.Code).IsEqualTo("DELIVERIES"));
  217. foreach (var role in roles.Rows)
  218. {
  219. var notification = new Notification
  220. {
  221. Title = string.Format("Treatment Delivery #{0} has been raised", DeliveryNumber),
  222. Description = "The above Delivery has been created, and is ready to be shipped to the relevant supplier."
  223. };
  224. notification.Sender.ID = _me;
  225. notification.Employee.ID = role.Get<EmployeeRole, Guid>(x => x.EmployeeLink.ID);
  226. updates.Add(notification);
  227. }
  228. new Client<Notification>().Save(updates, "Sent Notification");
  229. }
  230. private enum CodeStatus
  231. {
  232. Initialized,
  233. Opened,
  234. Closed,
  235. Added,
  236. Removed,
  237. Error,
  238. NotFound
  239. }
  240. }
  241. }