SupplierPurchaseOrderItemOneToMany.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. using System.Windows.Media.Imaging;
  7. using Comal.Classes;
  8. using FastReport.DevComponents.WinForms.Drawing;
  9. using InABox.Clients;
  10. using InABox.Core;
  11. using InABox.DynamicGrid;
  12. using InABox.WPF;
  13. using static InABox.DynamicGrid.DynamicMenuColumn;
  14. namespace PRSDesktop
  15. {
  16. public class SupplierPurchaseOrderItemOneToMany : DynamicOneToManyGrid<PurchaseOrder,PurchaseOrderItem>
  17. {
  18. private Button bill;
  19. private Button? consign;
  20. private Button? viewconsign;
  21. private Button receive;
  22. private Button assignLocation;
  23. public SupplierPurchaseOrderItemOneToMany() : base()
  24. {
  25. HiddenColumns.Add(x => x.ID);
  26. HiddenColumns.Add(x => x.BillLine.ID);
  27. HiddenColumns.Add(x => x.BillLine.Deleted);
  28. HiddenColumns.Add(x => x.Consignment.ID);
  29. HiddenColumns.Add(x => x.Product.Code);
  30. HiddenColumns.Add(x => x.Product.Name);
  31. HiddenColumns.Add(x => x.Description);
  32. HiddenColumns.Add(x => x.TaxCode.ID);
  33. HiddenColumns.Add(x => x.TaxCode.Code);
  34. HiddenColumns.Add(x => x.TaxCode.Description);
  35. HiddenColumns.Add(x => x.TaxCode.Rate);
  36. HiddenColumns.Add(x => x.TaxRate);
  37. HiddenColumns.Add(x => x.ExTax);
  38. HiddenColumns.Add(x => x.Tax);
  39. HiddenColumns.Add(x => x.IncTax);
  40. HiddenColumns.Add(x => x.ReceivedDate);
  41. HiddenColumns.Add(x => x.PurchaseOrderLink.SupplierLink.ID);
  42. HiddenColumns.Add(x => x.PurchaseOrderLink.Category.ID);
  43. HiddenColumns.Add(x => x.Product.DigitalForm.ID);
  44. HiddenColumns.Add(x => x.Product.DigitalForm.Description);
  45. HiddenColumns.Add(x => x.Product.Image.ID);
  46. HiddenColumns.Add(x => x.Product.Image.FileName);
  47. ActionColumns.Add(new DynamicImageManagerColumn<PurchaseOrderItem>(this, x => x.Product.Image, true)
  48. { Position = DynamicActionColumnPosition.Start });
  49. HiddenColumns.Add(x => x.FormCount);
  50. HiddenColumns.Add(x => x.OpenForms);
  51. ActionColumns.Add(new DynamicMenuColumn(BuildFormsMenu) { Position = DynamicActionColumnPosition.End });
  52. ActionColumns.Add(new DynamicImageColumn(FormsImage) { Position = DynamicActionColumnPosition.Start, ToolTip = FormsToolTip });
  53. }
  54. protected override void Init()
  55. {
  56. base.Init();
  57. if (Security.IsAllowed<CanViewConsignmentModule>())
  58. {
  59. consign = AddButton("Create Consignment", null, CreateConsignment);
  60. consign.IsEnabled = false;
  61. viewconsign = AddButton("View Consignment", null, ViewConsignment);
  62. viewconsign.Visibility = Visibility.Collapsed;
  63. }
  64. receive = AddButton("Receive Items", null, ReceiveItems);
  65. receive.IsEnabled = false;
  66. bill = AddButton("Enter Bill", null, EnterBill);
  67. bill.IsEnabled = false;
  68. assignLocation = AddButton("Assign Location", null, AssignLocation);
  69. }
  70. protected override void DoReconfigure(FluentList<DynamicGridOption> options)
  71. {
  72. base.DoReconfigure(options);
  73. if (!ReadOnly && Security.CanEdit<PurchaseOrderItem>())
  74. {
  75. options.AddRange(DynamicGridOption.DirectEdit);
  76. }
  77. }
  78. public override void Load(object item, Func<Type, CoreTable>? PageDataHandler)
  79. {
  80. Reconfigure();
  81. Refresh(true, false);
  82. base.Load(item, type =>
  83. {
  84. var data = PageDataHandler?.Invoke(type);
  85. if (data is null && type == typeof(PurchaseOrderItem))
  86. {
  87. data = new Client<PurchaseOrderItem>().Query(
  88. new Filter<PurchaseOrderItem>(x => x.PurchaseOrderLink.ID).IsEqualTo(Item.ID),
  89. DynamicGridUtils.LoadEditorColumns(DataColumns()),
  90. LookupFactory.DefineSort<PurchaseOrderItem>());
  91. }
  92. return data;
  93. });
  94. }
  95. private void BuildFormsMenu(DynamicMenuColumn column, CoreRow? row)
  96. {
  97. if (row == null) return;
  98. var formsItem = column.AddItem("Digital Forms", PRSDesktop.Resources.kanban, null);
  99. DynamicGridUtils.PopulateFormMenu<PurchaseOrderItemForm, PurchaseOrderItem, PurchaseOrderItemLink>(
  100. formsItem,
  101. row.Get<PurchaseOrderItem, Guid>(x => x.ID),
  102. row.ToObject<PurchaseOrderItem>);
  103. }
  104. private FrameworkElement? FormsToolTip(DynamicActionColumn arg1, CoreRow? arg2)
  105. {
  106. var text = arg2 == null || arg2.Get<PurchaseOrderItem, Guid>(x => x.Product.DigitalForm.ID) == Guid.Empty
  107. ? ""
  108. : arg2.Get<PurchaseOrderItem, int>(c => c.FormCount) == 0
  109. ? "No forms found for this item"
  110. : arg2.Get<PurchaseOrderItem, int>(c => c.OpenForms) > 0
  111. ? "Incomplete forms found"
  112. : "All forms completed";
  113. return string.IsNullOrWhiteSpace(text) ? null : arg1.TextToolTip(text);
  114. }
  115. private BitmapImage? FormsImage(CoreRow? arg)
  116. {
  117. if (arg == null)
  118. return PRSDesktop.Resources.quality.AsBitmapImage();
  119. return arg.Get<PurchaseOrderItem, Guid>(x => x.Product.DigitalForm.ID) == Guid.Empty
  120. ? null
  121. : arg.Get<PurchaseOrderItem, int>(c => c.FormCount) == 0
  122. ? PRSDesktop.Resources.warning.AsBitmapImage()
  123. : arg.Get<PurchaseOrderItem, int>(c => c.OpenForms) > 0
  124. ? PRSDesktop.Resources.warning.AsBitmapImage()
  125. : PRSDesktop.Resources.quality.AsBitmapImage();
  126. }
  127. private bool CreateConsignment(Button sender, CoreRow[] rows)
  128. {
  129. if (!rows.Any())
  130. {
  131. MessageBox.Show("Please select a row first");
  132. return false;
  133. }
  134. var consign = new Consignment();
  135. consign.Supplier.ID = rows.First().Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.SupplierLink.ID);
  136. consign.Category.ID = rows.First().Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.Category.ID);
  137. return new DynamicDataGrid<Consignment>().EditItems(new[] { consign }, LoadConsignmentLines, true);
  138. }
  139. private bool ViewConsignment(Button sender, CoreRow[] rows)
  140. {
  141. if (!rows.Any())
  142. {
  143. MessageBox.Show("Please select a row first");
  144. return false;
  145. }
  146. var consign = new Consignment();
  147. consign.Supplier.ID = rows.First().Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.SupplierLink.ID);
  148. consign.Category.ID = rows.First().Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.Category.ID);
  149. return new DynamicDataGrid<Consignment>().EditItems(new[] { consign }, LoadConsignmentLines, true);
  150. }
  151. private CoreTable LoadConsignmentLines(Type arg)
  152. {
  153. var result = new CoreTable();
  154. result.LoadColumns(typeof(PurchaseOrderItem));
  155. result.LoadRows(SelectedRows);
  156. return result;
  157. }
  158. private static bool EnterBill(Button sender, CoreRow[] rows)
  159. {
  160. if (!rows.Any())
  161. {
  162. MessageBox.Show("Please select a row first");
  163. return false;
  164. }
  165. var bill = new Bill();
  166. bill.SupplierLink.ID = rows.First()
  167. .Get<PurchaseOrderItem, Guid>(x => x.PurchaseOrderLink.SupplierLink.ID);
  168. bill.BillDate = DateTime.Today;
  169. return new DynamicDataGrid<Bill>().EditItems(new[] { bill }, (type) =>
  170. {
  171. return LoadBillLines(type, rows);
  172. }, true);
  173. }
  174. private static CoreTable LoadBillLines(Type type, CoreRow[] rows)
  175. {
  176. var result = new CoreTable();
  177. result.LoadColumns(typeof(BillLine));
  178. foreach (var row in rows)
  179. {
  180. var billrow = result.NewRow();
  181. billrow.Set<BillLine, Guid>(x => x.OrderItem.ID, row.Get<PurchaseOrderItem, Guid>(x => x.ID));
  182. var description = new List<string>();
  183. if (row.Get<PurchaseOrderItem, Guid>(x => x.Product.ID) != Guid.Empty)
  184. description.Add(string.Format("{0} : {1}", row.Get<PurchaseOrderItem, string>(x => x.Product.Code),
  185. row.Get<PurchaseOrderItem, string>(x => x.Product.Name)));
  186. var Description = row.Get<PurchaseOrderItem, string>(x => x.Description);
  187. if (!string.IsNullOrEmpty(Description))
  188. description.Add(Description);
  189. billrow.Set<BillLine, string>(x => x.Description, string.Join("\n", description));
  190. billrow.Set<BillLine, Guid>(x => x.TaxCode.ID, row.Get<PurchaseOrderItem, Guid>(x => x.TaxCode.ID));
  191. billrow.Set<BillLine, string>(x => x.TaxCode.Code, row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Code));
  192. billrow.Set<BillLine, string>(x => x.TaxCode.Description, row.Get<PurchaseOrderItem, string>(x => x.TaxCode.Description));
  193. billrow.Set<BillLine, double>(x => x.TaxCode.Rate, row.Get<PurchaseOrderItem, double>(x => x.TaxCode.Rate));
  194. billrow.Set<BillLine, double>(x => x.TaxRate, row.Get<PurchaseOrderItem, double>(x => x.TaxRate));
  195. billrow.Set<BillLine, double>(x => x.ExTax, row.Get<PurchaseOrderItem, double>(x => x.ExTax));
  196. billrow.Set<BillLine, double>(x => x.Tax, row.Get<PurchaseOrderItem, double>(x => x.Tax));
  197. billrow.Set<BillLine, double>(x => x.IncTax, row.Get<PurchaseOrderItem, double>(x => x.IncTax));
  198. result.Rows.Add(billrow);
  199. }
  200. return result;
  201. }
  202. private bool ReceiveItems(Button sender, CoreRow[] rows)
  203. {
  204. if (!rows.Any())
  205. {
  206. MessageBox.Show("Please select a row first");
  207. return false;
  208. }
  209. var now = DateTime.Now;
  210. using (new WaitCursor())
  211. {
  212. var items = LoadItems(rows);
  213. foreach (var item in items)
  214. item.ReceivedDate = now;
  215. new Client<PurchaseOrderItem>().Save(items, "Consignment Items Received");
  216. }
  217. return true;
  218. }
  219. public static bool AssignLocation(Button btn, CoreRow[] rows)
  220. {
  221. if (!rows.Any())
  222. {
  223. MessageBox.Show("Please select at least one row to assign");
  224. return false;
  225. }
  226. var menu = new ContextMenu();
  227. menu.AddItem("Create New Location", null, () =>
  228. {
  229. var grid = new StockLocationGrid();
  230. var location = new StockLocation();
  231. if (grid.EditItems(new StockLocation[] { location }))
  232. AssignLocationToItems(location.ID, rows);
  233. });
  234. menu.AddItem("Choose Existing", null, () =>
  235. {
  236. var popup = new PopupList(typeof(StockLocation), Guid.Empty, new string[] { });
  237. if (popup.ShowDialog() == true)
  238. AssignLocationToItems(popup.ID, rows);
  239. });
  240. menu.IsOpen = true;
  241. return true;
  242. }
  243. private static void AssignLocationToItems(Guid locationID, CoreRow[] rows)
  244. {
  245. List<PurchaseOrderItem> items = new List<PurchaseOrderItem>();
  246. foreach (CoreRow row in rows)
  247. {
  248. var item = row.ToObject<PurchaseOrderItem>();
  249. item.StockLocation.ID = locationID;
  250. items.Add(item);
  251. }
  252. new Client<PurchaseOrderItem>()
  253. .Save(items, "Added stock location from PurchaseOrderItem Grid");
  254. }
  255. /*private StockLocation[] QueryLocations()
  256. {
  257. CoreTable table = new Client<StockLocation>().Query(new Filter<StockLocation>(x => x.Active).IsEqualTo(true), new Columns<StockLocation>(x => x.ID));
  258. List<StockLocation> locations = new List<StockLocation>();
  259. foreach (CoreRow row in table.Rows)
  260. locations.Add(row.ToObject<StockLocation>());
  261. return locations.ToArray();
  262. }*/
  263. protected override void SelectItems(CoreRow[]? rows)
  264. {
  265. if (consign != null && viewconsign != null)
  266. {
  267. consign.IsEnabled =
  268. rows != null
  269. && !rows.Any(r => Entity.IsEntityLinkValid<PurchaseOrderItem, ConsignmentLink>(x => x.Consignment, r))
  270. && !rows.Any(r => r.Get<PurchaseOrderItem, DateTime>(c => c.ReceivedDate).IsEmpty() == false)
  271. && !ReadOnly && Security.CanEdit<Consignment>();
  272. viewconsign.Visibility =
  273. rows == null
  274. || consign.IsEnabled
  275. || rows.Select(r =>r.Get<PurchaseOrderItem, Guid>(x => x.Consignment.ID)).Distinct().Count() != 1
  276. ? Visibility.Collapsed
  277. : Visibility.Visible;
  278. consign.Visibility = viewconsign.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
  279. }
  280. receive.IsEnabled =
  281. rows != null
  282. && !rows.Any(r => Entity.IsEntityLinkValid<PurchaseOrderItem, ConsignmentLink>(x => x.Consignment, r))
  283. && !rows.Any(r => r.Get<PurchaseOrderItem, DateTime>(c => c.ReceivedDate).IsEmpty() == false)
  284. && !ReadOnly && Security.CanEdit<PurchaseOrderItem>();
  285. bill.IsEnabled =
  286. rows != null
  287. && !rows.Any(r => r.IsEntityLinkValid<PurchaseOrderItem, BillLineLink>(x => x.BillLine))
  288. && !ReadOnly && Security.CanEdit<PurchaseOrderItem>();
  289. assignLocation.IsEnabled =
  290. rows != null && !ReadOnly && Security.CanEdit<PurchaseOrderItem>();
  291. base.SelectItems(rows);
  292. }
  293. protected override void OnAfterEditorValueChanged(DynamicEditorGrid grid, PurchaseOrderItem[] items, string columnnname, Dictionary<string, object?> changes)
  294. {
  295. base.OnAfterEditorValueChanged(grid, items, columnnname, changes);
  296. if (columnnname.Equals("Product.ID") || columnnname.Equals("Job.ID") || columnnname.StartsWith("Dimensions."))
  297. {
  298. PurchaseOrder.UpdateCosts(
  299. items,
  300. Item.SupplierLink.ID,
  301. changes
  302. );
  303. }
  304. }
  305. protected override Dictionary<string, object?> EditorValueChanged(IDynamicEditorForm editor, PurchaseOrderItem[] items, string name,
  306. object value)
  307. {
  308. var results = base.EditorValueChanged(editor, items, name, value);
  309. if (name.Equals("ProductLink.TaxCode.ID"))
  310. DynamicGridUtils.UpdateEditorValue(items, "TaxCode.ID", (Guid)value, results);
  311. return results;
  312. }
  313. }
  314. }