using System; using System.Linq; using System.Reflection; using System.Windows; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using Microsoft.Exchange.WebServices.Data; namespace PRSDesktop { internal class JobSummaryGrid : DynamicDataGrid, IJobControl, IDataModelSource { public JobSummaryGrid() : base() { Options.AddRange( DynamicGridOption.RecordCount, DynamicGridOption.SelectColumns, DynamicGridOption.FilterRows, DynamicGridOption.ExportData, DynamicGridOption.MultiSelect ); HiddenColumns.Add(x => x.Product.ID); HiddenColumns.Add(x => x.Style.ID); HiddenColumns.Add(x => x.Dimensions.UnitSize); HiddenColumns.Add(x => x.BillOfMaterials); HiddenColumns.Add(x => x.TotalRequired); HiddenColumns.Add(x => x.BalanceRequired); HiddenColumns.Add(x => x.ReservedStock); HiddenColumns.Add(x => x.OnOrder); HiddenColumns.Add(x => x.Issued); HiddenColumns.Add(x => x.Received); HiddenColumns.Add(x => x.Product.Image.ID); HiddenColumns.Add(x => x.Product.Image.FileName); ActionColumns.Add(new DynamicImageManagerColumn(this, x => x.Product.Image, false) { Position = DynamicActionColumnPosition.Start }); OnCellDoubleClick += JobSummaryGrid_OnCellDoubleClick; } private void JobSummaryGrid_OnCellDoubleClick(object sender, DynamicGridCellClickEventArgs args) { if(args.Column.ColumnName == "BillOfMaterials" || args.Column.ColumnName == "TotalRequired" || args.Column.ColumnName == "ReservedStock" || args.Column.ColumnName == "OnOrder" || args.Column.ColumnName == "Issued" || args.Column.ColumnName == "Received" || args.Column.ColumnName == "FreeStock") { if(DatabaseSchema.Property(typeof(JobMaterial), args.Column.ColumnName) is StandardProperty property) { var aggregate = property.Property.GetCustomAttribute(); if(aggregate is not null) { var entityType = aggregate.Source; var filter = Filter.Create(entityType).All(); var aggFilter = aggregate.Filter; if (aggFilter is not null) filter.And(aggFilter); var links = aggregate.Links; foreach (var (pLeft, pJobMaterial) in aggregate.Links) { var value = pJobMaterial == "Job.ID" ? JobID : args.Row[pJobMaterial]; filter.And(pLeft).IsEqualTo(value); } var grid = (Activator.CreateInstance(typeof(DynamicDataGrid<>).MakeGenericType(entityType)) as IDynamicDataGrid)!; grid.ColumnsTag = $"JobSummaryAggregate.{args.Column.ColumnName}"; //DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), entityType); grid.Options.BeginUpdate().Clear().AddRange(DynamicGridOption.FilterRows, DynamicGridOption.SelectColumns).EndUpdate(); grid.OnDefineFilter += (o, type) => { return filter; }; var window = DynamicGridUtils.CreateGridWindow($"Viewing {CoreUtils.Neatify(args.Column.ColumnName)} Calculation", (grid as BaseDynamicGrid)!); window.ShowDialog(); } } } else if(args.Column.ColumnName == "BalanceRequired") { var totalRequired = (double)(args.Row["TotalRequired"] ?? 0.0); var issued = (double)(args.Row["Issued"] ?? 0.0); var balance = (double)(args.Row["BalanceRequired"] ?? 0.0); MessageBox.Show($"BalanceRequired\n = TotalRequired - Issued\n = {totalRequired:F2} - {issued:F2} = {balance:F2}"); } } public event DataModelUpdateEvent OnUpdateDataModel; public string SectionName => "Job Summary"; public DataModel DataModel(Selection selection) { return new AutoDataModel(new Filter(x => x.Job.ID).IsEqualTo(JobID)); } public Guid JobID { get; set; } protected override JobMaterial CreateItem() { var result = base.CreateItem(); result.Job.ID = JobID; return result; } protected override void Reload(Filters criteria, Columns columns, ref SortOrder? sort, Action action) { Filter? filter = JobID == Guid.Empty ? new Filter().None() : new Filter(x => x.Job.ID).IsEqualTo(JobID) .And(x => x.Product.ID).IsNotEqualTo(Guid.Empty); var orderby = sort != null ? Serialization.Deserialize>(Serialization.Serialize(sort)) : null; bool bHasStyle = columns.ColumnNames().Any(x => x.StartsWith("Style.") && !x.Equals("Style.ID")); new Client().Query(filter,columns,orderby, (o,e) => { void UpdateColumn(CoreRow srcrow, CoreRow tgtrow, int colno) { if (colno != -1) tgtrow.Set(colno, tgtrow.Get(colno) + (double)(srcrow.Values[colno] ?? default(double))); } CoreTable table = new CoreTable(); table.LoadColumns(columns); if (o != null) { int productcol = columns.IndexOf(x => x.Product.ID); int stylecol = columns.IndexOf(x => x.Style.ID); int unitcol = columns.IndexOf(x => x.Dimensions.UnitSize); int bomcol = columns.IndexOf(x => x.BillOfMaterials); int requiredcol = columns.IndexOf(x => x.TotalRequired); int reservedcol = columns.IndexOf(x => x.ReservedStock); int orderedcol = columns.IndexOf(x => x.OnOrder); int receivedcol = columns.IndexOf(x => x.Received); int issuedcol = columns.IndexOf(x => x.Issued); int balancecol = columns.IndexOf(x => x.BalanceRequired); Tuple[] keys = o.Rows .Select(r => new Tuple( (Guid)(r.Values[productcol] ?? Guid.Empty), bHasStyle ? (Guid)(r.Values[stylecol] ?? Guid.Empty) : Guid.Empty, (String)(r.Values[unitcol] ?? "")) ).Distinct().ToArray(); foreach (var key in keys) { var rows = o.Rows.Where(r => Guid.Equals(r.Values[productcol], key.Item1) && (bHasStyle ? Guid.Equals(r.Values[stylecol], key.Item2) : true) && String.Equals(r.Values[unitcol], key.Item3) ).ToArray(); CoreRow newrow = null; foreach (var row in rows) { if (newrow == null) { newrow = table.NewRow(); newrow.LoadValues(row.Values); } else { UpdateColumn(row, newrow, bomcol); UpdateColumn(row, newrow, requiredcol); UpdateColumn(row, newrow, orderedcol); UpdateColumn(row, newrow, receivedcol); UpdateColumn(row, newrow, issuedcol); UpdateColumn(row, newrow, balancecol); UpdateColumn(row, newrow, reservedcol); } } if (newrow != null) table.Rows.Add(newrow); } } action?.Invoke(table, e); }); } protected override bool FilterRecord(CoreRow row) { var result = base.FilterRecord(row); if (result) result = (result && row.Get(x => x.BillOfMaterials) != 0.0F) || row.Get(x => x.TotalRequired) != 0.0F || row.Get(x => x.BalanceRequired) != 0.0F || row.Get(x => x.OnOrder) != 0.0F || row.Get(x => x.Issued) != 0.0F || row.Get(x => x.Received) != 0.0F || row.Get(x => x.ReservedStock) != 0.0F; return result; } } }