StockLocationPanel.xaml.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Windows.Controls;
  6. using System.Windows.Threading;
  7. using Comal.Classes;
  8. using InABox.Clients;
  9. using InABox.Core;
  10. using InABox.DynamicGrid;
  11. namespace PRSDesktop
  12. {
  13. /// <summary>
  14. /// Interaction logic for ProductBinList.xaml
  15. /// </summary>
  16. public partial class StockLocationPanel : UserControl, IPanel<StockLocation>
  17. {
  18. public StockLocationPanel()
  19. {
  20. InitializeComponent();
  21. }
  22. public bool IsReady { get; set; }
  23. public event DataModelUpdateEvent? OnUpdateDataModel;
  24. public void CreateToolbarButtons(IPanelHost host)
  25. {
  26. ProductSetupActions.Standard(host);
  27. host.CreatePanelAction(new PanelAction
  28. { Caption = "Treament PO", Image = PRSDesktop.Resources.purchase, OnExecute = DoCreatePurchaseOrder });
  29. }
  30. public string SectionName => "Stock Locations";
  31. public DataModel DataModel(Selection selection)
  32. {
  33. var ids = Locations.ExtractValues(x => x.ID, selection).ToArray();
  34. return new BaseDataModel<StockLocation>(new Filter<StockLocation>(x => x.ID).InList(ids));
  35. }
  36. public void Heartbeat(TimeSpan time)
  37. {
  38. }
  39. public void Refresh()
  40. {
  41. Locations.Refresh(false, true);
  42. Holdings.Refresh(false, true);
  43. Movements.Refresh(false, true);
  44. }
  45. public Dictionary<string, object[]> Selected()
  46. {
  47. var result = new Dictionary<string, object[]>();
  48. result[typeof(StockLocation).EntityName()] = Locations.SelectedRows;
  49. return result;
  50. }
  51. public void Setup()
  52. {
  53. Locations.Refresh(true, false);
  54. Holdings.Refresh(true, false);
  55. Movements.Refresh(true, false);
  56. Movements.Location = new StockLocation();
  57. Locations.OnSelectItem += Locations_OnSelectItem;
  58. Movements.OnChanged += Movements_OnChanged;
  59. Holdings.OnChanged += Holdings_OnChanged;
  60. }
  61. public void Shutdown(CancelEventArgs? cancel)
  62. {
  63. }
  64. #region Treatment PO
  65. private void DoCreatePurchaseOrder(PanelAction obj)
  66. {
  67. if (!Locations.SelectedRows.Any())
  68. return;
  69. var id = Locations.SelectedRows.First().Get<StockLocation, Guid>(c => c.ID);
  70. var window = new StockTreatmentWindow(id);
  71. if (window.ShowDialog() != true)
  72. return;
  73. //Progress.ShowModal("Creating Purchase Order", (progress) =>
  74. //{
  75. // PurchaseOrder order = new PurchaseOrder();
  76. // order.SupplierLink.ID = window.SupplierID;
  77. // order.SupplierLink.Name = window.SupplierName; //supplier != null ? supplier.Name : "Unknown Supplier";
  78. // order.Notes = String.Format("Materials Processing Request raised by {0} from Factory Floor", Employees[myID]);
  79. // order.RaisedBy.ID = myID;
  80. // order.IssuedBy.ID = myID;
  81. // order.IssuedDate = DateTime.Today;
  82. // order.DueDate = DateTime.Today.AddDays(7);
  83. // new Client<PurchaseOrder>().Save(order, "Created Treatment Purchase Order");
  84. //});
  85. //Supplier supplier = new Client<Supplier>().Query(
  86. // new Filter<Supplier>(x => x.ID).IsEqualTo(window.SupplierID),
  87. // new Columns<Supplier>(x=>x.ID
  88. //).Rows.FirstOrDefault()?.ToObject<Supplier>());
  89. //Progress.SetMessage("Creating Consignment");
  90. //Consignment consignment = new Consignment();
  91. //consignment.Number = String.Format("MFG PO {0}", order.PONumber);
  92. //consignment.Supplier.ID = order.SupplierLink.ID;
  93. //consignment.EstimatedDispatchDate = order.IssuedDate;
  94. //consignment.EstimatedWarehouseArrival = order.DueDate;
  95. //consignment.Description = String.Format("{0} #{1} - {2}", CurrentSection.Name, CurrentStation, Employees.ContainsKey(myID) ? Employees[myID] : "(unknown)");
  96. //new Client<Consignment>().Save(consignment, "Created by Factory Floor Purchase");
  97. //Progress.SetMessage("Processing Order");
  98. //List<PurchaseOrderItem> orderitems = new List<PurchaseOrderItem>();
  99. //List<ManufacturingPacket> packetupdates = new List<ManufacturingPacket>();
  100. //MultiQuery query = new MultiQuery();
  101. //query.Add<SupplierProduct>(
  102. // new Filter<SupplierProduct>(x => x.ProductLink.ID).IsEqualTo(window.ProductID).And(x => x.SupplierLink.ID).IsEqualTo(window.SupplierID),
  103. // new Columns<SupplierProduct>(x => x.Job.ID).Add(x => x.CostPrice).Add(x => x.ProductLink.NettCost)
  104. //);
  105. //query.Add<Product>(
  106. // new Filter<Product>(x => x.ID).IsEqualTo(window.ProductID),
  107. // new Columns<Product>(x => x.NettCost)
  108. //);
  109. //query.Query();
  110. //var supprods = query.Get<SupplierProduct>().Rows.Select(x => x.ToObject<SupplierProduct>()).ToArray();
  111. //var supprice = supprods.FirstOrDefault(x => Guid.Equals(x.Job.ID, Guid.Empty));
  112. //var prodprice = query.Get<Product>().Rows.FirstOrDefault()?.ToObject<Product>();
  113. //double stdcost = supprice != null
  114. // ? supprice.CostPrice
  115. // : prodprice != null
  116. // ? prodprice.NettCost
  117. // : 0.0F;
  118. //foreach (var row in window.Selected)
  119. //{
  120. // var treatment = row.ToObject<ManufacturingTreatment>();
  121. // var packet = Packets.Rows.First(p => p.Get<ManufacturingPacket, Guid>(c => c.ID).Equals(treatment.Packet.ID)).ToObject<ManufacturingPacket>();
  122. // packetupdates.Add(packet);
  123. // PurchaseOrderItem item = new PurchaseOrderItem();
  124. // item.PurchaseOrderLink.ID = order.ID;
  125. // item.Job.ID = treatment.Packet.SetoutLink.JobLink.ID;
  126. // item.Packet.ID = packet.ID;
  127. // item.Consignment.ID = consignment.ID;
  128. // item.ProductLink.ID = window.ProductID;
  129. // item.Qty = packet.BarcodeQty;
  130. // item.UnitSize = treatment.Parameter == 0.0F ? 1.0F : treatment.Parameter;
  131. // var jobprice = supprods.FirstOrDefault(x => x.Job.ID.Equals(item.Job.ID));
  132. // item.Cost = jobprice != null ? jobprice.CostPrice : stdcost;
  133. // List<String> description = new List<String>();
  134. // description.Add(String.Format("{0} x {1} - {2}", packet.BarcodeQty, packet.Serial, packet.Title));
  135. // List<String> dimensions = new List<string>();
  136. // if (packet.Height > 0.0F)
  137. // dimensions.Add(String.Format("H:{0:F2}mm", packet.Height));
  138. // if (packet.Width > 0.0F)
  139. // dimensions.Add(String.Format("W:{0:F2}mm", packet.Width));
  140. // if (packet.Length > 0.0F)
  141. // dimensions.Add(String.Format("L:{0:F2}mm", packet.Length));
  142. // dimensions.Add(String.Format("Param:{0:F4}", treatment.Parameter));
  143. // if (dimensions.Any())
  144. // description.Add(String.Format("Dimensions: {0}", String.Join(" ", dimensions)));
  145. // item.Description = String.Join("\n", description);
  146. // orderitems.Add(item);
  147. //}
  148. //new Client<PurchaseOrderItem>().Save(orderitems, "Created by Factory Floor Purchase");
  149. //Progress.SetMessage("Updating Packets");
  150. //foreach (var orderitem in orderitems)
  151. //{
  152. // var packet = packetupdates.FirstOrDefault(x => x.ID.Equals(orderitem.Packet.ID));
  153. // if (packet != null)
  154. // packet.OrderItem.ID = orderitem.ID;
  155. //}
  156. //new Client<ManufacturingPacket>().Save(packetupdates.Where(x => x.IsChanged()), "");
  157. //Progress.SetMessage("Creating Delivery");
  158. //Delivery delivery = new Delivery();
  159. //delivery.Date = DateTime.Today;
  160. //delivery.Due = DateTime.Today;
  161. //delivery.Employee.ID = myID;
  162. //StringBuilder sb = new StringBuilder();
  163. //sb.Append("Serial # ");
  164. //sb.AppendLine();
  165. //if (Employees.ContainsKey(myID))
  166. // sb.AppendLine();
  167. //delivery.Notes = String.Format("Delivery of Items for processing to {0}\nOrder #{1} (raised on {2:dd MMM yy} by {3})\nItems: {4}",
  168. // order.SupplierLink.Name,
  169. // order.PONumber,
  170. // delivery.Date,
  171. // myName,
  172. // String.Join(", ", orderitems.Select(x => String.Format("{0}{1}", x.Description.Split('\n').FirstOrDefault(), x.Qty > 1 ? " (x" + x.Qty.ToString("F0") + ")" : "")))
  173. //);
  174. //new Client<Delivery>().Save(delivery, "Created by Factory Floor Purchase");
  175. //Progress.Close();
  176. //PrintDeliveryBarcode(delivery, order, consignment);
  177. //PrintOrderItemBarcodes(delivery, order, consignment);
  178. //SendPurchaseNotification(order.PONumber);
  179. //MessageBox.Show("All Done");
  180. //new DeliveryBuilder(delivery.ID, order.ID).ShowDialog();
  181. //Refresh();
  182. }
  183. //private void SendPurchaseNotification(String PONumber)
  184. //{
  185. // List<Notification> updates = new List<Notification>();
  186. // CoreTable roles = new Client<EmployeeRole>().Query(new Filter<EmployeeRole>(x => x.RoleLink.Code).IsEqualTo("PURCHASES"));
  187. // foreach (var role in roles.Rows)
  188. // {
  189. // Notification notification = new Notification()
  190. // {
  191. // Title = String.Format("Treatment PO #{0} has been raised", PONumber),
  192. // Description = "The above Purchase Order has been created, and is ready to be checked and issued to the relevant supplier."
  193. // };
  194. // notification.Sender.ID = myID;
  195. // notification.Employee.ID = role.Get<EmployeeRole, Guid>(x => x.EmployeeLink.ID);
  196. // updates.Add(notification);
  197. // }
  198. // new Client<Notification>().Save(updates, "Sent Notification");
  199. //}
  200. //private void PrintDeliveryBarcode(Delivery delivery, PurchaseOrder order, Consignment consignment)
  201. //{
  202. // ManufacturingTreatmentDataModel model = new ManufacturingTreatmentDataModel(order, delivery, consignment);
  203. // String templatename = "Print Treatment Delivery Bar Code";
  204. // ReportTemplate template = new Client<ReportTemplate>().Load(new Filter<ReportTemplate>(x => x.Name).IsEqualTo(templatename).And(x => x.Section).IsEqualTo(model.Name)).FirstOrDefault();
  205. // if (template == null)
  206. // {
  207. // template = new ReportTemplate()
  208. // {
  209. // Section = model.Name,
  210. // Name = templatename
  211. // };
  212. // new Client<ReportTemplate>().Save(template, "Auto Created Report Template");
  213. // }
  214. // ReportUtils.PreviewReport(template, model, !Security.IsAllowed<CanDesignReports>(), Security.IsAllowed<CanDesignReports>());
  215. //}
  216. //private void PrintOrderItemBarcodes(Delivery delivery, PurchaseOrder order, Consignment consignment)
  217. //{
  218. // ManufacturingTreatmentDataModel model = new ManufacturingTreatmentDataModel(order, delivery, consignment);
  219. // String templatename = "Print Treatment Item Bar Codes";
  220. // ReportTemplate template = new Client<ReportTemplate>().Load(new Filter<ReportTemplate>(x => x.Name).IsEqualTo(templatename).And(x => x.Section).IsEqualTo(model.Name)).FirstOrDefault();
  221. // if (template == null)
  222. // {
  223. // template = new ReportTemplate()
  224. // {
  225. // Section = model.Name,
  226. // Name = templatename
  227. // };
  228. // new Client<ReportTemplate>().Save(template, "Auto Created Report Template");
  229. // }
  230. // ReportUtils.PreviewReport(template, model, !Security.IsAllowed<CanDesignReports>(), Security.IsAllowed<CanDesignReports>());
  231. //}
  232. //private CoreTable POItemTable(IEnumerable<PurchaseOrderItem> items)
  233. //{
  234. // var result = new CoreTable();
  235. // result.LoadColumns(typeof(PurchaseOrderItem));
  236. // result.LoadRows(items);
  237. // return result;
  238. //}
  239. #endregion
  240. public Dictionary<Type, CoreTable> DataEnvironment()
  241. {
  242. var result = new Dictionary<Type, CoreTable>();
  243. if (Locations.SelectedRows.Any())
  244. {
  245. var id = Locations.SelectedRows.FirstOrDefault().Get<StockLocation, Guid>(c => c.ID);
  246. result[typeof(StockLocation)] = new Client<StockLocation>().Query(new Filter<StockLocation>(x => x.ID).IsEqualTo(id));
  247. result[typeof(StockHolding)] = new Client<StockHolding>().Query(new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(id));
  248. result[typeof(StockMovement)] = new Client<StockMovement>().Query(new Filter<StockMovement>(x => x.Location.ID).IsEqualTo(id));
  249. var productids = new List<Guid>();
  250. foreach (var row in result[typeof(StockHolding)].Rows)
  251. {
  252. var productid = row.Get<StockHolding, Guid>(x => x.Product.ID);
  253. if (!productids.Contains(productid))
  254. productids.Add(productid);
  255. }
  256. result[typeof(Product)] = new Client<Product>().Query(new Filter<Product>(x => x.ID).InList(productids.ToArray()));
  257. var docids = new List<Guid>();
  258. foreach (var row in result[typeof(Product)].Rows)
  259. {
  260. var docid = row.EntityLinkID<Product, ImageDocumentLink>(x => x.Image) ?? Guid.Empty;
  261. if (docid != Guid.Empty && !docids.Contains(docid))
  262. docids.Add(docid);
  263. }
  264. result[typeof(Document)] = new Client<Document>().Query(new Filter<Document>(x => x.ID).InList(docids.ToArray()));
  265. }
  266. return result;
  267. }
  268. private void Holdings_OnChanged(object? sender, EventArgs args)
  269. {
  270. Movements.Refresh(false, true);
  271. }
  272. private void Movements_OnChanged(object? sender, EventArgs args)
  273. {
  274. Holdings.Refresh(false, true);
  275. }
  276. private void Locations_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
  277. {
  278. var row = e.Rows?.FirstOrDefault();
  279. var id = row != null ? row.Get<StockLocation, Guid>(c => c.ID) : CoreUtils.FullGuid;
  280. var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
  281. timer.Tick += (o, args) =>
  282. {
  283. timer.Stop();
  284. var location = row?.ToObject<StockLocation>();
  285. Holdings.Location = location;
  286. Holdings.Refresh(false, true);
  287. Movements.Location = location;
  288. Movements.Refresh(false, true);
  289. };
  290. timer.Start();
  291. }
  292. }
  293. }