using System; using System.Collections.Generic; using System.Linq; using System.Reactive.Linq; using System.Windows; using System.Windows.Controls; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.Wpf; using InABox.WPF; namespace PRSDesktop; internal class JobRequisitionItemGrid : DynamicDataGrid, IMasterDetailControl, ISpecificGrid { public Job? Job { get; set; } private JobRequisition? _master; public JobRequisition? Master { get => _master; set { _master = value; CheckVisibility(); Reconfigure(); } } public Filter MasterDetailFilter => Master != null ? Master.ID != Guid.Empty ? new Filter(x => x.Requisition.ID).IsEqualTo(Master.ID) : new Filter().None() : Job is not null && Job.ID != Guid.Empty ? new Filter(x => x.Requisition.Job.ID).IsEqualTo(Job.ID) : new Filter().None(); private Button CancelItemsButton; public JobRequisitionItemGrid() { CancelItemsButton = AddButton("Cancel Items", PRSDesktop.Resources.disabled.AsBitmapImage(), CancelItems); CheckVisibility(); } private void CheckVisibility() { CancelItemsButton.Visibility = Master is not null && Security.CanEdit() && Security.CanEdit() ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden; } protected override void SelectItems(CoreRow[]? rows) { base.SelectItems(rows); CancelItemsButton.IsEnabled = rows is not null && rows.Length > 0; } private bool CancelItems(Button button, CoreRow[] rows) { if (Master is null) return false; if(rows.Length == 0) { MessageWindow.ShowMessage("Please select at least one item to cancel.", "Select items"); return false; } // Reloading so I can ensure the correct columns without having to add hidden columns to JobRequisitionGrid. var oldRequi = Client.Query( new Filter(x => x.ID).IsEqualTo(Master?.ID ?? Guid.Empty), new Columns(x => x.Description) .Add(x => x.Number) .Add(x => x.DueDate)) .ToObjects() .First(); var oldRequiItems = Client.Query( new Filter(x => x.ID).InList(rows.Select(x => x.Get(x => x.ID)).ToArray()), new Columns(x => x.Qty) .Add(x => x.Sequence) .Add(x => x.Job.ID) .Add(x => x.Product.ID) .Add(x => x.Product.Code) .Add(x => x.Style.ID) .Add(x => x.Style.Code) .Add(x => x.Style.Description) .Add(x => x.Dimensions.Unit.ID) .Add(x => x.Dimensions.Quantity) .Add(x => x.Dimensions.Length) .Add(x => x.Dimensions.Width) .Add(x => x.Dimensions.Height) .Add(x => x.Dimensions.Weight) .Add(x => x.Dimensions.UnitSize) .Add(x => x.Supplier.ID)); var requisition = new JobRequisition { Description = $"Adjustment Requisition for Requisition {oldRequi.Number}", DueDate = oldRequi.DueDate }; requisition.Job.ID = Master.Job.ID; requisition.Job.Synchronise(Master.Job); var requiItems = new List(); foreach(var oldItem in oldRequiItems.ToObjects()) { var newItem = new JobRequisitionItem { Notes = "Adjustment Requisition item", Qty = -oldItem.Qty, Sequence = oldItem.Sequence }; newItem.Job.ID = requisition.Job.ID; newItem.Product.ID = oldItem.Product.ID; newItem.Style.ID = oldItem.Style.ID; newItem.Supplier.ID = oldItem.Supplier.ID; requiItems.Add(newItem); } var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicGrid<>), typeof(JobRequisition)); if (grid.EditItems(new JobRequisition[] { requisition }, t => { if (t == typeof(JobRequisitionItem)) { var table = new CoreTable(); table.LoadColumns(new Columns().Default( ColumnType.IncludeOptional, ColumnType.IncludeEditable, ColumnType.IncludeAggregates, ColumnType.IncludeForeignKeys, ColumnType.IncludeFormulae)); table.LoadRows(requiItems); return table; } return null; })) { MessageWindow.ShowMessage($"Created requisition {requisition.Number}", "Created Requisition"); return true; } else { return false; } } protected override void DoReconfigure(FluentList options) { base.DoReconfigure(options); options.AddRange( DynamicGridOption.RecordCount, DynamicGridOption.SelectColumns, DynamicGridOption.FilterRows, DynamicGridOption.MultiSelect ); if(Master is not null) { options.Add(DynamicGridOption.AddRows); } else { options.Remove(DynamicGridOption.AddRows); } } protected override void Reload(Filters criteria, Columns columns, ref SortOrder? sort, Action action) { criteria.Add(MasterDetailFilter); base.Reload(criteria, columns, ref sort, action); } protected override bool CanCreateItems() { return base.CanCreateItems() && (Master?.ID ?? Guid.Empty) != Guid.Empty; } protected override JobRequisitionItem CreateItem() { var result = base.CreateItem(); if(Master is not null) { result.Requisition.ID = Master.ID; result.Requisition.Synchronise(Master); result.Job.ID = Master.Job.ID; result.Job.Synchronise(Master.Job); } result.Qty = 1; return result; } protected override void OnAfterEditorValueChanged(DynamicEditorGrid? grid, JobRequisitionItem[] items, AfterEditorValueChangedArgs args, Dictionary changes) { base.OnAfterEditorValueChanged(grid, items, args, changes); if (args.ColumnName.Equals("Product.ID") || args.ColumnName.Equals("Dimensions") || args.ColumnName.StartsWith("Dimensions.") || args.ColumnName.Equals("Style.ID") || args.ColumnName.Equals("Supplier.ID")) { JobRequisitionItem.UpdateCosts( items, changes ); } } public override DynamicGridColumns GenerateColumns() { var columns = new DynamicGridColumns(); columns.Add(x => x.Created, 80, "Date", "", Alignment.MiddleLeft); columns.Add(x => x.Requisition.Job.JobNumber, 70, "Job", "", Alignment.MiddleLeft); columns.Add(x => x.Requisition.Number, 50, "NO.", "", Alignment.MiddleLeft); columns.Add(x => x.Product.Code, 70, "Code", "", Alignment.MiddleLeft); columns.Add(x => x.Product.Name, 200, "Product Name", "", Alignment.MiddleLeft); columns.Add(x => x.Style.Description, 150, "Style", "", Alignment.MiddleLeft); columns.Add(x => x.Qty, 50, "Qty", "", Alignment.MiddleLeft); columns.Add(x => x.Dimensions.UnitSize, 50, "Size", "", Alignment.MiddleLeft); columns.Add(x => x.PurchaseOrderNumbers, 80, "PO Numbers", "", Alignment.MiddleLeft); columns.Add(x => x.Status, 80, "Status", "", Alignment.MiddleLeft); columns.Add(x => x.Notes, 300, "Notes", "", Alignment.MiddleLeft); columns.AddRange(base.GenerateColumns()); return columns; } }