using Comal.Classes;
using InABox.Clients;
using InABox.Core;
using InABox.DynamicGrid;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
namespace PRSDesktop.Panels.Requisitions;
///
/// Interaction logic for RequisitionItemEditor.xaml
///
public partial class RequisitionItemEditor : INotifyPropertyChanged
{
private readonly RequisitionItem Item;
public RequisitionItem[]? Result { get; private set; }
private bool _loadedAllocations;
private bool _loadedStockHoldings;
private bool _loadedProductInstances;
private bool _loadedBOMItems;
private bool _loadedJobRequisitionItems;
private bool _loadedCustom;
private bool _allowActual;
private bool _canSave;
public bool CanSave
{
get => _canSave;
private set
{
_canSave = value;
OnPropertyChanged();
}
}
public RequisitionItemEditor(Func> products, RequisitionItem requisitionItem, bool allowActual)
{
_allowActual = allowActual;
Item = requisitionItem;
InitializeComponent();
StockHoldingProducts.ProductsFunction = products;
ProductInstancesProducts.ProductsFunction = products;
BOMItems.Item = requisitionItem;
JobRequisitionItemsGrid.Item = requisitionItem;
AllocationsPage.Visibility = _allowActual && requisitionItem.Product.ID != Guid.Empty
? Visibility.Visible
: Visibility.Collapsed;
HoldingsPage.Visibility = _allowActual && requisitionItem.SourceJRI.ID == Guid.Empty ? Visibility.Visible : Visibility.Collapsed;
InstancesPage.Visibility = _allowActual ? Visibility.Collapsed : Visibility.Visible;
BOMPage.Visibility = _allowActual
? Visibility.Collapsed
: Visibility.Visible;
RequisitionPage.Visibility = _allowActual
? Visibility.Collapsed
: Visibility.Visible;
TabControl.SelectedItem = requisitionItem.EditType == RequisitionItemEditType.Normal
? _allowActual
? requisitionItem.Product.ID != Guid.Empty
? AllocationsPage
: HoldingsPage
: requisitionItem.JobRequisitionItem.ID == Guid.Empty
? BOMPage
: RequisitionPage
: CustomPage;
CanSave = false;
UpdateState();
}
private void UpdateState()
{
if (TabControl.SelectedTab == AllocationsPage)
{
if (!_loadedAllocations)
{
LoadAllocations();
_loadedAllocations = true;
}
}
else if(TabControl.SelectedTab == HoldingsPage)
{
if (!_loadedStockHoldings)
{
LoadStockHoldings();
_loadedStockHoldings = true;
}
}
else if(TabControl.SelectedTab == BOMPage)
{
if (!_loadedBOMItems)
{
LoadBOMItems();
_loadedBOMItems = true;
}
}
else if(TabControl.SelectedTab == RequisitionPage)
{
if (!_loadedJobRequisitionItems)
{
LoadJobRequisitionItems();
_loadedJobRequisitionItems = true;
}
}
else if(TabControl.SelectedTab == InstancesPage)
{
if (!_loadedProductInstances)
{
LoadProductInstances();
_loadedProductInstances = true;
}
}
else if (TabControl.SelectedTab == CustomPage)
{
if (!_loadedCustom)
{
LoadCustom();
_loadedCustom = true;
}
}
CheckCanSave();
}
private void CheckCanSave()
{
if (TabControl.SelectedTab == AllocationsPage)
CanSave = CanSaveAllocations();
else if (TabControl.SelectedTab == HoldingsPage)
CanSave = CanSaveStockHoldings();
else if (TabControl.SelectedTab == BOMPage)
CanSave = CanSaveBOMItems();
else if (TabControl.SelectedTab == RequisitionPage)
CanSave = CanSaveJobRequisitionItems();
else if (TabControl.SelectedTab == InstancesPage)
CanSave = CanSaveProductInstances();
else if (TabControl.SelectedTab == CustomPage)
CanSave = true;
}
private void DoSave()
{
if (TabControl.SelectedTab == AllocationsPage)
SaveAllocations();
else if (TabControl.SelectedTab == HoldingsPage)
SaveStockHoldings();
else if (TabControl.SelectedTab == BOMPage)
SaveBOMItems();
else if (TabControl.SelectedTab == RequisitionPage)
SaveJobRequisitionItems();
else if (TabControl.SelectedTab == InstancesPage)
SaveProductInstances();
else if (TabControl.SelectedTab == CustomPage)
SaveCustom();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
DoSave();
DialogResult = true;
Close();
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
Item.CancelChanges();
DialogResult = false;
Close();
}
private void TabChanged(object sender, SelectionChangedEventArgs e)
{
if (e.OriginalSource == sender)
UpdateState();
}
#region Allocations
private IEnumerable CreateStockSelectionItems(IEnumerable> groups, Func description)
{
var _result = new List();
foreach (var _group in groups)
{
var _units = _group.Sum(x => x.Units);
if (!_units.IsEffectivelyEqual(0.0))
{
var _holding = new StockHolding();
_holding.Location.ID = _group.Key;
_holding.Location.Synchronise(_group.FirstOrDefault()?.Location ?? new StockLocationLink());
_holding.Product.ID = Item.Product.ID;
_holding.Product.Synchronise(Item.Product);
_holding.Style.ID = Item.Style.ID;
_holding.Style.Synchronise(Item.Style);
_holding.Dimensions.CopyFrom(Item.Dimensions);
_holding.Location.Area.Code = description(_group.FirstOrDefault() ?? new StockMovement());
_holding.Units = _units;
var _jri = new JobRequisitionItem()
{
ID = _group.FirstOrDefault()?.JobRequisitionItem.ID ?? Guid.Empty
};
_result.Add(new StockSelectionItem() { Holding = _holding, MaxValue = Item.Quantity, JRI = _jri });
}
}
return _result;
}
private void LoadAllocations()
{
var movements = Client.Query(
new Filter(x=>x.Product.ID).IsEqualTo(Item.Product.ID)
.And(x=>x.Style.ID).IsEqualTo(Item.Style.ID)
.And(x=>x.Dimensions).DimensionEquals(Item.Dimensions)
.And(
new Filter(x => x.JobRequisitionItem.ID).IsEqualTo(Item.SourceJRI.ID)
.Or(new Filter(x => x.Job.ID).IsEqualTo(Item.RequisitionLink.JobLink.ID)
.And(x => x.JobRequisitionItem.ID).IsEqualTo(Guid.Empty))
.Or(new Filter(x => x.Job.ID).IsEqualTo(Guid.Empty)
.And(x => x.JobRequisitionItem.ID).IsEqualTo(Guid.Empty))
),
Columns.None()
.Add(x => x.Location.ID)
.Add(x => x.Location.Code)
.Add(x => x.Location.Description)
.Add(x => x.Job.ID)
.Add(x=>x.Job.JobNumber)
.Add(x=>x.Job.Name)
.Add(x => x.JobRequisitionItem.ID)
.Add(x=>x.JobRequisitionItem.Requisition.Number)
.Add(x=>x.JobRequisitionItem.Requisition.Description)
.Add(x => x.Units)
).Rows.Select(x=>x.ToObject()).ToArray();
List items = new();
var allocations = movements.Where(x => x.JobRequisitionItem.ID == Item.SourceJRI.ID)
.GroupBy(x => x.Location.ID);
items.AddRange(
CreateStockSelectionItems(
allocations,
(m) => $"{m.Job.JobNumber}:{m.JobRequisitionItem.Requisition.Number} {m.JobRequisitionItem.Requisition.Description}"
)
);
// if the pickinglist does not have a job, skip this bit
var reserves = movements.Where(x =>
x.JobRequisitionItem.ID != Guid.Empty && x.Job.ID == Item.RequisitionLink.JobLink.ID &&
x.JobRequisitionItem.ID == Guid.Empty)
.GroupBy(x => x.Location.ID);
items.AddRange(
CreateStockSelectionItems(
reserves,
(m) => $"{m.Job.JobNumber} (Unallocated Stock)"
)
);
var freeitems = movements.Where(x => x.Job.ID == Guid.Empty && x.JobRequisitionItem.ID == Guid.Empty)
.GroupBy(x => x.Location.ID);
items.AddRange(
CreateStockSelectionItems(
freeitems,
(m) => $"General Stock"
)
);
Allocations.Items = items;
Allocations.Refresh(true,true);
}
private void Allocations_OnAfterRefresh(object sender, AfterRefreshEventArgs args)
{
UpdateMaximums();
}
private void UpdateMaximums()
{
foreach (var item in Allocations.Items)
item.MaxValue = Item.Quantity + item.Issued - Allocations.Items.Sum(x=>x.Issued);
}
private void Allocations_OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
UpdateMaximums();
CheckCanSave();
}
private bool CanSaveAllocations()
{
return Allocations.Items.Sum(x=>x.Issued).IsEffectivelyGreaterThan(0.0);
}
private RequisitionItem CopyRequisitionItem()
{
var newItem = new RequisitionItem();
newItem.Done = Item.Done;
newItem.Image.CopyFrom(Item.Image);
newItem.RequisitionLink.ID = Item.RequisitionLink.ID;
newItem.SourceJRI.ID = Item.SourceJRI.ID;
newItem.Product.CopyFrom(Item.Product);
newItem.Style.CopyFrom(Item.Style);
newItem.Location.CopyFrom(Item.Location);
newItem.JobRequisitionItem.ID = Item.JobRequisitionItem.ID;
newItem.Dimensions.CopyFrom(Item.Dimensions, true);
newItem.JobLink.CopyFrom(Item.JobLink);
newItem.Description = Item.Description;
newItem.Quantity = Item.Quantity;
newItem.EditType = RequisitionItemEditType.Normal;
return newItem;
}
private void SaveAllocations()
{
var remainder = Item.Quantity;
var newItems = new List();
foreach(var item in Allocations.Items.Where(x=>!x.Issued.IsEffectivelyEqual(0.0)))
{
var newItem = newItems.Count == 0 ? Item : CopyRequisitionItem();
newItem.Location.CopyFrom(item.Holding.Location);
newItem.JobRequisitionItem.CopyFrom(item.JRI);
newItem.JobLink.CopyFrom(item.Holding.Job);
// Automagically attach to Requisition if it seems appropriate
// ie selected from a JRI allocation, and current source jri is blank
if (newItem.SourceJRI.ID == Guid.Empty
&& newItem.RequisitionLink.JobLink.ID == item.Holding.Job.ID
&& item.JRI.ID != Guid.Empty)
newItem.SourceJRI.ID = item.JRI.ID;
newItem.Quantity = item.Issued;
newItem.ActualQuantity = item.Issued;
newItem.Done = true;
remainder -= item.Issued;
newItems.Add(newItem);
}
if(!remainder.IsEffectivelyEqual(0.0))
{
var newItem = CopyRequisitionItem();
newItem.Location.CopyFrom(new StockLocationLink());
newItem.JobRequisitionItem.CopyFrom(new JobRequisitionItemLink());
newItem.JobLink.CopyFrom(new JobLink());
newItem.Quantity = remainder;
newItem.Done = false;
newItems.Add(newItem);
}
Client.Save(newItems, "Updated from RequisitionItemEditor(Allocations)");
Result = newItems.ToArray();
}
#endregion
#region StockHoldings
private void LoadStockHoldings()
{
StockHoldingProducts.Refresh(true, true);
foreach(var column in StockHolding.Columns)
{
StockHoldings.HiddenColumns.Add(column);
}
foreach(var column in Columns.None()
.AddSubColumns(x => x.Product, LookupFactory.DefineLookupColumns(x => x.Product).CastIntersection())
.AddSubColumns(x => x.Style, LookupFactory.DefineLookupColumns(x => x.Style).CastIntersection())
.AddSubColumns(x => x.Location, LookupFactory.DefineLookupColumns(x => x.Location).CastIntersection())
.AddSubColumns(x => x.Job, LookupFactory.DefineLookupColumns(x => x.JobLink).CastIntersection())
)
{
StockHoldings.HiddenColumns.Add(column);
}
StockHoldings.HiddenColumns.Add(x => x.Available);
StockHoldings.Refresh(true, false);
if(Item.Product.ID != Guid.Empty)
{
// Delaying, cause otherwise it doesn't work.
Dispatcher.BeginInvoke(() =>
{
StockHoldingProducts.SelectedRows = StockHoldingProducts.Data.Rows.Where(x => x.Get(x => x.ID) == Item.Product.ID).ToArray();
StockHoldingProducts.ScrollIntoView(StockHoldingProducts.SelectedRows[0]);
});
}
}
private void StockHoldingProducts_OnSelectItem(object sender, InABox.DynamicGrid.DynamicGridSelectionEventArgs e)
{
StockHoldings.Product = e.Rows is not null && e.Rows.Length > 0 ? e.Rows[0].ToObject() : null;
StockHoldings.Refresh(false, true);
CheckCanSave();
}
private void StockHoldings_OnAfterRefresh(object sender, AfterRefreshEventArgs args)
{
var row = StockHoldings.Data.Rows.FirstOrDefault();
if (row != null)
{
StockHoldings.SelectedRows = new CoreRow[] { row };
SelectHolding(new CoreRow[] { row });
}
}
private void StockHoldings_OnSelectItem(object sender, InABox.DynamicGrid.DynamicGridSelectionEventArgs e)
{
SelectHolding(e.Rows);
}
private void SelectHolding(CoreRow[]? rows)
{
StockHolding = rows?.FirstOrDefault()?.ToObject();
RefreshJobRequisitionItems();
JRIRow.Height = _allowActual && StockHolding is not null ? new GridLength(1, GridUnitType.Star) : new GridLength(0);
TotalRow.Height = _allowActual && StockHolding is not null ? new GridLength(40) : new GridLength(0);
RequiredEditor.SetValue(Grid.ColumnProperty, _allowActual && StockHolding is not null ? 4 : 6);
CheckCanSave();
}
private bool CanSaveStockHoldings()
{
return StockHolding is not null && TotalTaken > 0;
}
private void SaveStockHoldings()
{
if (StockHolding is null) return;
var items = JRIItems.Where(x => x.Taken > 0).ToArray();
if (items.Length == 0) return;
Item.Product.CopyFrom(StockHolding.Product);
Item.Style.CopyFrom(StockHolding.Style);
Item.Location.CopyFrom(StockHolding.Location);
Item.Dimensions.CopyFrom(StockHolding.Dimensions, true);
Item.JobLink.CopyFrom(StockHolding.Job);
Item.EditType = RequisitionItemEditType.Normal;
var remainder = Item.Quantity;
var newItems = new List();
foreach(var item in items)
{
RequisitionItem newItem;
if(newItems.Count == 0)
{
newItem = Item;
}
else
{
newItem = new RequisitionItem();
newItem.Done = Item.Done;
newItem.Description = Item.Description;
newItem.Image.CopyFrom(Item.Image);
newItem.RequisitionLink.ID = Item.RequisitionLink.ID;
newItem.JobRequisitionItem.ID = item.ID;
newItem.Product.CopyFrom(Item.Product);
newItem.Style.CopyFrom(Item.Style);
newItem.Location.CopyFrom(Item.Location);
newItem.Dimensions.CopyFrom(Item.Dimensions, true);
newItem.JobLink.CopyFrom(Item.JobLink);
newItem.EditType = RequisitionItemEditType.Normal;
}
newItem.JobRequisitionItem.ID = item.ID;
newItem.Quantity = item.Taken;
newItem.ActualQuantity = item.Taken;
remainder -= item.Taken;
newItems.Add(newItem);
}
if(remainder > 0)
{
var newItem = new RequisitionItem();
newItem.Done = false;
newItem.Description = Item.Description;
newItem.Image.CopyFrom(Item.Image);
newItem.RequisitionLink.ID = Item.RequisitionLink.ID;
newItem.JobRequisitionItem.ID = Guid.Empty;
newItem.Product.CopyFrom(Item.Product);
newItem.Style.CopyFrom(Item.Style);
newItem.Dimensions.CopyFrom(Item.Dimensions, true);
newItem.Quantity = remainder;
newItems.Add(newItem);
}
Client.Save(newItems, "Edited by user.");
Result = newItems.ToArray();
}
#region JobRequisitionItem Selection
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private bool _observing = false;
public void SetObserving(bool observing)
{
if(_observing != observing)
{
_observing = observing;
if (_observing)
{
Recalculate();
}
}
}
private StockHolding? StockHolding;
private List _jriItems;
public List JRIItems
{
get => _jriItems;
set
{
_jriItems = value;
OnPropertyChanged();
}
}
private void RefreshJobRequisitionItems()
{
SetObserving(false);
if(StockHolding is null)
{
JRIItems = [];
}
else
{
var jris = StockHolding.LoadRequisitionItems(true);
JRIItems = jris.Select(x =>
{
var newItem = new RequisitionItemStockHoldingItem
{
Quantity = x.Qty,
Taken = 0,
ID = x.ID,
Text = x.ID == Guid.Empty
? "General Stock"
: $"{x.Job.JobNumber}:{x.Requisition.Number} {x.Requisition.Description} ({x.Qty})",
};
newItem.PropertyChanged += (o, e) => Recalculate();
return newItem;
}).ToList();
}
SetObserving(true);
}
private void Recalculate()
{
if (!_observing) return;
TotalTaken = JRIItems.Sum(x => x.Taken);
}
private double _totalTaken;
public double TotalTaken
{
get => _totalTaken;
set
{
_totalTaken = value;
OnPropertyChanged();
CheckCanSave();
}
}
public double RequiredQuantity
{
get => Item.Quantity;
set
{
Item.Quantity = value;
CheckCanSave();
OnPropertyChanged();
}
}
private void None_Click(object sender, RoutedEventArgs e)
{
if (sender is not FrameworkElement element || element.Tag is not RequisitionItemStockHoldingItem item) return;
item.Taken = 0;
}
private void Minus_Click(object sender, RoutedEventArgs e)
{
if (sender is not FrameworkElement element || element.Tag is not RequisitionItemStockHoldingItem item) return;
item.Taken = Math.Max(0, item.Taken - 1);
}
private void Plus_Click(object sender, RoutedEventArgs e)
{
if (sender is not FrameworkElement element || element.Tag is not RequisitionItemStockHoldingItem item) return;
item.Taken = Math.Min(item.Taken + 1, item.Quantity);
}
private void All_Click(object sender, RoutedEventArgs e)
{
if (sender is not FrameworkElement element || element.Tag is not RequisitionItemStockHoldingItem item) return;
item.Taken = Math.Min(Math.Max(RequiredQuantity - (TotalTaken - item.Taken), 0), item.Quantity);
}
#endregion
#endregion
#region BOM Items
private void LoadBOMItems()
{
BOMItems.Refresh(true,true);
}
private bool CanSaveBOMItems()
{
return BOMItems.Data.Rows.Any(r =>!r.Get(x=>x.Quantity).IsEffectivelyEqual(0.0));
}
private void SaveBOMItems()
{
var result = new List() { Item };
var bomItems = BOMItems.Data.Rows
.Where(r => !r.Get(x => x.Quantity).IsEffectivelyEqual(0.0))
.Select(r => r.ToObject()).ToArray();
var first = bomItems.FirstOrDefault();
if (first is null)
return;
Item.Product.CopyFrom(first.Product);
Item.Style.CopyFrom(first.Style);
Item.Dimensions.CopyFrom(first.Dimensions, true);
Item.EditType = RequisitionItemEditType.Normal;
Item.Quantity = first.Quantity;
foreach (var item in bomItems.Skip(1).ToArray())
{
var newItem = new RequisitionItem();
newItem.RequisitionLink.ID = Item.RequisitionLink.ID;
newItem.Done = false;
newItem.Description = item.Product.Name;
newItem.Product.CopyFrom(item.Product);
newItem.Style.CopyFrom(item.Style);
newItem.Dimensions.CopyFrom(item.Dimensions, true);
newItem.EditType = RequisitionItemEditType.Normal;
newItem.Quantity = item.Quantity;
result.Add(newItem);
}
Client.Save(result, "Edited by user.");
Result = result.ToArray();
}
private void BOMItems_OnOnChanged(object? sender, EventArgs e)
{
CheckCanSave();
}
#endregion
#region Job Requisition Items
private void LoadJobRequisitionItems()
{
JobRequisitionItemsGrid.Refresh(true,true);
}
private bool CanSaveJobRequisitionItems()
{
return JobRequisitionItemsGrid.Data.Rows.Any(r =>!r.Get(x=>x.Quantity).IsEffectivelyEqual(0.0));
}
private void SaveJobRequisitionItems()
{
var result = new List() { Item };
var items = JobRequisitionItemsGrid.Data.Rows
.Where(r => !r.Get(x => x.Quantity).IsEffectivelyEqual(0.0))
.Select(r => r.ToObject()).ToArray();
var first = items.FirstOrDefault();
if (first is null)
return;
Item.Product.CopyFrom(first.JRI.Product);
Item.Style.CopyFrom(first.JRI.Style);
Item.Dimensions.CopyFrom(first.JRI.Dimensions, true);
Item.JobRequisitionItem.CopyFrom(first.JRI);
Item.EditType = RequisitionItemEditType.Normal;
Item.Quantity = first.Quantity;
foreach (var item in items.Skip(1).ToArray())
{
var newItem = new RequisitionItem();
newItem.RequisitionLink.ID = Item.RequisitionLink.ID;
newItem.Done = false;
newItem.Description = item.JRI.Product.Name;
newItem.Product.CopyFrom(item.JRI.Product);
newItem.Style.CopyFrom(item.JRI.Style);
newItem.Dimensions.CopyFrom(item.JRI.Dimensions, true);
newItem.JobRequisitionItem.CopyFrom(item.JRI);
newItem.EditType = RequisitionItemEditType.Normal;
newItem.Quantity = item.Quantity;
result.Add(newItem);
}
Client.Save(result, "Edited by user.");
Result = result.ToArray();
}
private void JobRequisitionItems_OnOnChanged(object? sender, EventArgs e)
{
CheckCanSave();
}
#endregion
#region Product Instances
private ProductInstance? SelectedProductInstance;
private void LoadProductInstances()
{
ProductInstancesProducts.Refresh(true, true);
ProductInstances.Refresh(true, false);
foreach(var column in Columns.None().Add(x => x.Style.ID).AddDimensionsColumns(x => x.Dimensions))
{
ProductInstances.HiddenColumns.Add(column);
}
if(Item.Product.ID != Guid.Empty)
{
// Delaying, cause otherwise it doesn't work.
Dispatcher.BeginInvoke(() =>
{
ProductInstancesProducts.SelectedRows = ProductInstancesProducts.Data.Rows.Where(x => x.Get(x => x.ID) == Item.Product.ID).ToArray();
if (ProductInstancesProducts.SelectedRows.Any())
ProductInstancesProducts.ScrollIntoView(ProductInstancesProducts.SelectedRows[0]);
});
}
}
private bool CanSaveProductInstances()
{
return ProductInstances.Product is not null && SelectedProductInstance is not null && RequiredQuantity > 0;
}
private void SaveProductInstances()
{
if (ProductInstances.Product is null || SelectedProductInstance is null) return;
Item.Product.CopyFrom(ProductInstances.Product);
Item.Style.CopyFrom(SelectedProductInstance.Style);
Item.Dimensions.CopyFrom(SelectedProductInstance.Dimensions, true);
Item.Location.ID = Guid.Empty;
Item.EditType = RequisitionItemEditType.Normal;
Client.Save(Item, "Edited by user.");
Result = [Item];
}
private void ProductInstancesProducts_OnSelectItem(object sender, InABox.DynamicGrid.DynamicGridSelectionEventArgs e)
{
ProductInstances.Product = e.Rows is not null && e.Rows.Length > 0 ? e.Rows[0].ToObject() : null;
ProductInstances.Refresh(false, true);
CheckCanSave();
}
private void ProductInstances_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
{
SelectedProductInstance = e.Rows is not null && e.Rows.Length > 0 ? e.Rows[0].ToObject() : null;
CheckCanSave();
}
#endregion
#region Custom
private void LoadCustom()
{
CustomEditorGrid.Setup(typeof(RequisitionItem));
CustomEditorGrid.Items = new RequisitionItem[] { Item };
}
private static readonly Columns ActualCustomColumns = Columns.None()
.Add(x => x.Product.ID)
.Add(x => x.Style.ID)
.Add(x => x.Dimensions)
.Add(x => x.Description)
.Add(x => x.Location.ID)
.Add(x => x.Quantity)
.Add(x => x.ActualQuantity);
private static readonly Columns RequstedCustomColumns = Columns.None()
.Add(x => x.Product.ID)
.Add(x => x.Style.ID)
.Add(x => x.Dimensions)
.Add(x => x.Description)
.Add(x => x.Location.ID)
.Add(x => x.Quantity)
.Add(x => x.ActualQuantity);
// private static readonly Columns ProductInstanceCustomColumns = new Columns()
// .Add(x => x.Product.ID)
// .Add(x => x.Style.ID)
// .Add(x => x.Dimensions)
// .Add(x => x.Description)
// .Add(x => x.Quantity);
private void CustomEditorGrid_OnFormCustomiseEditor(IDynamicEditorForm sender, object items, DynamicGridColumn column, BaseEditor editor)
{
var columns = _allowActual ? ActualCustomColumns : RequstedCustomColumns;
editor.Editable = columns.Contains(column.ColumnName)
? Editable.Enabled
: Editable.Hidden;
}
/*
private void LoadCustom()
{
var host = new DefaultDynamicEditorHost
{
Items = [Item]
};
var editors = new Dictionary();
BaseDynamicEditorControl? CreateControl(Expression> exp, int row)
{
var property = DatabaseSchema.Property(exp)!;
BaseEditor? editor;
if (property.HasParentEditor())
{
property = property.GetParentWithEditor();
}
if (property is null) return null;
editor = property.Editor;
editor = editor.CloneEditor();
var control = DynamicEditorControlFactory.CreateControl(editor, host)!;
Grid.SetRow(control, row);
Grid.SetColumn(control, 1);
control.Margin = new Thickness(5, 2.5, 5, 2.5);
CustomEditorGrid.Children.Add(control);
editors[property.Name] = control;
control.IsEnabled = true;
control.ColumnName = property.Name;
control.Color = editor is UniqueCodeEditor ? Color.FromArgb(0xFF, 0xF6, 0xC9, 0xE8) : Colors.LightYellow;
control.Configure();
control.Loaded = true;
foreach(var (k, v) in control.GetValues())
{
var value = DatabaseSchema.Property(typeof(RequisitionItem), k)!.Getter()(Item);
if(!Equals(v, value))
{
bool bLoaded = control.Loaded;
control.Loaded = false;
control.SetValue(k, value);
control.Loaded = bLoaded;
}
}
control.OnEditorValueChanged += (sender, values) =>
{
var changededitors = new Dictionary();
void ExtractChanged(Dictionary? columns)
{
if (columns != null)
foreach (var (change, value) in columns)
if (!changededitors.ContainsKey(change) && !change.Equals(sender.ColumnName))
changededitors[change] = value;
}
var name = sender.ColumnName;
var resetAll = false;
if(values.Remove(name, out var value))
{
var changedcolumns = DynamicGridUtils.UpdateEditorValue([Item], sender.ColumnName, value);
resetAll = changedcolumns?.ContainsKey(name) ?? false;
ExtractChanged(changedcolumns);
}
foreach(var (k, v) in values)
{
var changes = new Dictionary();
if (resetAll)
{
var prop = DatabaseSchema.Property(typeof(RequisitionItem), k);
if(prop is not null)
{
var def = CoreUtils.GetDefault(prop.PropertyType);
var resetChanges = DynamicGridUtils.UpdateEditorValue([Item], k, def);
if(resetChanges is not null)
{
changes = resetChanges;
}
}
else
{
}
}
var changedOtherColumns = DynamicGridUtils.UpdateEditorValue([Item], k, v);
if(changedOtherColumns is not null)
{
foreach (var (k1, v1) in changedOtherColumns)
{
changes[k1] = v1;
}
}
ExtractChanged(changes);
}
if (changededitors.Count != 0)
{
foreach(var (k, v) in changededitors)
{
var editor = editors.GetValueOrDefault(k) ?? editors.FirstOrDefault(x => k.StartsWith(x.Key + ".")).Value;
if(editor is not null)
{
editor.Loaded = false;
editor.SetValue(k, v);
editor.Loaded = true;
}
}
}
};
return control;
}
var productEditor = CreateControl(x => x.Product.ID, 0);
var styleEditor = CreateControl(x => x.Style.ID, 1);
var dimensionsEditor = CreateControl(x => x.Dimensions.Quantity, 2);
var descriptionEditor = CreateControl(x => x.Description, 3);
var locationEditor = CreateControl(x => x.Location.ID, 4);
var quantityEditor = CreateControl(x => x.Quantity, 5);
}
*/
private void SaveCustom()
{
Item.EditType = RequisitionItemEditType.Custom;
Client.Save(Item, "Custom edited by user.");
Result = [Item];
}
#endregion
}