JobRequisitionReviewDashboard.xaml.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. using Comal.Classes;
  2. using InABox.Core;
  3. using InABox.DynamicGrid;
  4. using InABox.WPF;
  5. using PRSDesktop.WidgetGroups;
  6. using InABox.Clients;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Threading.Tasks;
  11. using System.Windows;
  12. using System.Windows.Controls;
  13. using org.apache.logging.log4j.message;
  14. using static com.sun.tools.javap.TypeAnnotationWriter;
  15. using System.Windows.Media.Imaging;
  16. using System.Windows.Media;
  17. using org.omg.PortableInterceptor;
  18. namespace PRSDesktop
  19. {
  20. public class JobRequisitionReviewDashboardProperties : IDashboardProperties { }
  21. public class JobRequisitionReviewDashboardElement : DashboardElement<JobRequisitionReviewDashboard, Projects, JobRequisitionReviewDashboardProperties> { }
  22. /// <summary>
  23. /// Interaction logic for JobRequisitionReviewDashboard.xaml
  24. /// </summary>
  25. ///
  26. //Job Requi Review Dashboard works with JobRequisitionReviewGrid (for viewing data), and also allows:
  27. // 1. Changing the status of a Job Requi Item line via an action column with context menu.
  28. // Of note is "Reserving" stock - using the JobRequisitionReserveWindow, which works with the JobRequisitionItemStockHoldingReserverGrid
  29. // 2. Create a purchase order from a selection of one or more lines using the added button. If the PO process is cancelled, the PO and items created are cleaned up
  30. // 3. Splitting Job Requi Item lines
  31. public partial class JobRequisitionReviewDashboard : UserControl, IDashboardWidget<Projects, JobRequisitionReviewDashboardProperties>
  32. {
  33. public List<JobRequiReviewDashboardFilterItem> filterItems = new List<JobRequiReviewDashboardFilterItem>();
  34. public JobRequisitionReviewDashboardProperties Properties { get; set; }
  35. public JobRequisitionReviewDashboard()
  36. {
  37. InitializeComponent();
  38. Grid.Refresh(true, true);
  39. LoadFilters();
  40. }
  41. public void Refresh()
  42. {
  43. }
  44. public void Setup()
  45. {
  46. }
  47. public void Shutdown()
  48. {
  49. }
  50. private void Filter_SelectionChanged(object sender, SelectionChangedEventArgs e)
  51. {
  52. var item = filterComboBox.SelectedItem as JobRequiReviewDashboardFilterItem;
  53. Grid.RefreshOnFilterChanged(item.SupplierID);
  54. }
  55. private void LoadFilters()
  56. {
  57. List<Guid> productIDs = new List<Guid>();
  58. CoreTable productsTable = new Client<JobRequisitionItem>().Query(new Filter<JobRequisitionItem>(x => x.Product).LinkValid(),
  59. new Columns<JobRequisitionItem>(x => x.Product.ID));
  60. foreach (CoreRow row1 in productsTable.Rows)
  61. {
  62. productIDs.Add(Guid.Parse(row1.Values[0].ToString()));
  63. }
  64. CoreTable table = new Client<SupplierProduct>().Query(
  65. new Filter<SupplierProduct>(x => x.ProductLink).LinkValid()
  66. .And(x => x.SupplierLink).LinkValid(),
  67. new Columns<SupplierProduct>(x => x.SupplierLink.ID, x => x.ProductLink.ID, x => x.SupplierLink.Name, x => x.SupplierLink.Code));
  68. if (table.Rows.Any())
  69. {
  70. JobRequiReviewDashboardFilterItem firstItem = new JobRequiReviewDashboardFilterItem
  71. {
  72. Text = "No Filter"
  73. };
  74. filterItems.Add(firstItem);
  75. foreach (CoreRow row in table.Rows)
  76. {
  77. JobRequiReviewDashboardFilterItem filterItem = new JobRequiReviewDashboardFilterItem
  78. {
  79. SupplierID = Guid.Parse(row.Values[0].ToString()),
  80. ProductID = Guid.Parse(row.Values[1].ToString()),
  81. };
  82. if (row.Values[3] != null)
  83. {
  84. filterItem.Text = row.Values[3].ToString();
  85. if (row.Values[2] != null)
  86. {
  87. filterItem.Text = filterItem.Text + " " + row.Values[2].ToString();
  88. }
  89. }
  90. var founditem = filterItems.Find(x => x.SupplierID == filterItem.SupplierID);
  91. if (founditem == null)
  92. {
  93. if (productIDs.Contains(filterItem.ProductID))
  94. filterItems.Add(filterItem);
  95. }
  96. }
  97. }
  98. filterComboBox.ItemsSource = filterItems;
  99. }
  100. }
  101. public class JobRequisitionReviewGrid : DynamicDataGrid<JobRequisitionItem>
  102. {
  103. List<Guid> filterProductIDs = new List<Guid>();
  104. Guid empID = new Guid();
  105. string empName = "";
  106. public JobRequisitionReviewGrid()
  107. {
  108. Options.AddRange(
  109. DynamicGridOption.FilterRows,
  110. DynamicGridOption.SelectColumns,
  111. DynamicGridOption.RecordCount,
  112. DynamicGridOption.MultiSelect
  113. );
  114. HiddenColumns.Add(x => x.ID);
  115. HiddenColumns.Add(x => x.Product.ID);
  116. HiddenColumns.Add(x => x.Product.Code);
  117. HiddenColumns.Add(x => x.Product.Group.ID);
  118. HiddenColumns.Add(x => x.Product.Group.Code);
  119. HiddenColumns.Add(x => x.Product.Group.Description);
  120. HiddenColumns.Add(x => x.Style.ID);
  121. HiddenColumns.Add(x => x.Style.Code);
  122. HiddenColumns.Add(x => x.Style.Description);
  123. HiddenColumns.Add(x => x.Requisition.ID);
  124. HiddenColumns.Add(x => x.Requisition.Job.ID);
  125. HiddenColumns.Add(x => x.Requisition.Job.JobNumber);
  126. HiddenColumns.Add(x => x.Requisition.Job.Name);
  127. HiddenColumns.Add(x => x.Requisition.Number);
  128. HiddenColumns.Add(x => x.PurchaseOrderItem.PurchaseOrderLink.ID);
  129. HiddenColumns.Add(x => x.PurchaseOrderItem.PurchaseOrderLink.PONumber);
  130. HiddenColumns.Add(x => x.PurchaseOrderItem.DueDate);
  131. if (Security.CanEdit<JobRequisitionItem>())
  132. ActionColumns.Add(new DynamicMenuColumn(BuildMenu, EmptyReturnFunction));
  133. if (Security.CanEdit<PurchaseOrder>())
  134. AddButton("Create Purchase Order", null, CreatePurchaseOrder);
  135. if (Security.CanEdit<PurchaseOrder>())
  136. AddButton("Create Treatment PO", null, CreateTreatmentPO);
  137. ActionColumns.Add(new DynamicActionColumn(ViewStockImage, null) { ToolTip = ShowStockToolTip });
  138. ColumnsTag = "JobRequisitionReview";
  139. CoreTable table = new Client<Employee>().Query(new Filter<Employee>(x => x.UserLink.UserID).IsEqualTo(ClientFactory.UserID), new Columns<Employee>(x => x.ID, x => x.Name));
  140. if (table.Rows.Any())
  141. {
  142. empID = Guid.Parse(table.Rows.FirstOrDefault().Values[0].ToString());
  143. empName = table.Rows.FirstOrDefault().Values[1].ToString();
  144. }
  145. }
  146. private FrameworkElement ShowStockToolTip(DynamicActionColumn arg1, CoreRow row)
  147. {
  148. JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
  149. var holdings = new StockHoldingToolTipGrid(item.Product.ID, item.Job.ID, item.ID, item.Requisition.Number.ToString());
  150. holdings.Refresh(true, true);
  151. Frame frame = new Frame();
  152. frame.Background = new SolidColorBrush(Colors.LightYellow);
  153. frame.Padding = new Thickness(10);
  154. frame.BorderBrush = new SolidColorBrush(Colors.DarkGray);
  155. frame.BorderThickness = new Thickness(1);
  156. frame.Content = holdings;
  157. return frame;
  158. }
  159. private bool CreateTreatmentPO(Button button, CoreRow[] rows)
  160. {
  161. return true;
  162. }
  163. private BitmapImage? ViewStockImage(CoreRow? arg)
  164. {
  165. return PRSDesktop.Resources.warehouse.AsBitmapImage();
  166. }
  167. protected override void GenerateColumns(DynamicGridColumns columns)
  168. {
  169. columns.Add<JobRequisitionItem, DateTime>(x => x.Created, 80, "Date", "", Alignment.MiddleLeft);
  170. columns.Add<JobRequisitionItem, string>(x => x.Requisition.Job.JobNumber, 70, "Job", "", Alignment.MiddleLeft);
  171. columns.Add<JobRequisitionItem, int>(x => x.Requisition.Number, 50, "NO.", "", Alignment.MiddleLeft);
  172. columns.Add<JobRequisitionItem, string>(x => x.Product.Code, 70, "Code", "", Alignment.MiddleLeft);
  173. columns.Add<JobRequisitionItem, string>(x => x.Product.Name, 200, "Product Name", "", Alignment.MiddleLeft);
  174. columns.Add<JobRequisitionItem, string>(x => x.Style.Description, 150, "Style", "", Alignment.MiddleLeft);
  175. columns.Add<JobRequisitionItem, double>(x => x.Qty, 50, "Qty", "", Alignment.MiddleLeft);
  176. columns.Add<JobRequisitionItem, string>(x => x.Dimensions.UnitSize, 50, "Size", "", Alignment.MiddleLeft);
  177. columns.Add<JobRequisitionItem, string>(x => x.PurchaseOrderItem.PurchaseOrderLink.PONumber, 80, "PO Number", "", Alignment.MiddleLeft);
  178. columns.Add<JobRequisitionItem, string>(x => x.PurchaseOrderItem.PONumber, 80, "PO Number", "", Alignment.MiddleLeft);
  179. columns.Add<JobRequisitionItem, DateTime>(x => x.PurchaseOrderItem.DueDate, 80, "Due", "", Alignment.MiddleLeft);
  180. columns.Add<JobRequisitionItem, DateTime>(x => x.PurchaseOrderItem.ReceivedDate, 80, "Received", "", Alignment.MiddleLeft);
  181. columns.Add<JobRequisitionItem, JobRequisitionItemStatus>(x => x.Status, 80, "Status", "", Alignment.MiddleLeft);
  182. columns.Add<JobRequisitionItem, string>(x => x.Notes, 300, "Notes", "", Alignment.MiddleLeft);
  183. }
  184. private DynamicMenuStatus EmptyReturnFunction(CoreRow row)
  185. {
  186. return DynamicMenuStatus.Enabled;
  187. }
  188. #region Action Column Buttons
  189. private bool CheckValidAction(JobRequisitionItem item, bool bypassReserved)
  190. {
  191. bool valid = true;
  192. if (item.Status == JobRequisitionItemStatus.Reserved && !bypassReserved)
  193. {
  194. MessageBox.Show("Error. Item has already been reserved!");
  195. return false;
  196. }
  197. else if (item.Status == JobRequisitionItemStatus.OnOrder)
  198. {
  199. MessageBox.Show("Error. Item is already on order!");
  200. return false;
  201. }
  202. if (item.Status == JobRequisitionItemStatus.Received)
  203. {
  204. MessageBox.Show("Error. Item has already been recieved!");
  205. return false;
  206. }
  207. return valid;
  208. }
  209. private void Reserve_Clicked(CoreRow row)
  210. {
  211. JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
  212. CoreTable table = new Client<StockHolding>().Query
  213. (
  214. new Filter<StockHolding>(x => x.Product.ID).IsEqualTo(item.Product.ID)
  215. .And(x => x.Job).NotLinkValid(),
  216. new Columns<StockHolding>(x => x.Units)
  217. );
  218. if (table.Rows.Count == 0)
  219. {
  220. MessageBox.Show("No free stock found for this product.");
  221. return;
  222. }
  223. double units = 0.0;
  224. foreach (CoreRow corerow in table.Rows)
  225. {
  226. List<Object> list = corerow.Values;
  227. if (list[0] == null) list[0] = 0;
  228. double holdingUnits = double.Parse(list[0].ToString());
  229. units = units + holdingUnits;
  230. }
  231. if (item.Qty > units)
  232. {
  233. var result = MessageBox.Show("Current free stock for this product is " + units + ". Amount required for this requisition line is " + item.Qty +
  234. ". Do you want to split this requisition line?", "Alert", MessageBoxButton.YesNo);
  235. switch (result)
  236. {
  237. case MessageBoxResult.Yes:
  238. SplitLine(item, units, item.Qty - units, "line split due to insufficient stock holdings");
  239. return;
  240. case MessageBoxResult.No:
  241. break;
  242. default:
  243. return;
  244. }
  245. }
  246. Dispatcher.BeginInvoke(() =>
  247. {
  248. JobRequisitionReserveWindow window = new JobRequisitionReserveWindow();
  249. JobRequisitionItemStockHoldingReserverGrid holdings = new JobRequisitionItemStockHoldingReserverGrid
  250. (
  251. item.Product.ID, item.Requisition.Job.ID, item.ID, item.Requisition.Job.JobNumber + " (" + item.Requisition.Number + ")"
  252. );
  253. holdings.Refresh(true, true);
  254. window.grid.Children.Add(holdings);
  255. window.SizeToContent = SizeToContent.WidthAndHeight;
  256. window.ShowDialog();
  257. if (holdings.StockReserved || window.StockReserved)
  258. SaveRow(row, JobRequisitionItemStatus.Reserved, "Line marked reserved by " + empName + " on " + DateTime.Now.ToString("dd MMM yy"));
  259. });
  260. }
  261. private void SplitLine(JobRequisitionItem item, double oldItemQty, double newItemQty, string notes)
  262. {
  263. List<JobRequisitionItem> items = new List<JobRequisitionItem>();
  264. JobRequisitionItem newItem = new JobRequisitionItem();
  265. newItem.Requisition.ID = item.Requisition.ID;
  266. newItem.Requisition.Job.ID = item.Requisition.Job.ID;
  267. newItem.Requisition.Job.JobNumber = item.Requisition.Job.JobNumber;
  268. newItem.Requisition.Job.Name = item.Requisition.Job.Name;
  269. newItem.Product.ID = item.Product.ID;
  270. newItem.Product.Name = item.Product.Name;
  271. newItem.Product.Code = item.Product.Code;
  272. newItem.Product.Group.ID = item.Product.Group.ID;
  273. newItem.Product.Group.Description = item.Product.Group.Description;
  274. newItem.Dimensions.CopyFrom(item.Dimensions);
  275. newItem.Style.ID = item.Style.ID;
  276. newItem.Style.Description = item.Style.Description;
  277. newItem.Style.Code = item.Style.Code;
  278. newItem.Notes = item.Notes + Environment.NewLine + notes;
  279. item.Notes = newItem.Notes;
  280. item.Qty = oldItemQty;
  281. newItem.Qty = newItemQty;
  282. items.Add(newItem);
  283. items.Add(item);
  284. new Client<JobRequisitionItem>().Save(items, "Split lines from Job Requi Item Review Dashboard");
  285. MessageBox.Show("Line split - original line Qty is now " + item.Qty + ". New line Qty is " + newItem.Qty, "Success");
  286. Dispatcher.BeginInvoke(() =>
  287. {
  288. Refresh(true, true);
  289. });
  290. }
  291. private void SplitLine_Clicked(CoreRow row)
  292. {
  293. JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
  294. if (CheckValidAction(item, false))
  295. {
  296. int units = Convert.ToInt32(item.Qty);
  297. if (NumberEdit.Execute("Enter amount to split", 1, units, ref units))
  298. {
  299. SplitLine(item, item.Qty - units, units, "Line split");
  300. }
  301. }
  302. }
  303. private void OrderRequired_Clicked(CoreRow row)
  304. {
  305. JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
  306. if (CheckValidAction(item, false))
  307. SaveRow(row, JobRequisitionItemStatus.OrderRequired, "Line marked as Order Required by " + empName + " on " + DateTime.Now.ToString("dd MMM yy"));
  308. }
  309. private void TreatmentRequired_Clicked(CoreRow row)
  310. {
  311. JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
  312. if (item.Status != JobRequisitionItemStatus.Reserved)
  313. {
  314. MessageBox.Show("Stock must first be reserved for this item");
  315. return;
  316. }
  317. SaveRow(row, JobRequisitionItemStatus.TreatmentRequired, "Line marked as Treatment Required by " + empName + " on " + DateTime.Now.ToString("dd MMM yy"));
  318. }
  319. private void Uncheck_Clicked(CoreRow row)
  320. {
  321. string extraMessage = "";
  322. JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
  323. if (!CheckValidAction(item, true))
  324. return;
  325. CoreTable table = new Client<StockMovement>().Query
  326. (
  327. new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(item.ID),
  328. new Columns<StockMovement>(x => x.ID)
  329. );
  330. if (table.Rows.Any())
  331. {
  332. var result = MessageBox.Show("This will reverse stock movements already created for this Requisition Item. Proceed?", "Alert", MessageBoxButton.YesNo);
  333. switch (result)
  334. {
  335. case MessageBoxResult.Yes:
  336. break;
  337. case MessageBoxResult.No:
  338. return;
  339. default:
  340. return;
  341. }
  342. List<StockMovement> movements = new List<StockMovement>();
  343. foreach (CoreRow stockmovementRow in table.Rows)
  344. {
  345. StockMovement movement = new StockMovement();
  346. movement.ID = Guid.Parse(stockmovementRow.Values[0].ToString());
  347. movements.Add(movement);
  348. }
  349. new Client<StockMovement>().Delete(movements, "Stock movements reversed from Job Requisition Item Review Dashboard");
  350. extraMessage = " and Stock Movements Reversed ";
  351. }
  352. SaveRow(row, JobRequisitionItemStatus.NotChecked, "Line marked as Not Checked by " + empName + extraMessage + " on " + DateTime.Now.ToString("dd MMM yy"));
  353. }
  354. private bool CreatePurchaseOrder(Button btn, CoreRow[] rows)
  355. {
  356. if (!rows.Any())
  357. {
  358. MessageBox.Show("Please select at least one row to add to Purchase Order!");
  359. return false;
  360. }
  361. PurchaseOrder purchaseOrder = new PurchaseOrder();
  362. purchaseOrder.Notes = "Created from Job Requi Item Review Screen" + System.Environment.NewLine;
  363. purchaseOrder.RaisedBy.ID = empID;
  364. var page = new SupplierPurchaseOrders();
  365. page.OnAfterSave += (form, items) =>
  366. {
  367. PurchaseOrderOnSave(form, items);
  368. };
  369. return page.EditItems(new[] { purchaseOrder }, LoadPurchaseOrderItems, true);
  370. }
  371. private void PurchaseOrderOnSave(DynamicEditorForm form, PurchaseOrder[] items)
  372. {
  373. Progress.Show("Working");
  374. Guid POID = items[0].ID;
  375. CoreTable table = new Client<PurchaseOrderItem>().Query(new Filter<PurchaseOrderItem>(x => x.PurchaseOrderLink.ID).IsEqualTo(POID),
  376. new Columns<PurchaseOrderItem>(x => x.ID, x => x.Product.ID, x => x.Qty, x => x.Dimensions.UnitSize, x => x.DueDate, x => x.Job.ID));
  377. if (table.Rows.Any())
  378. {
  379. List<JobRequisitionItem> requiItems = new List<JobRequisitionItem>();
  380. List<PurchaseOrderItem> poItems = new List<PurchaseOrderItem>();
  381. foreach (CoreRow row in table.Rows)
  382. {
  383. PurchaseOrderItem poItem = row.ToObject<PurchaseOrderItem>();
  384. poItems.Add(poItem);
  385. }
  386. foreach (CoreRow row in SelectedRows)
  387. {
  388. JobRequisitionItem JobReqItem = row.ToObject<JobRequisitionItem>();
  389. foreach (var item in poItems)
  390. {
  391. if (JobReqItem.Product.ID == item.Product.ID &&
  392. JobReqItem.Qty == item.Qty &&
  393. JobReqItem.Dimensions.UnitSize == item.Dimensions.UnitSize &&
  394. JobReqItem.Job.ID == item.Job.ID)
  395. {
  396. JobReqItem.PurchaseOrderItem.ID = item.ID;
  397. JobReqItem.PurchaseOrderItem.DueDate = item.DueDate;
  398. JobReqItem.Status = JobRequisitionItemStatus.OnOrder;
  399. JobReqItem.Notes = JobReqItem.Notes + Environment.NewLine + "Line marked as On Order by " + empName + " on " + DateTime.Now.ToString("dd MMM yy");
  400. requiItems.Add(JobReqItem);
  401. }
  402. }
  403. }
  404. if (requiItems.Count > 0)
  405. {
  406. new Client<JobRequisitionItem>().Save(requiItems, "Updated on Create Purchase Order from Job Requi Dashboard");
  407. Dispatcher.BeginInvoke(() =>
  408. {
  409. Refresh(false, true);
  410. });
  411. }
  412. }
  413. Progress.Close();
  414. }
  415. private CoreTable LoadPurchaseOrderItems(Type arg)
  416. {
  417. Progress.Show("Working");
  418. var result = new CoreTable();
  419. result.LoadColumns(typeof(PurchaseOrderItem));
  420. List<PurchaseOrderItem> items = new List<PurchaseOrderItem>();
  421. foreach (CoreRow row in SelectedRows)
  422. {
  423. JobRequisitionItem JobReqItem = row.ToObject<JobRequisitionItem>();
  424. PurchaseOrderItem POItem = new PurchaseOrderItem();
  425. POItem.Product.ID = JobReqItem.Product.ID;
  426. POItem.Product.Code = JobReqItem.Product.Code;
  427. POItem.Product.Name = JobReqItem.Product.Name;
  428. POItem.Description = JobReqItem.Product.Name;
  429. POItem.Qty = JobReqItem.Qty;
  430. POItem.Dimensions.CopyFrom(JobReqItem.Dimensions);
  431. POItem.Style.ID = JobReqItem.Style.ID;
  432. POItem.Style.Code = JobReqItem.Style.Code;
  433. POItem.Style.Description = JobReqItem.Style.Description;
  434. POItem.Job.ID = JobReqItem.Requisition.Job.ID;
  435. items.Add(POItem);
  436. }
  437. result.LoadRows(items);
  438. Progress.Close();
  439. return result;
  440. }
  441. #endregion
  442. #region Utils
  443. private void SaveRow(CoreRow row, JobRequisitionItemStatus status, string note)
  444. {
  445. if (row == null)
  446. return;
  447. var id = row.Get<JobRequisitionItem, Guid>(c => c.ID);
  448. JobRequisitionItem item = Data.Rows.Where(r => r.Get<JobRequisitionItem, Guid>(c => c.ID).Equals(id)).FirstOrDefault().ToObject<JobRequisitionItem>();
  449. item.Status = status;
  450. item.Notes = item.Notes + Environment.NewLine + note;
  451. new Client<JobRequisitionItem>().Save(item, "Updated From Job Requisition Review Dashboard");
  452. Dispatcher.BeginInvoke(() =>
  453. {
  454. Refresh(true, true);
  455. });
  456. }
  457. private void SaveItem(JobRequisitionItem item, JobRequisitionItemStatus status, string note)
  458. {
  459. item.Status = status;
  460. item.Notes = item.Notes + Environment.NewLine + note;
  461. new Client<JobRequisitionItem>().Save(item, "Updated From Job Requisition Review Dashboard");
  462. Dispatcher.BeginInvoke(() =>
  463. {
  464. Refresh(true, true);
  465. });
  466. }
  467. private void MultiSaveRows(CoreRow[] rows, JobRequisitionItemStatus status, string note)
  468. {
  469. List<JobRequisitionItem> items = new List<JobRequisitionItem>();
  470. foreach (CoreRow row in rows)
  471. {
  472. var id = row.Get<JobRequisitionItem, Guid>(c => c.ID);
  473. JobRequisitionItem item = Data.Rows.Where(r => r.Get<JobRequisitionItem, Guid>(c => c.ID).Equals(id)).FirstOrDefault().ToObject<JobRequisitionItem>();
  474. item.Status = status;
  475. item.Notes = item.Notes + Environment.NewLine + note;
  476. items.Add(item);
  477. }
  478. new Client<JobRequisitionItem>().Save(items, "Updated From Job Requisition Review Dashboard");
  479. Dispatcher.BeginInvoke(() =>
  480. {
  481. Refresh(true, true);
  482. });
  483. }
  484. protected override void Reload(Filters<JobRequisitionItem> criteria, Columns<JobRequisitionItem> columns, ref SortOrder<JobRequisitionItem> sort,
  485. Action<CoreTable, Exception> action)
  486. {
  487. if (filterProductIDs.Count > 0)
  488. {
  489. Filter<JobRequisitionItem> filter = new Filter<JobRequisitionItem>(x => x.Product.ID).IsEqualTo(filterProductIDs.FirstOrDefault());
  490. foreach (Guid id in filterProductIDs)
  491. {
  492. if (id != filterProductIDs[0])
  493. filter = filter.Or(x => x.Product.ID).IsEqualTo(id);
  494. }
  495. criteria.Add(filter);
  496. }
  497. sort = new SortOrder<JobRequisitionItem>(x => x.Requisition.Number, SortDirection.Descending);
  498. base.Reload(criteria, columns, ref sort, action);
  499. }
  500. public void RefreshOnFilterChanged(Guid id)
  501. {
  502. filterProductIDs.Clear();
  503. if (id != Guid.Empty)
  504. {
  505. CoreTable table = new Client<SupplierProduct>().Query(
  506. new Filter<SupplierProduct>(x => x.SupplierLink.ID).IsEqualTo(id)
  507. .And(x => x.ProductLink).LinkValid(),
  508. new Columns<SupplierProduct>(x => x.ProductLink.ID));
  509. if (table.Rows.Any())
  510. {
  511. foreach (CoreRow row in table.Rows)
  512. {
  513. filterProductIDs.Add(Guid.Parse(row.Values[0].ToString()));
  514. }
  515. }
  516. }
  517. Dispatcher.BeginInvoke(() =>
  518. {
  519. Refresh(true, true);
  520. });
  521. }
  522. private void BuildMenu(DynamicMenuColumn column, CoreRow row)
  523. {
  524. column.AddItem("Reserve", PRSDesktop.Resources.project, Reserve_Clicked);
  525. column.AddItem("Treatment Required", PRSDesktop.Resources.palette, TreatmentRequired_Clicked);
  526. column.AddItem("Order Required", PRSDesktop.Resources.purchase, OrderRequired_Clicked);
  527. column.AddItem("Mark as Not Checked", PRSDesktop.Resources.disabled, Uncheck_Clicked);
  528. column.AddItem("Split Line", PRSDesktop.Resources.split, SplitLine_Clicked);
  529. }
  530. #endregion
  531. }
  532. public class JobRequiReviewDashboardFilterItem
  533. {
  534. public Guid SupplierID { get; set; }
  535. public Guid ProductID { get; set; }
  536. public string Text { get; set; }
  537. public JobRequiReviewDashboardFilterItem()
  538. {
  539. SupplierID = Guid.Empty;
  540. ProductID = Guid.Empty;
  541. Text = "";
  542. }
  543. }
  544. }