StockSummaryGrid.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using System.Windows.Media;
  5. using Comal.Classes;
  6. using InABox.Clients;
  7. using InABox.Core;
  8. using InABox.DynamicGrid;
  9. using Syncfusion.Data.Extensions;
  10. namespace PRSDesktop
  11. {
  12. public class StockSummaryGrid : DynamicDataGrid<StockSummary>, IDataModelSource
  13. {
  14. public Guid[] GroupIDs { get; set; }
  15. public Guid[] JobIDs { get; set; }
  16. public StockSummaryGrid() : base()
  17. {
  18. ColumnsTag = "StockSummaryGrid";
  19. GroupIDs = new Guid[] { };
  20. JobIDs = new Guid[] { };
  21. Options.AddRange(
  22. DynamicGridOption.RecordCount,
  23. DynamicGridOption.SelectColumns,
  24. DynamicGridOption.FilterRows,
  25. DynamicGridOption.ExportData,
  26. DynamicGridOption.MultiSelect
  27. );
  28. HiddenColumns.Add(x => x.Product.ID);
  29. HiddenColumns.Add(x => x.Style.ID);
  30. HiddenColumns.Add(x => x.Dimensions.UnitSize);
  31. HiddenColumns.Add(x => x.Product.Image.ID);
  32. HiddenColumns.Add(x => x.Product.Image.FileName);
  33. ActionColumns.Add(new DynamicImagePreviewColumn<StockSummary>(x => x.Product.Image)
  34. { Position = DynamicActionColumnPosition.Start });
  35. OnCellDoubleClick += StockSummaryGrid_OnCellDoubleClick;
  36. }
  37. protected override void GenerateColumns(DynamicGridColumns columns)
  38. {
  39. columns.Add<StockSummary, string>(x => x.Product.Code, 120, "Product Code", "", Alignment.MiddleCenter);
  40. columns.Add<StockSummary, string>(x => x.Style.Code, 120, "Style Code", "", Alignment.MiddleCenter);
  41. columns.Add<StockSummary, string>(x => x.Dimensions.UnitSize, 120, "Unit Size", "", Alignment.MiddleCenter);
  42. columns.Add<StockSummary, int>(x => x.Product.MinimumStockLevel, 120, "Minimum Stock Level", "", Alignment.MiddleCenter);
  43. columns.Add<StockSummary, double>(x => x.BillOfMaterials, 120, "BOM", "", Alignment.MiddleCenter);
  44. columns.Add<StockSummary, double>(x => x.Issued, 120, "Issued", "", Alignment.MiddleCenter);
  45. columns.Add<StockSummary, double>(x => x.AllStock, 120, "Stock", "", Alignment.MiddleCenter);
  46. columns.Add<StockSummary, double>(x => x.OnOrder, 120, "On Order", "", Alignment.MiddleCenter);
  47. columns.Add<StockSummary, double>(x => x.BalanceAvailable, 120, "Balance Available", "", Alignment.MiddleCenter);
  48. }
  49. private void ShowAggregateScreen(CoreRow row, DynamicGridColumn column, AggregateAttribute aggregate)
  50. {
  51. var entityType = aggregate.Source;
  52. var filter = Filter.Create(entityType).All();
  53. var aggFilter = aggregate.Filter;
  54. if (aggFilter is not null)
  55. filter.And(aggFilter);
  56. var links = aggregate.Links;
  57. foreach (var (pLeft, pStockSummary) in aggregate.Links)
  58. {
  59. if(string.Equals(pStockSummary, CoreUtils.GetFullPropertyName<StockSummary, Guid>(x => x.Job.ID, ".")))
  60. {
  61. var jobFilter = filter.And(pLeft);
  62. if (!JobIDs.Any())
  63. {
  64. jobFilter.None();
  65. }
  66. else if (!JobIDs.Contains(CoreUtils.FullGuid))
  67. {
  68. jobFilter.InList(JobIDs);
  69. }
  70. else
  71. {
  72. jobFilter.All();
  73. }
  74. }
  75. else if (string.Equals(pStockSummary, CoreUtils.GetFullPropertyName<StockSummary, Guid>(x => x.Style.ID, ".")))
  76. {
  77. if (HasStyle())
  78. {
  79. var value = row[pStockSummary];
  80. filter.And(pLeft).IsEqualTo(value);
  81. }
  82. }
  83. else
  84. {
  85. var value = row[pStockSummary];
  86. filter.And(pLeft).IsEqualTo(value);
  87. }
  88. }
  89. var grid = (Activator.CreateInstance(typeof(DynamicDataGrid<>).MakeGenericType(entityType)) as IDynamicDataGrid)!;
  90. grid.ColumnsTag = $"StockSummaryAggregate.{column.ColumnName}";
  91. //DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), entityType);
  92. grid.Options.BeginUpdate().Clear().AddRange(DynamicGridOption.FilterRows, DynamicGridOption.SelectColumns).EndUpdate();
  93. grid.OnDefineFilter += t =>
  94. {
  95. return filter;
  96. };
  97. var window = DynamicGridUtils.CreateGridWindow($"Viewing {CoreUtils.Neatify(column.ColumnName)} Calculation", (grid as BaseDynamicGrid)!);
  98. window.ShowDialog();
  99. }
  100. private void StockSummaryGrid_OnCellDoubleClick(object sender, DynamicGridCellClickEventArgs args)
  101. {
  102. if(DatabaseSchema.Property(typeof(StockSummary), args.Column.ColumnName) is StandardProperty property)
  103. {
  104. var aggregate = property.Property.GetCustomAttribute<AggregateAttribute>();
  105. if(aggregate is not null)
  106. {
  107. ShowAggregateScreen(args.Row, args.Column, aggregate);
  108. }
  109. }
  110. }
  111. private bool HasStyle()
  112. {
  113. return DataColumns().ColumnNames().Any(x => x.StartsWith("Style.") && !x.Equals("Style.ID"));
  114. }
  115. private Filters<StockSummary> GetFilters()
  116. {
  117. var filters = new Filters<StockSummary>();
  118. Filter<StockSummary>? _groupfilter = !GroupIDs.Any()
  119. ? new Filter<StockSummary>().None()
  120. : !GroupIDs.Contains(CoreUtils.FullGuid)
  121. ? new Filter<StockSummary>(x => x.Product.Group.ID).InList(GroupIDs)
  122. : null;
  123. filters.Add(_groupfilter);
  124. var jobFilter = !JobIDs.Any()
  125. ? new Filter<StockSummary>().None()
  126. : !JobIDs.Contains(CoreUtils.FullGuid)
  127. ? new Filter<StockSummary>(x => x.Job.ID).InList(JobIDs)
  128. : null;
  129. filters.Add(jobFilter);
  130. Filter<StockSummary> _productfilter = new Filter<StockSummary>(x => x.Product.ID).IsNotEqualTo(Guid.Empty);
  131. filters.Add(_productfilter);
  132. return filters;
  133. }
  134. protected override void Reload(Filters<StockSummary> criteria, Columns<StockSummary> columns, ref SortOrder<StockSummary>? sort,
  135. Action<CoreTable?, Exception?> action)
  136. {
  137. var filters = GetFilters();
  138. var filter = filters.Combine();
  139. var orderby = sort != null ? Serialization.Deserialize<SortOrder<StockSummary>>(Serialization.Serialize(sort)) : null;
  140. bool bHasStyle = HasStyle();
  141. new Client<StockSummary>().Query(filter,columns,orderby, (o,e) =>
  142. {
  143. static void UpdateColumn(CoreRow srcrow, CoreRow tgtrow, int colno)
  144. {
  145. if (colno != -1)
  146. tgtrow.Set(colno, tgtrow.Get<double>(colno) + (double)(srcrow.Values[colno] ?? default(double)));
  147. }
  148. CoreTable table = new CoreTable();
  149. table.LoadColumns(columns);
  150. if (o != null)
  151. {
  152. int productcol = columns.IndexOf(x => x.Product.ID);
  153. int stylecol = columns.IndexOf(x => x.Style.ID);
  154. int unitcol = columns.IndexOf(x => x.Dimensions.UnitSize);
  155. int[] updateColumns = new int[]
  156. {
  157. columns.IndexOf(x => x.BillOfMaterials),
  158. columns.IndexOf(x => x.Issued),
  159. columns.IndexOf(x => x.AllStock),
  160. columns.IndexOf(x => x.OnOrder)
  161. };
  162. Tuple<Guid, Guid, String>[] keys = o.Rows
  163. .Select(r => new Tuple<Guid, Guid, String>(
  164. (Guid)(r.Values[productcol] ?? Guid.Empty),
  165. bHasStyle ? (Guid)(r.Values[stylecol] ?? Guid.Empty) : Guid.Empty,
  166. (String)(r.Values[unitcol] ?? ""))
  167. ).Distinct().ToArray();
  168. foreach (var key in keys)
  169. {
  170. var rows = o.Rows.Where(r =>
  171. Guid.Equals(r.Values[productcol], key.Item1)
  172. && (!bHasStyle || Guid.Equals(r.Values[stylecol], key.Item2))
  173. && String.Equals(r.Values[unitcol], key.Item3)
  174. ).ToArray();
  175. CoreRow? newrow = null;
  176. foreach (var row in rows)
  177. {
  178. if (newrow == null)
  179. {
  180. newrow = table.NewRow();
  181. newrow.LoadValues(row.Values);
  182. }
  183. else
  184. {
  185. foreach(var column in updateColumns)
  186. {
  187. UpdateColumn(row, newrow, column);
  188. }
  189. }
  190. }
  191. if (newrow != null)
  192. table.Rows.Add(newrow);
  193. }
  194. }
  195. action?.Invoke(table, e);
  196. });
  197. }
  198. protected override bool FilterRecord(CoreRow row)
  199. {
  200. var result = base.FilterRecord(row);
  201. if (result)
  202. result = (result && row.Get<StockSummary, double>(x => x.BillOfMaterials) != 0.0F) ||
  203. row.Get<StockSummary, double>(x => x.Issued) != 0.0F ||
  204. row.Get<StockSummary, double>(x => x.AllStock) != 0.0F ||
  205. row.Get<StockSummary, double>(x => x.OnOrder) != 0.0F;
  206. return result;
  207. }
  208. // private String _minstock = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.Product.MinimumStockLevel, ".");
  209. // private String _bom = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.BillOfMaterials, ".");
  210. // private String _issued = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.Issued, ".");
  211. // private String _nettrequired = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.NettRequired, ".");
  212. // private String _stock = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.AllStock, ".");
  213. // private String _ordered = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.OnOrder, ".");
  214. private String _balance = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.BalanceAvailable, ".");
  215. protected override Brush? GetCellBackground(CoreRow row, string columnname)
  216. {
  217. // if (String.Equals(columnname, _minstock) || String.Equals(columnname, _bom) || String.Equals(columnname, _issued) || String.Equals(columnname, _nettrequired))
  218. // return Brushes.Khaki;
  219. // if (String.Equals(columnname, _stock) || String.Equals(columnname, _ordered))
  220. // return Brushes.Lavender;
  221. if (String.Equals(columnname, _balance))
  222. {
  223. var balance = row.Get<StockSummary, double>(x => x.BalanceAvailable);
  224. return balance < 0.0F
  225. ? Brushes.LightSalmon
  226. : Brushes.LightGreen;
  227. }
  228. return null;
  229. }
  230. #region IDataModelSource
  231. public event DataModelUpdateEvent OnUpdateDataModel;
  232. public string SectionName => "Stock Summary";
  233. public DataModel DataModel(Selection selection)
  234. {
  235. return new AutoDataModel<StockSummary>(null);
  236. }
  237. #endregion
  238. }
  239. }