| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 | using System;using System.Linq;using System.Reflection;using System.Windows.Media;using Comal.Classes;using InABox.Clients;using InABox.Core;using InABox.DynamicGrid;using Syncfusion.Data.Extensions;namespace PRSDesktop{    public class StockSummaryGrid : DynamicDataGrid<StockSummary>, IDataModelSource    {                public Guid[] GroupIDs { get; set; }        public Guid[] JobIDs { get; set; }                public StockSummaryGrid() : base()        {            ColumnsTag = "StockSummaryGrid";            GroupIDs = new Guid[] { };            JobIDs = new Guid[] { };                        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.Product.Image.ID);            HiddenColumns.Add(x => x.Product.Image.FileName);            ActionColumns.Add(new DynamicImagePreviewColumn<StockSummary>(x => x.Product.Image)                { Position = DynamicActionColumnPosition.Start });                        OnCellDoubleClick += StockSummaryGrid_OnCellDoubleClick;        }        protected override void GenerateColumns(DynamicGridColumns columns)        {            columns.Add<StockSummary, string>(x => x.Product.Code, 120, "Product Code", "", Alignment.MiddleCenter);            columns.Add<StockSummary, string>(x => x.Style.Code, 120, "Style Code", "", Alignment.MiddleCenter);            columns.Add<StockSummary, string>(x => x.Dimensions.UnitSize, 120, "Unit Size", "", Alignment.MiddleCenter);            columns.Add<StockSummary, int>(x => x.Product.MinimumStockLevel, 120, "Minimum Stock Level", "", Alignment.MiddleCenter);            columns.Add<StockSummary, double>(x => x.BillOfMaterials, 120, "BOM", "", Alignment.MiddleCenter);            columns.Add<StockSummary, double>(x => x.Issued, 120, "Issued", "", Alignment.MiddleCenter);            columns.Add<StockSummary, double>(x => x.AllStock, 120, "Stock", "", Alignment.MiddleCenter);            columns.Add<StockSummary, double>(x => x.OnOrder, 120, "On Order", "", Alignment.MiddleCenter);            columns.Add<StockSummary, double>(x => x.BalanceAvailable, 120, "Balance Available", "", Alignment.MiddleCenter);        }        private void ShowAggregateScreen(CoreRow row, DynamicGridColumn column, AggregateAttribute aggregate)        {            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, pStockSummary) in aggregate.Links)            {                if(string.Equals(pStockSummary, CoreUtils.GetFullPropertyName<StockSummary, Guid>(x => x.Job.ID, ".")))                {                    var jobFilter = filter.And(pLeft);                    if (!JobIDs.Any())                    {                        jobFilter.None();                    }                    else if (!JobIDs.Contains(CoreUtils.FullGuid))                    {                        jobFilter.InList(JobIDs);                    }                    else                    {                        jobFilter.All();                    }                }                else if (string.Equals(pStockSummary, CoreUtils.GetFullPropertyName<StockSummary, Guid>(x => x.Style.ID, ".")))                {                    if (HasStyle())                    {                        var value = row[pStockSummary];                        filter.And(pLeft).IsEqualTo(value);                    }                }                else                {                    var value = row[pStockSummary];                    filter.And(pLeft).IsEqualTo(value);                }            }            var grid = (Activator.CreateInstance(typeof(DynamicDataGrid<>).MakeGenericType(entityType)) as IDynamicDataGrid)!;            grid.ColumnsTag = $"StockSummaryAggregate.{column.ColumnName}";            //DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), entityType);            grid.Options.BeginUpdate().Clear().AddRange(DynamicGridOption.FilterRows, DynamicGridOption.SelectColumns).EndUpdate();            grid.OnDefineFilter += t =>            {                return filter;            };            var window = DynamicGridUtils.CreateGridWindow($"Viewing {CoreUtils.Neatify(column.ColumnName)} Calculation", (grid as BaseDynamicGrid)!);            window.ShowDialog();        }        private void StockSummaryGrid_OnCellDoubleClick(object sender, DynamicGridCellClickEventArgs args)        {            if(DatabaseSchema.Property(typeof(StockSummary), args.Column.ColumnName) is StandardProperty property)            {                var aggregate = property.Property.GetCustomAttribute<AggregateAttribute>();                if(aggregate is not null)                {                    ShowAggregateScreen(args.Row, args.Column, aggregate);                }            }        }        private bool HasStyle()        {            return DataColumns().ColumnNames().Any(x => x.StartsWith("Style.") && !x.Equals("Style.ID"));        }        private Filters<StockSummary> GetFilters()        {            var filters = new Filters<StockSummary>();            Filter<StockSummary>? _groupfilter = !GroupIDs.Any()                ? new Filter<StockSummary>().None()                : !GroupIDs.Contains(CoreUtils.FullGuid)                    ? new Filter<StockSummary>(x => x.Product.Group.ID).InList(GroupIDs)                    : null;            filters.Add(_groupfilter);            var jobFilter = !JobIDs.Any()                ? new Filter<StockSummary>().None()                : !JobIDs.Contains(CoreUtils.FullGuid)                    ? new Filter<StockSummary>(x => x.Job.ID).InList(JobIDs)                    : null;            filters.Add(jobFilter);            Filter<StockSummary> _productfilter = new Filter<StockSummary>(x => x.Product.ID).IsNotEqualTo(Guid.Empty);            filters.Add(_productfilter);            return filters;        }                protected override void Reload(Filters<StockSummary> criteria, Columns<StockSummary> columns, ref SortOrder<StockSummary>? sort,            Action<CoreTable?, Exception?> action)        {            var filters = GetFilters();            var filter = filters.Combine();                        var orderby = sort != null ? Serialization.Deserialize<SortOrder<StockSummary>>(Serialization.Serialize(sort)) : null;            bool bHasStyle = HasStyle();                        new Client<StockSummary>().Query(filter,columns,orderby, (o,e) =>            {                                static void UpdateColumn(CoreRow srcrow, CoreRow tgtrow, int colno)                {                    if (colno != -1)                        tgtrow.Set(colno, tgtrow.Get<double>(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[] updateColumns = new int[]                    {                        columns.IndexOf(x => x.BillOfMaterials),                        columns.IndexOf(x => x.Issued),                        columns.IndexOf(x => x.AllStock),                        columns.IndexOf(x => x.OnOrder)                    };                    Tuple<Guid, Guid, String>[] keys = o.Rows                        .Select(r => new Tuple<Guid, Guid, String>(                            (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))                            && 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                            {                                foreach(var column in updateColumns)                                {                                    UpdateColumn(row, newrow, column);                                }                            }                        }                        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<StockSummary, double>(x => x.BillOfMaterials) != 0.0F) ||                         row.Get<StockSummary, double>(x => x.Issued) != 0.0F ||                         row.Get<StockSummary, double>(x => x.AllStock) != 0.0F ||                         row.Get<StockSummary, double>(x => x.OnOrder) != 0.0F;            return result;        }        // private String _minstock = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.Product.MinimumStockLevel, ".");        // private String _bom = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.BillOfMaterials, ".");        // private String _issued = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.Issued, ".");        // private String _nettrequired = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.NettRequired, ".");        // private String _stock = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.AllStock, ".");        // private String _ordered = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.OnOrder, ".");        private String _balance = CoreUtils.GetFullPropertyName<StockSummary, double>(x => x.BalanceAvailable, ".");        protected override Brush? GetCellBackground(CoreRow row, string columnname)        {            // if (String.Equals(columnname, _minstock) || String.Equals(columnname, _bom) || String.Equals(columnname, _issued) || String.Equals(columnname, _nettrequired))            //     return Brushes.Khaki;            // if (String.Equals(columnname, _stock) || String.Equals(columnname, _ordered))            //     return Brushes.Lavender;            if (String.Equals(columnname, _balance))            {                var balance = row.Get<StockSummary, double>(x => x.BalanceAvailable);                return balance < 0.0F                    ? Brushes.LightSalmon                    : Brushes.LightGreen;            }            return null;        }        #region IDataModelSource                public event DataModelUpdateEvent OnUpdateDataModel;        public string SectionName => "Stock Summary";        public DataModel DataModel(Selection selection)        {            return new AutoDataModel<StockSummary>(null);        }                #endregion    }}
 |