1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003 |
- 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;
- /// <summary>
- /// Interaction logic for RequisitionItemEditor.xaml
- /// </summary>
- 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<List<Product>> 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<StockSelectionItem> CreateStockSelectionItems(IEnumerable<IGrouping<Guid, StockMovement>> groups, Func<StockMovement,string> description)
- {
-
- var _result = new List<StockSelectionItem>();
- 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<StockMovement>(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<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(Item.SourceJRI.ID)
- .Or(new Filter<StockMovement>(x => x.Job.ID).IsEqualTo(Item.RequisitionLink.JobLink.ID)
- .And(x => x.JobRequisitionItem.ID).IsEqualTo(Guid.Empty))
- .Or(new Filter<StockMovement>(x => x.Job.ID).IsEqualTo(Guid.Empty)
- .And(x => x.JobRequisitionItem.ID).IsEqualTo(Guid.Empty))
- ),
- Columns.None<StockMovement>()
- .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<StockMovement>()).ToArray();
-
- List<StockSelectionItem> 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<RequisitionItem>();
-
- 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<StockHolding>()
- .AddSubColumns(x => x.Product, LookupFactory.DefineLookupColumns<RequisitionItem, Product, ProductLink>(x => x.Product).CastIntersection<ProductLink>())
- .AddSubColumns(x => x.Style, LookupFactory.DefineLookupColumns<RequisitionItem, ProductStyle, ProductStyleLink>(x => x.Style).CastIntersection<ProductStyleLink>())
- .AddSubColumns(x => x.Location, LookupFactory.DefineLookupColumns<RequisitionItem, StockLocation, StockLocationLink>(x => x.Location).CastIntersection<StockLocationLink>())
- .AddSubColumns(x => x.Job, LookupFactory.DefineLookupColumns<RequisitionItem, Job, JobLink>(x => x.JobLink).CastIntersection<JobLink>())
- )
- {
- 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<Product, Guid>(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<Product>() : 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<StockHolding>();
- 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<RequisitionItem>();
- 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<RequisitionItemStockHoldingItem> _jriItems;
- public List<RequisitionItemStockHoldingItem> 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<JobBOMSummary,double>(x=>x.Quantity).IsEffectivelyEqual(0.0));
- }
- private void SaveBOMItems()
- {
- var result = new List<RequisitionItem>() { Item };
-
- var bomItems = BOMItems.Data.Rows
- .Where(r => !r.Get<JobBOMSummary, double>(x => x.Quantity).IsEffectivelyEqual(0.0))
- .Select(r => r.ToObject<JobBOMSummary>()).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<JobJRISummary,double>(x=>x.Quantity).IsEffectivelyEqual(0.0));
- }
- private void SaveJobRequisitionItems()
- {
- var result = new List<RequisitionItem>() { Item };
-
- var items = JobRequisitionItemsGrid.Data.Rows
- .Where(r => !r.Get<JobJRISummary, double>(x => x.Quantity).IsEffectivelyEqual(0.0))
- .Select(r => r.ToObject<JobJRISummary>()).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<ProductInstance>().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<Product, Guid>(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<Product>() : 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<ProductInstance>() : null;
- CheckCanSave();
- }
- #endregion
- #region Custom
- private void LoadCustom()
- {
- CustomEditorGrid.Setup(typeof(RequisitionItem));
- CustomEditorGrid.Items = new RequisitionItem[] { Item };
- }
- private static readonly Columns<RequisitionItem> ActualCustomColumns = Columns.None<RequisitionItem>()
- .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<RequisitionItem> RequstedCustomColumns = Columns.None<RequisitionItem>()
- .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<RequisitionItem> ProductInstanceCustomColumns = new Columns<RequisitionItem>()
- // .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<RequisitionItem>
- {
- Items = [Item]
- };
- var editors = new Dictionary<string, IDynamicEditorControl>();
- BaseDynamicEditorControl? CreateControl(Expression<Func<RequisitionItem, object?>> 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<string, object?>();
- void ExtractChanged(Dictionary<string, object?>? 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<string, object?>();
- 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
- }
|