|
@@ -5,63 +5,328 @@ using InABox.DynamicGrid;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
-using System.Windows;
|
|
|
using System.Windows.Controls;
|
|
|
-using System.Windows.Data;
|
|
|
-using System.Windows.Documents;
|
|
|
-using System.Windows.Input;
|
|
|
-using System.Windows.Media;
|
|
|
-using System.Windows.Media.Imaging;
|
|
|
-using System.Windows.Navigation;
|
|
|
-using System.Windows.Shapes;
|
|
|
|
|
|
namespace PRSDesktop
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// Interaction logic for JobRequisitionPurchasing.xaml
|
|
|
/// </summary>
|
|
|
- public partial class JobRequisitionPurchasing : UserControl
|
|
|
+ public partial class JobRequisitionPurchasing : UserControl, IBasePanel, IDynamicEditorHost
|
|
|
{
|
|
|
- private List<JobRequisitionItem> jobRequiItems;
|
|
|
- public List<JobRequisitionItem> JobRequiItems
|
|
|
+ public delegate void PurchaseOrderSaved();
|
|
|
+ public event PurchaseOrderSaved OnPurchaseOrderSaved;
|
|
|
+
|
|
|
+ public List<JobRequisitionItem> JobRequiItems;
|
|
|
+
|
|
|
+ public event DataModelUpdateEvent? OnUpdateDataModel;
|
|
|
+
|
|
|
+ public PurchaseOrder Order { get; set; } = new PurchaseOrder();
|
|
|
+
|
|
|
+ bool bLoaded = false;
|
|
|
+ public void LoadFromRequiLine()
|
|
|
+ {
|
|
|
+ if (bLoaded)
|
|
|
+ return;
|
|
|
+
|
|
|
+ var poid = JobRequiItems[0].PurchaseOrderItem.PurchaseOrderLink.ID;
|
|
|
+ if (poid != Guid.Empty && poid != Order.ID)
|
|
|
+ LoadPO(poid);
|
|
|
+ else if (poid == Guid.Empty)
|
|
|
+ ClearEditor();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadPO(Guid poid)
|
|
|
{
|
|
|
- get => jobRequiItems;
|
|
|
- set
|
|
|
+ var po = new Client<PurchaseOrder>().Query(
|
|
|
+ new Filter<PurchaseOrder>(x => x.ID).IsEqualTo(poid),
|
|
|
+ new Columns<PurchaseOrder>
|
|
|
+ (
|
|
|
+ x => x.ID,
|
|
|
+ x => x.SupplierLink.ID,
|
|
|
+ x => x.SupplierLink.Code,
|
|
|
+ x => x.SupplierLink.Name,
|
|
|
+ x => x.Notes,
|
|
|
+ x => x.Category.ID,
|
|
|
+ x => x.Category.Code,
|
|
|
+ x => x.Category.Description,
|
|
|
+ x => x.RaisedBy.ID,
|
|
|
+ x => x.RaisedBy.Code,
|
|
|
+ x => x.RaisedBy.Name,
|
|
|
+ x => x.DueDate,
|
|
|
+ x => x.IssuedBy.ID,
|
|
|
+ x => x.IssuedBy.Code,
|
|
|
+ x => x.IssuedBy.Name,
|
|
|
+ x => x.IssuedDate,
|
|
|
+ x => x.ClosedDate,
|
|
|
+ x => x.PONumber
|
|
|
+ ))
|
|
|
+ .Rows.FirstOrDefault().ToObject<PurchaseOrder>();
|
|
|
+ if (po != null)
|
|
|
{
|
|
|
- jobRequiItems = value;
|
|
|
- if (jobRequiItems.First().PurchaseOrderItem.ID != Guid.Empty)
|
|
|
- LoadOrder(new Client<PurchaseOrder>().Query(new Filter<PurchaseOrder>(x => x.ID).IsEqualTo(jobRequiItems.First().PurchaseOrderItem.PurchaseOrderLink.ID)).Rows.First());
|
|
|
+ Order = po;
|
|
|
+ CreatePOEditor(new BaseObject[] { po });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public IEnumerable<DynamicGridColumn> Columns => throw new NotImplementedException();
|
|
|
+
|
|
|
+ public bool IsReady { get; set; }
|
|
|
+
|
|
|
+ public string SectionName { get; set; }
|
|
|
+
|
|
|
public JobRequisitionPurchasing()
|
|
|
{
|
|
|
InitializeComponent();
|
|
|
+ empName = new Client<Employee>().Query(new Filter<Employee>(x => x.UserLink.ID).IsEqualTo(ClientFactory.UserGuid)).Rows.FirstOrDefault().Get<Employee, string>(x => x.Name);
|
|
|
+ CreatePOEditor();
|
|
|
//JobRequiItems = new List<JobRequisitionItem>();
|
|
|
- Items.Options.Remove(DynamicGridOption.ImportData);
|
|
|
- Items.Options.Remove(DynamicGridOption.ExportData);
|
|
|
}
|
|
|
- private void LoadOrder(CoreRow row)
|
|
|
+
|
|
|
+ private string CheckDate(DateTime date)
|
|
|
{
|
|
|
- Number.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.PONumber);
|
|
|
+ return date.IsEmpty() ? "" : date.ToShortDateString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool EditorChanged = false;
|
|
|
+ private string empName = "";
|
|
|
|
|
|
- SupplierCode.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.SupplierLink.Code);
|
|
|
- SupplierName.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.SupplierLink.Name);
|
|
|
+ private void CreatePOEditor(BaseObject[]? items = null)
|
|
|
+ {
|
|
|
+ DetailBorder.Child = null;
|
|
|
|
|
|
- Description.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.Notes);
|
|
|
+ Editor = new EmbeddedDynamicEditorForm();
|
|
|
+ Editor.SetLayoutType<VerticalDynamicEditorGridLayout>();
|
|
|
+ Editor.SetValue(Grid.RowProperty, 1);
|
|
|
+ Editor.SetValue(Grid.ColumnProperty, 0);
|
|
|
+ Editor.SetValue(Grid.ColumnSpanProperty, 4);
|
|
|
+
|
|
|
+ EditorChanged = false;
|
|
|
|
|
|
- Issued.Text = row == null ? "" : CheckDate(row.Get<PurchaseOrder, DateTime>(x => x.IssuedDate));
|
|
|
- IssuedBy.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.IssuedBy.Name);
|
|
|
+ Editor.OnAfterEditorValueChanged += (sender, column) =>
|
|
|
+ {
|
|
|
+ EditorChanged = true;
|
|
|
+ return null;
|
|
|
+ };
|
|
|
+
|
|
|
+ Editor.OnOK += () =>
|
|
|
+ {
|
|
|
+ var cancel = new System.ComponentModel.CancelEventArgs();
|
|
|
+ Editor.SaveItem(cancel);
|
|
|
+ UpdateJobRequiItems();
|
|
|
+ OnPurchaseOrderSaved?.Invoke();
|
|
|
+ bLoaded = false;
|
|
|
+ };
|
|
|
+ Editor.OnCancel += () =>
|
|
|
+ {
|
|
|
+ bLoaded = false;
|
|
|
+ ClearEditor();
|
|
|
+ };
|
|
|
|
|
|
- DueDate.Text = row == null ? "" : CheckDate(row.Get<PurchaseOrder, DateTime>(x => x.DueDate));
|
|
|
- ClosedDate.Text = row == null ? "" : CheckDate(row.Get<PurchaseOrder, DateTime>(x => x.ClosedDate));
|
|
|
+ DetailBorder.Child = Editor;
|
|
|
+
|
|
|
+ var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(PurchaseOrder));
|
|
|
+ grid.InitialiseEditorForm(Editor, items ?? new object[] { Activator.CreateInstance(typeof(PurchaseOrder))! });
|
|
|
+
|
|
|
+ var loadPO = new Button
|
|
|
+ {
|
|
|
+ Content = "Load PO",
|
|
|
+ Height = 30,
|
|
|
+ Margin = new System.Windows.Thickness(2, 0, 0, 0),
|
|
|
+ Padding = new System.Windows.Thickness(15, 0, 15, 0)
|
|
|
+ };
|
|
|
+ loadPO.Click += LoadPO_Click;
|
|
|
+ Editor.AddButton(loadPO);
|
|
|
}
|
|
|
|
|
|
- private string CheckDate(DateTime date)
|
|
|
+ private void LoadPO_Click(object sender, System.Windows.RoutedEventArgs e)
|
|
|
{
|
|
|
- return date.IsEmpty() ? "" : date.ToShortDateString();
|
|
|
+ var popup = new PopupList(typeof(PurchaseOrder), Guid.Empty, new string[0]);
|
|
|
+ if(popup.ShowDialog() == true)
|
|
|
+ {
|
|
|
+ bLoaded = true;
|
|
|
+ LoadPO(popup.ID);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateJobRequiItems()
|
|
|
+ {
|
|
|
+ var page = Editor.Pages.Find(x => x.GetType() == typeof(SupplierPurchaseOrderItemOneToMany)) as SupplierPurchaseOrderItemOneToMany;
|
|
|
+ if (page.Items.Count != 0)
|
|
|
+ MatchRequiItems(page.Items);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void MatchRequiItems(List<PurchaseOrderItem> poItems)
|
|
|
+ {
|
|
|
+ List<JobRequisitionItem> toSave = new List<JobRequisitionItem>();
|
|
|
+ foreach (var JobReqItem in JobRequiItems)
|
|
|
+ {
|
|
|
+ if (JobReqItem.PurchaseOrderItem.ID == Guid.Empty)
|
|
|
+ foreach (var item in poItems)
|
|
|
+ if (MatchReqItemToPOItem(JobReqItem, item))
|
|
|
+ toSave.Add(UpdateJobReqItemWithPODetails(JobReqItem, item));
|
|
|
+ }
|
|
|
+ if (toSave.Count > 0)
|
|
|
+ new Client<JobRequisitionItem>().Save(toSave, "Updated from Job Requi Review Create Purchase Order");
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool MatchReqItemToPOItem(JobRequisitionItem JobReqItem, PurchaseOrderItem item)
|
|
|
+ {
|
|
|
+ if (JobReqItem.Product.ID == item.Product.ID &&
|
|
|
+ JobReqItem.Dimensions.UnitSize == item.Dimensions.UnitSize &&
|
|
|
+ JobReqItem.Requisition.Job.ID == item.Job.ID)
|
|
|
+ return true;
|
|
|
+ else
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private JobRequisitionItem UpdateJobReqItemWithPODetails(JobRequisitionItem JobReqItem, PurchaseOrderItem poItem)
|
|
|
+ {
|
|
|
+ JobReqItem.PurchaseOrderItem.ID = poItem.ID;
|
|
|
+ JobReqItem.PurchaseOrderItem.DueDate = poItem.DueDate;
|
|
|
+ if (JobReqItem.Status != JobRequisitionItemStatus.OnOrder)
|
|
|
+ {
|
|
|
+ JobReqItem.Notes = JobReqItem.Notes + Environment.NewLine + "Line marked as On Order by " + empName + " on " + DateTime.Now.ToString("dd MMM yy");
|
|
|
+ JobReqItem.Ordered = poItem.Created;
|
|
|
+ }
|
|
|
+ return JobReqItem;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ClearEditor()
|
|
|
+ {
|
|
|
+ Order = new PurchaseOrder();
|
|
|
+ CreatePOEditor();
|
|
|
+
|
|
|
+ //if (Popup is not null)
|
|
|
+ //{
|
|
|
+ // Popup.Value = Guid.Empty;
|
|
|
+ //}
|
|
|
+ }
|
|
|
+
|
|
|
+ public void DropItems(CoreRow[] rows)
|
|
|
+ {
|
|
|
+ var page = Editor.Pages.Find(x => x.GetType() == typeof(SupplierPurchaseOrderItemOneToMany)) as SupplierPurchaseOrderItemOneToMany;
|
|
|
+ if (page.Items.Count == 0)
|
|
|
+ page.LoadItems(CreatePOItemsFromRequiItems(rows).ToArray());
|
|
|
+ else
|
|
|
+ page.LoadItems(CombineItems(rows, page.Items));
|
|
|
+ }
|
|
|
+
|
|
|
+ private PurchaseOrderItem[] CombineItems(CoreRow[] selected, List<PurchaseOrderItem> existingItems)
|
|
|
+ {
|
|
|
+ List<PurchaseOrderItem> items = new List<PurchaseOrderItem>();
|
|
|
+ items.AddRange(existingItems);
|
|
|
+ items.AddRange(CreatePOItemsFromRequiItems(selected, existingItems));
|
|
|
+ return items.ToArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<PurchaseOrderItem> CreatePOItemsFromRequiItems(CoreRow[] selected, List<PurchaseOrderItem> comparison = null)
|
|
|
+ {
|
|
|
+ List<PurchaseOrderItem> items = new List<PurchaseOrderItem>();
|
|
|
+ foreach (CoreRow row in selected)
|
|
|
+ {
|
|
|
+ JobRequisitionItem JobReqItem = row.ToObject<JobRequisitionItem>();
|
|
|
+ JobRequiItems.Add(JobReqItem);
|
|
|
+ if (JobReqItem.PurchaseOrderItem.ID != Guid.Empty)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ PurchaseOrderItem POItem = new PurchaseOrderItem();
|
|
|
+ POItem.Product.ID = JobReqItem.Product.ID;
|
|
|
+ POItem.Product.Code = JobReqItem.Product.Code;
|
|
|
+ POItem.Product.Name = JobReqItem.Product.Name;
|
|
|
+ POItem.Description = JobReqItem.Product.Name;
|
|
|
+ POItem.Qty = JobReqItem.Qty;
|
|
|
+ POItem.Dimensions.CopyFrom(JobReqItem.Dimensions);
|
|
|
+ POItem.Style.ID = JobReqItem.Style.ID;
|
|
|
+ POItem.Style.Code = JobReqItem.Style.Code;
|
|
|
+ POItem.Style.Description = JobReqItem.Style.Description;
|
|
|
+ POItem.Job.ID = JobReqItem.Requisition.Job.ID;
|
|
|
+ POItem.Job.JobNumber = JobReqItem.Requisition.Job.JobNumber;
|
|
|
+ POItem.Job.Name = JobReqItem.Requisition.Job.Name;
|
|
|
+ POItem.Dimensions.UnitSize = JobReqItem.Dimensions.UnitSize;
|
|
|
+ if (comparison != null && !Duplicated(POItem, comparison))
|
|
|
+ items.Add(POItem);
|
|
|
+ else if (comparison == null)
|
|
|
+ items.Add(POItem);
|
|
|
+ }
|
|
|
+ return items;
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool Duplicated(PurchaseOrderItem newItem, List<PurchaseOrderItem> existing)
|
|
|
+ {
|
|
|
+ if (existing.Find(x =>
|
|
|
+ x.Product.ID == newItem.Product.ID
|
|
|
+ && x.Qty == newItem.Qty
|
|
|
+ && x.Style.ID == newItem.Style.ID
|
|
|
+ && x.Job.ID == newItem.Job.ID
|
|
|
+ && x.Dimensions.UnitSize == newItem.Dimensions.UnitSize
|
|
|
+ )
|
|
|
+ != null)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void LoadColumns(string column, Dictionary<string, string> columns)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public IFilter? DefineFilter(Type type) => LookupFactory.DefineFilter(type);
|
|
|
+
|
|
|
+ public void LoadLookups(ILookupEditorControl sender)
|
|
|
+ {
|
|
|
+ var editor = sender.EditorDefinition as ILookupEditor;
|
|
|
+ var colname = sender.ColumnName;
|
|
|
+
|
|
|
+ var values = editor.Values(colname, Editor.Items);
|
|
|
+ sender.LoadLookups(values);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Document? FindDocument(string filename) => null;
|
|
|
+
|
|
|
+ public Document? GetDocument(Guid id) => null;
|
|
|
+
|
|
|
+ public void SaveDocument(Document document) { }
|
|
|
+
|
|
|
+ object?[] IDynamicEditorHost.GetItems() => Editor.Items;
|
|
|
+
|
|
|
+ public BaseEditor? GetEditor(DynamicGridColumn column) => column.Editor.CloneEditor();
|
|
|
+
|
|
|
+ public void CreateToolbarButtons(IPanelHost host)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public Dictionary<string, object[]> Selected()
|
|
|
+ {
|
|
|
+ return new Dictionary<string, object[]>();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Heartbeat(TimeSpan time)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Setup()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Shutdown()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Refresh()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public DataModel DataModel(Selection selection)
|
|
|
+ {
|
|
|
+ return new EmptyDataModel();
|
|
|
}
|
|
|
}
|
|
|
}
|