JobSummaryGrid.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Media;
  9. using Comal.Classes;
  10. using InABox.Clients;
  11. using InABox.Core;
  12. using InABox.DynamicGrid;
  13. using InABox.WPF;
  14. namespace PRSDesktop
  15. {
  16. internal class JobSummaryGrid : DynamicDataGrid<JobMaterial>, IJobControl, IDataModelSource
  17. {
  18. Guid empID = Guid.Empty;
  19. string empName = "";
  20. public bool IncludeReserves { get; set; }
  21. public Job Job { get; set; }
  22. public JobPanelSettings Settings { get; set; }
  23. public JobSummaryGrid() : base()
  24. {
  25. ColumnsTag = nameof(JobSummaryGrid);
  26. OnCellDoubleClick += JobSummaryGrid_OnCellDoubleClick;
  27. }
  28. protected override void Init()
  29. {
  30. base.Init();
  31. HiddenColumns.Add(x => x.Product.ID);
  32. HiddenColumns.Add(x => x.Style.ID);
  33. HiddenColumns.Add(x => x.Dimensions.UnitSize);
  34. HiddenColumns.Add(x => x.BillOfMaterials);
  35. HiddenColumns.Add(x => x.Requisitions);
  36. HiddenColumns.Add(x => x.PickingLists);
  37. HiddenColumns.Add(x => x.Issued);
  38. HiddenColumns.Add(x => x.ReservedStock);
  39. HiddenColumns.Add(x => x.OnOrder);
  40. HiddenColumns.Add(x => x.JobShortage);
  41. HiddenColumns.Add(x => x.FreeOnHand);
  42. HiddenColumns.Add(x => x.FreeOnOrder);
  43. HiddenColumns.Add(x => x.FreeStockTotal);
  44. HiddenColumns.Add(x => x.FreeStockShortage);
  45. HiddenColumns.Add(x => x.Product.Image.ID);
  46. HiddenColumns.Add(x => x.Product.Image.FileName);
  47. ActionColumns.Add(new DynamicImageManagerColumn<JobMaterial>(this, x => x.Product.Image, false)
  48. { Position = DynamicActionColumnPosition.Start });
  49. AddButton("Create PO", null, CreatePO);
  50. }
  51. protected override void DoReconfigure(FluentList<DynamicGridOption> options)
  52. {
  53. base.DoReconfigure(options);
  54. options.AddRange(
  55. DynamicGridOption.RecordCount,
  56. DynamicGridOption.SelectColumns,
  57. DynamicGridOption.FilterRows,
  58. DynamicGridOption.ExportData,
  59. DynamicGridOption.MultiSelect
  60. );
  61. }
  62. private bool StyleColumnVisible()
  63. {
  64. var styleColumn = CoreUtils.GetFullPropertyName<JobMaterial, ProductStyleLink>(x => x.Style, ".");
  65. return VisibleColumns.Any(x => x.ColumnName.StartsWith(styleColumn));
  66. }
  67. protected override void GenerateColumns(DynamicGridColumns columns)
  68. {
  69. columns.Add<JobMaterial, string>(x => x.Product.Group.Code, 120, "Group Code", "", Alignment.MiddleCenter);
  70. columns.Add<JobMaterial, string>(x => x.Product.Code, 200, "Product Code", "", Alignment.MiddleCenter);
  71. columns.Add<JobMaterial, string>(x => x.Product.Name, 0, "Product Name", "", Alignment.MiddleCenter);
  72. columns.Add<JobMaterial, string>(x => x.Dimensions.UnitSize, 120, "UOM", "", Alignment.MiddleCenter);
  73. columns.Add<JobMaterial, double>(x => x.BillOfMaterials, 80, "BOM", "", Alignment.MiddleCenter);
  74. columns.Add<JobMaterial, double>(x => x.Requisitions, 80, "Req.", "", Alignment.MiddleCenter);
  75. columns.Add<JobMaterial, double>(x => x.PickingLists, 80, "P/L", "", Alignment.MiddleCenter);
  76. columns.Add<JobMaterial, double>(x => x.Issued, 80, "Issued", "", Alignment.MiddleCenter);
  77. columns.Add<JobMaterial, double>(x => x.ReservedStock, 80, "Reserved", "", Alignment.MiddleCenter);
  78. columns.Add<JobMaterial, double>(x => x.OnOrder, 80, "Ordered", "", Alignment.MiddleCenter);
  79. columns.Add<JobMaterial, double>(x => x.JobShortage, 80, "Job Short", "", Alignment.MiddleCenter);
  80. columns.Add<JobMaterial, double>(x => x.FreeStockTotal, 80, "Free Stock", "", Alignment.MiddleCenter);
  81. columns.Add<JobMaterial, double>(x => x.FreeStockShortage, 80, "Stk Short", "", Alignment.MiddleCenter);
  82. }
  83. private void ShowDetailGrid<TEntity>(
  84. String columnname,
  85. Expression<Func<TEntity,object?>> productcol,
  86. Guid productid,
  87. Expression<Func<TEntity,object?>> stylecol,
  88. Guid? styleid,
  89. Expression<Func<TEntity,object?>> unitcol,
  90. String unitsize,
  91. Expression<Func<TEntity,object?>>? jobcol,
  92. Filter<TEntity>? extrafilter,
  93. Func<CoreRow,bool>? rowfilter
  94. )
  95. {
  96. var grid = (Activator.CreateInstance(typeof(DynamicDataGrid<>).MakeGenericType(typeof(TEntity))) as IDynamicDataGrid);
  97. if (grid == null)
  98. {
  99. MessageBox.Show($"Cannot create Grid for [{typeof(TEntity).Name}]");
  100. return;
  101. }
  102. grid.ColumnsTag = $"{ColumnsTag}.{columnname}";
  103. grid.Reconfigure(options =>
  104. {
  105. options.BeginUpdate().Clear().AddRange(DynamicGridOption.FilterRows, DynamicGridOption.SelectColumns).EndUpdate();
  106. });
  107. grid.OnDefineFilter += t =>
  108. {
  109. var filter = new Filter<TEntity>(productcol).IsEqualTo(productid)
  110. .And(unitcol).IsEqualTo(unitsize);
  111. if (styleid.HasValue)
  112. filter = filter.And(stylecol).IsEqualTo(styleid);
  113. if (jobcol != null)
  114. filter = filter.And(jobcol).IsEqualTo(Job.ID);
  115. if (extrafilter != null)
  116. filter = filter.And(extrafilter);
  117. return filter;
  118. };
  119. grid.OnFilterRecord += row => rowfilter?.Invoke(row) ?? true;
  120. var window = DynamicGridUtils.CreateGridWindow($"Viewing {CoreUtils.Neatify(columnname)} Calculation", (grid as BaseDynamicGrid)!);
  121. window.ShowDialog();
  122. }
  123. private void JobSummaryGrid_OnCellDoubleClick(object sender, DynamicGridCellClickEventArgs args)
  124. {
  125. var productid = args.Row.Get<StockSummary, Guid>(c => c.Product.ID);
  126. Guid? styleid = StyleColumnVisible() ? args.Row.Get<StockSummary, Guid>(c => c.Style.ID) : null;
  127. var unitsize = args.Row.Get<StockSummary, String>(c => c.Dimensions.UnitSize);
  128. if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.BillOfMaterials, ".")))
  129. {
  130. ShowDetailGrid<JobBillOfMaterialsItem>(
  131. args.Column.ColumnName,
  132. x => x.Product.ID,
  133. productid,
  134. x => x.Style.ID,
  135. styleid,
  136. x=>x.Dimensions.UnitSize,
  137. unitsize,
  138. x => x.Job.ID,
  139. new Filter<JobBillOfMaterialsItem>(x=>x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue),
  140. null
  141. );
  142. }
  143. else if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.Requisitions, ".")))
  144. {
  145. ShowDetailGrid<JobRequisitionItem>(
  146. args.Column.ColumnName,
  147. x => x.Product.ID,
  148. productid,
  149. x => x.Style.ID,
  150. styleid,
  151. x=>x.Dimensions.UnitSize,
  152. unitsize,
  153. x => x.Job.ID,
  154. new Filter<JobRequisitionItem>(x=>x.Requisition.Approved).IsNotEqualTo(DateTime.MinValue),
  155. null
  156. );
  157. }
  158. else if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.PickingLists, ".")))
  159. {
  160. ShowDetailGrid<RequisitionItem>(
  161. args.Column.ColumnName,
  162. x => x.Product.ID,
  163. productid,
  164. x => x.Style.ID,
  165. styleid,
  166. x=>x.Dimensions.UnitSize,
  167. unitsize,
  168. x => x.JobLink.ID,
  169. new Filter<RequisitionItem>(x=>x.RequisitionLink.Filled).IsEqualTo(DateTime.MinValue),
  170. null
  171. );
  172. }
  173. else if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.Issued, ".")))
  174. {
  175. ShowDetailGrid<StockMovement>(
  176. args.Column.ColumnName,
  177. x => x.Product.ID,
  178. productid,
  179. x => x.Style.ID,
  180. styleid,
  181. x=>x.Dimensions.UnitSize,
  182. unitsize,
  183. x => x.Job.ID,
  184. new Filter<StockMovement>(x=>x.IsTransfer).IsEqualTo(false).And(x=>x.Issued).IsNotEqualTo(0.0F),
  185. null
  186. );
  187. }
  188. else if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.ReservedStock, ".")))
  189. {
  190. ShowDetailGrid<StockHolding>(
  191. args.Column.ColumnName,
  192. x => x.Product.ID,
  193. productid,
  194. x => x.Style.ID,
  195. styleid,
  196. x=>x.Dimensions.UnitSize,
  197. unitsize,
  198. x=>x.Job.ID,
  199. new Filter<StockHolding>(x => x.Units).IsGreaterThan(0.1),
  200. null
  201. );
  202. }
  203. else if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.OnOrder, ".")))
  204. {
  205. ShowDetailGrid<PurchaseOrderItem>(
  206. args.Column.ColumnName,
  207. x => x.Product.ID,
  208. productid,
  209. x => x.Style.ID,
  210. styleid,
  211. x=>x.Dimensions.UnitSize,
  212. unitsize,
  213. x=>x.Job.ID,
  214. null,
  215. null
  216. );
  217. }
  218. else if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.FreeOnHand, ".")))
  219. {
  220. ShowDetailGrid<StockHolding>(
  221. args.Column.ColumnName,
  222. x => x.Product.ID,
  223. productid,
  224. x => x.Style.ID,
  225. styleid,
  226. x=>x.Dimensions.UnitSize,
  227. unitsize,
  228. null,
  229. new Filter<StockHolding>(x=>x.Units).IsNotEqualTo(0.0F)
  230. .And(
  231. IncludeReserves
  232. ? new Filter<StockHolding>(x=>x.Job.ID).IsNotEqualTo(Job.ID)
  233. : new Filter<StockHolding>(x=>x.Job.JobStatus.Active).IsEqualTo(false)
  234. ),
  235. null
  236. );
  237. }
  238. else if (string.Equals(args.Column.ColumnName, CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.FreeOnOrder, ".")))
  239. {
  240. ShowDetailGrid<PurchaseOrderItem>(
  241. args.Column.ColumnName,
  242. x => x.Product.ID,
  243. productid,
  244. x => x.Style.ID,
  245. styleid,
  246. x=>x.Dimensions.UnitSize,
  247. unitsize,
  248. null,
  249. IncludeReserves
  250. ? new Filter<PurchaseOrderItem>(x=>x.Job.ID).IsNotEqualTo(Job.ID)
  251. : new Filter<PurchaseOrderItem>(x=>x.Job.JobStatus.Active).IsEqualTo(false),
  252. null
  253. );
  254. }
  255. }
  256. public event DataModelUpdateEvent OnUpdateDataModel;
  257. public string SectionName => "Job Summary";
  258. public DataModel DataModel(Selection selection)
  259. {
  260. return new AutoDataModel<JobMaterial>(new Filter<JobMaterial>(x => x.Job.ID).IsEqualTo(Job.ID));
  261. }
  262. protected override JobMaterial CreateItem()
  263. {
  264. var result = base.CreateItem();
  265. result.Job.ID = Job.ID;
  266. result.Job.Synchronise(Job);
  267. return result;
  268. }
  269. private Tuple<Guid,Guid,Guid?,String>[] GetKeys(IEnumerable<CoreRow> rows, Columns<JobMaterial> columns, bool hasstyle)
  270. {
  271. int jobcol = columns.IndexOf(x => x.Job.ID);
  272. int productcol = columns.IndexOf(x => x.Product.ID);
  273. int stylecol = hasstyle ? columns.IndexOf(x => x.Style.ID) : -1;
  274. int unitcol = columns.IndexOf(x => x.Dimensions.UnitSize);
  275. var result = rows.Select(r => new Tuple<Guid, Guid, Guid?, String>(
  276. (Guid)(r.Values[jobcol] ?? Guid.Empty),
  277. (Guid)(r.Values[productcol] ?? Guid.Empty),
  278. (stylecol != -1) ? (Guid)(r.Values[stylecol] ?? Guid.Empty) : null,
  279. (String)(r.Values[unitcol] ?? ""))
  280. ).Distinct().ToArray();
  281. return result;
  282. }
  283. private CoreRow[] GetRows<TSource>(IEnumerable<CoreRow> rows, Columns<TSource> columns, Guid? jobid, Guid productid, Guid? styleid, String unitsize, Func<CoreRow,bool>? extrafilter = null) where TSource : IJobMaterial
  284. {
  285. int jobcol = columns.IndexOf(x => x.Job.ID);
  286. int productcol = columns.IndexOf(x => x.Product.ID);
  287. int stylecol = styleid.HasValue ? columns.IndexOf(x => x.Style.ID) : -1;
  288. int unitcol = columns.IndexOf(x => x.Dimensions.UnitSize);
  289. var subset = rows
  290. .Where(r=>
  291. (!jobid.HasValue || Guid.Equals(r.Values[jobcol], jobid))
  292. && Guid.Equals(r.Values[productcol], productid)
  293. && (!styleid.HasValue || Guid.Equals(r.Values[stylecol], styleid))
  294. && String.Equals(r.Values[unitcol], unitsize)
  295. && ((extrafilter == null) || extrafilter(r) )
  296. );
  297. return subset.ToArray();
  298. }
  299. private double Aggregate<TSource>(IEnumerable<CoreRow> rows, Columns<TSource> columns, bool hasstyle, bool hasjob, Expression<Func<TSource, object>> source, CoreRow target, Expression<Func<JobMaterial, object>> aggregate )
  300. {
  301. int srcol = columns.IndexOf(source);
  302. if (srcol == -1)
  303. return 0.00;
  304. var total = rows.Aggregate(0d, (value, row) => value + (double)(row.Values[srcol] ?? 0.0d));
  305. target.Set(aggregate, total);
  306. return total;
  307. }
  308. protected override void Reload(Filters<JobMaterial> criteria, Columns<JobMaterial> columns, ref SortOrder<JobMaterial>? sort,
  309. Action<CoreTable?, Exception?> action)
  310. {
  311. Filter<JobMaterial>? filter = Job.ID == Guid.Empty
  312. ? new Filter<JobMaterial>().None()
  313. : new Filter<JobMaterial>(x => x.Job.ID).IsEqualTo(Job.ID)
  314. .And(x => x.Product.ID).IsNotEqualTo(Guid.Empty);
  315. var orderby = sort;
  316. Progress.ShowModal("Loading Data",
  317. (progress) =>
  318. {
  319. CoreTable table = new CoreTable();
  320. table.LoadColumns(columns);
  321. var data = new Client<JobMaterial>().Query(filter, columns, orderby);
  322. var pids = data.ExtractValues<JobMaterial, Guid>(x => x.Product.ID).ToArray();
  323. if (pids.Any())
  324. {
  325. MultiQuery query = new MultiQuery();
  326. query.Add<StockHolding>(
  327. new Filter<StockHolding>(x => x.Product.ID).InList(pids)
  328. .And(x => x.Units).IsNotEqualTo(0.0F)
  329. .And(new Filter<StockHolding>(x => x.Job.ID).IsEqualTo(Guid.Empty).Or(x=>x.Job.ID).IsNotEqualTo(Job.ID)),
  330. new Columns<StockHolding>(x => x.Product.ID)
  331. .Add(x => x.Style.ID)
  332. .Add(x => x.Dimensions.UnitSize)
  333. .Add(x => x.Units)
  334. .Add(x => x.Job.ID)
  335. .Add(x => x.Job.JobStatus.Active)
  336. );
  337. query.Add<PurchaseOrderItem>(
  338. new Filter<PurchaseOrderItem>(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue)
  339. .And(x => x.Product.ID).InList(pids)
  340. .And(new Filter<PurchaseOrderItem>(x => x.Job.ID).IsEqualTo(Guid.Empty).Or(x=>x.Job.ID).IsNotEqualTo(Job.ID)),
  341. new Columns<PurchaseOrderItem>(x => x.Product.ID)
  342. .Add(x => x.Style.ID)
  343. .Add(x => x.Dimensions.UnitSize)
  344. .Add(x => x.Qty)
  345. .Add(x => x.Job.ID)
  346. .Add(x => x.Job.JobStatus.Active)
  347. );
  348. query.Query();
  349. var freestock = query.Get<StockHolding>();
  350. Columns<StockHolding> freestockcolumns = new Columns<StockHolding>(freestock.Columns.Select(x => x.ColumnName));
  351. var freeorders = query.Get<PurchaseOrderItem>();
  352. Columns<PurchaseOrderItem> freeordercolumns = new Columns<PurchaseOrderItem>(freeorders.Columns.Select(x => x.ColumnName));
  353. var hasStyle = StyleColumnVisible();
  354. var keys = GetKeys(data.Rows, columns, hasStyle);
  355. foreach (var key in keys)
  356. {
  357. var rows = GetRows(data.Rows, columns, key.Item1, key.Item2, key.Item3, key.Item4);
  358. if (rows.Any())
  359. {
  360. CoreRow newrow = table.NewRow();
  361. newrow.LoadValues(rows.First().Values);
  362. var bom = Aggregate(rows, columns, hasStyle, true, x => x.BillOfMaterials, newrow,
  363. x => x.BillOfMaterials);
  364. var requi = Aggregate(rows, columns, hasStyle, true, x => x.Requisitions, newrow, x => x.Requisitions);
  365. var picklist = Aggregate(rows, columns, hasStyle, true, x => x.PickingLists, newrow,
  366. x => x.PickingLists);
  367. var issued = Aggregate(rows, columns, hasStyle, true, x => x.Issued, newrow, x => x.Issued);
  368. var reserved = Aggregate(rows, columns, hasStyle, true, x => x.ReservedStock, newrow,
  369. x => x.ReservedStock);
  370. var ordered = Aggregate(rows, columns, hasStyle, true, x => x.OnOrder, newrow, x => x.OnOrder);
  371. var shortage = Math.Max(0, Math.Max(0, (requi - issued)) - (reserved + ordered));
  372. newrow.Set<JobMaterial, double>(x => x.JobShortage, shortage);
  373. var freestockrows = GetRows(freestock.Rows, freestockcolumns, null, key.Item2, key.Item3, key.Item4,
  374. IncludeReserves ? null : (r) => !r.Get<StockHolding,bool>(x=>x.Job.JobStatus.Active));
  375. var freeonhand = Aggregate(freestockrows, freestockcolumns, hasStyle, false, x => x.Units, newrow,
  376. x => x.FreeOnHand);
  377. newrow.Set<JobMaterial, double>(x => x.FreeOnHand, freeonhand);
  378. var freeorderrows = GetRows(freeorders.Rows, freeordercolumns, null, key.Item2, key.Item3, key.Item4,
  379. IncludeReserves ? null : (r) => !r.Get<PurchaseOrderItem,bool>(x=>x.Job.JobStatus.Active));
  380. var freeonorder = Aggregate(freeorderrows, freeordercolumns, hasStyle, false, x => x.Qty, newrow,
  381. x => x.FreeOnOrder);
  382. newrow.Set<JobMaterial, double>(x => x.FreeOnOrder, freeonorder);
  383. newrow.Set<JobMaterial, double>(x => x.FreeStockTotal, freeonhand + freeonorder);
  384. newrow.Set<JobMaterial, double>(x => x.FreeStockShortage, Math.Max(0, shortage - (freeonhand + freeonorder)));
  385. table.Rows.Add(newrow);
  386. }
  387. }
  388. }
  389. action?.Invoke(table, null);
  390. }
  391. );
  392. }
  393. protected override bool FilterRecord(CoreRow row)
  394. {
  395. var result = base.FilterRecord(row)
  396. && (
  397. row.Get<JobMaterial, double>(x => x.BillOfMaterials) != 0.0F ||
  398. row.Get<JobMaterial, double>(x => x.Requisitions) != 0.0F ||
  399. row.Get<JobMaterial, double>(x => x.PickingLists) != 0.0F ||
  400. row.Get<JobMaterial, double>(x => x.Issued) != 0.0F ||
  401. row.Get<JobMaterial, double>(x => x.ReservedStock) != 0.0F ||
  402. row.Get<JobMaterial, double>(x => x.OnOrder) != 0.0F
  403. );
  404. return result;
  405. }
  406. private String _jobshortage = CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.JobShortage, ".");
  407. private String _stockshortage = CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.FreeStockShortage, ".");
  408. protected override Brush? GetCellBackground(CoreRow row, string columnname)
  409. {
  410. if (String.Equals(columnname, _jobshortage))
  411. return row.Get<JobMaterial, double>(x => x.JobShortage) > 0.0F ? new SolidColorBrush(Colors.LightSalmon) { Opacity = 0.5 } : null;
  412. if (String.Equals(columnname, _stockshortage))
  413. return row.Get<JobMaterial, double>(x => x.FreeStockShortage) > 0.0F ? new SolidColorBrush(Colors.LightSalmon) { Opacity = 0.5 } : null;
  414. return null;
  415. }
  416. #region Create PO
  417. private void GetEmpID()
  418. {
  419. 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));
  420. if (table.Rows.Any())
  421. {
  422. empID = Guid.Parse(table.Rows.FirstOrDefault().Values[0].ToString());
  423. empName = table.Rows.FirstOrDefault().Values[1].ToString();
  424. }
  425. }
  426. private bool CreatePO(System.Windows.Controls.Button btn, CoreRow[] rows)
  427. {
  428. if (!rows.Any())
  429. {
  430. MessageBox.Show("Please select at least one row to add to PO");
  431. return false;
  432. }
  433. PurchaseOrder purchaseOrder = new PurchaseOrder();
  434. purchaseOrder.Description = "Created from Job Summary Screen" + System.Environment.NewLine;
  435. purchaseOrder.RaisedBy.ID = empID;
  436. var page = new SupplierPurchaseOrders();
  437. page.OnAfterSave += (form, items) =>
  438. {
  439. MessageBox.Show("Success - New Purchase Order Created (" + purchaseOrder.PONumber + ")");
  440. };
  441. return page.EditItems(new[] { purchaseOrder }, LoadPurchaseOrderItems, true);
  442. }
  443. private CoreTable LoadPurchaseOrderItems(Type arg)
  444. {
  445. Progress.Show("Working");
  446. var result = new CoreTable();
  447. result.LoadColumns(typeof(PurchaseOrderItem));
  448. List<PurchaseOrderItem> items = new List<PurchaseOrderItem>();
  449. foreach (CoreRow row in SelectedRows)
  450. {
  451. JobMaterial material = row.ToObject<JobMaterial>();
  452. PurchaseOrderItem POItem = new PurchaseOrderItem();
  453. POItem.Product.ID = material.Product.ID;
  454. POItem.Product.Code = material.Product.Code;
  455. POItem.Product.Name = material.Product.Name;
  456. POItem.Description = material.Product.Name;
  457. POItem.Qty = 0;
  458. POItem.Dimensions.CopyFrom(material.Dimensions);
  459. POItem.Style.ID = material.Style.ID;
  460. POItem.Style.Code = material.Style.Code;
  461. POItem.Style.Description = material.Style.Description;
  462. POItem.Job.ID = material.Job.ID;
  463. POItem.Dimensions.UnitSize = material.Dimensions.UnitSize;
  464. items.Add(POItem);
  465. }
  466. result.LoadRows(items);
  467. Progress.Close();
  468. return result;
  469. }
  470. #endregion
  471. }
  472. }