Przeglądaj źródła

PRS DESKTOP - continued work on Job Requisitions panel

Nick-PRSDigital@bitbucket.org 2 lat temu
rodzic
commit
33208cdfbe

+ 72 - 0
prs.desktop/JobRequisitionPurchasing.xaml

@@ -0,0 +1,72 @@
+<UserControl x:Class="PRSDesktop.JobRequisitionPurchasing"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:PRSDesktop"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800">
+    <DockPanel>
+        <Border DockPanel.Dock="Top" BorderBrush="Gray" BorderThickness="1" Background="WhiteSmoke">
+            <Grid Margin="4,4,0,0">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="Auto" />
+                    <ColumnDefinition Width="*" />
+                    <ColumnDefinition Width="Auto" />
+                    <ColumnDefinition Width="*" />
+                    <ColumnDefinition Width="Auto" />
+                    <ColumnDefinition Width="*" />
+                </Grid.ColumnDefinitions>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="Auto" />
+                    <RowDefinition Height="Auto" />
+                    <RowDefinition Height="Auto" />
+                    <RowDefinition Height="Auto" />
+                    <RowDefinition Height="Auto" />
+                    <RowDefinition Height="Auto" />
+                </Grid.RowDefinitions>
+
+                <Label Grid.Row="0" Grid.Column="0" Margin="0,0,4,4" Content="Purchase #"
+                               VerticalContentAlignment="Center" />
+                <TextBox Grid.Row="0" Grid.Column="1" Margin="0,0,4,4" x:Name="Number"
+                                 VerticalContentAlignment="Center" />
+
+                <Label Grid.Row="1" Grid.Column="0" Margin="0,0,4,4" Content="Supplier"
+                               VerticalContentAlignment="Center" />
+                <TextBox Grid.Row="1" Grid.Column="1" Margin="0,0,4,4" x:Name="SupplierCode"
+                                 VerticalContentAlignment="Center" />
+                <TextBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="4" Margin="0,0,4,4"
+                                 x:Name="SupplierName" VerticalContentAlignment="Center" />
+
+                <Label Grid.Row="2" Grid.Column="0" Margin="0,0,4,4" Content="Description"
+                               VerticalContentAlignment="Center" />
+                <Border Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="5" BorderBrush="Gray"
+                                BorderThickness="0.75" Background="White" Padding="0" Margin="0,0,4,4">
+                    <TextBlock Height="80" x:Name="Description" TextWrapping="WrapWithOverflow" />
+                </Border>
+
+                <Label Grid.Row="3" Grid.Column="0" Margin="0,0,4,4" Content="Issued"
+                               VerticalContentAlignment="Center" />
+                <TextBox Grid.Row="3" Grid.Column="1" Margin="0,0,4,4" x:Name="Issued"
+                                 VerticalContentAlignment="Center" />
+
+                <Label Grid.Row="3" Grid.Column="2" Margin="0,0,4,4" Content="Issued By"
+                               VerticalContentAlignment="Center" />
+                <TextBox Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="3" Margin="0,0,4,4" x:Name="IssuedBy"
+                                 VerticalContentAlignment="Center" />
+
+                <Label Grid.Row="4" Grid.Column="0" Margin="0,0,4,4" Content="Due Date"
+                               VerticalContentAlignment="Center" />
+                <TextBox Grid.Row="4" Grid.Column="1" Margin="0,0,4,4" x:Name="DueDate"
+                                 VerticalContentAlignment="Center" />
+
+                <Label Grid.Row="4" Grid.Column="4" Margin="0,0,4,4" Content="Closed"
+                               VerticalContentAlignment="Center" />
+                <TextBox Grid.Row="4" Grid.Column="5" Margin="0,0,4,4" x:Name="ClosedDate"
+                                 VerticalContentAlignment="Center" />
+
+            </Grid>
+        </Border>
+        <local:SupplierPurchaseOrderItems x:Name="Items" DockPanel.Dock="Top" Margin="0,2,0,2"/>
+    </DockPanel>
+</UserControl>

+ 67 - 0
prs.desktop/JobRequisitionPurchasing.xaml.cs

@@ -0,0 +1,67 @@
+using Comal.Classes;
+using InABox.Clients;
+using InABox.Core;
+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
+    {
+        private List<JobRequisitionItem> jobRequiItems;
+        public List<JobRequisitionItem> JobRequiItems
+        {
+            get => jobRequiItems;
+            set
+            {
+                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());
+            }
+        }
+
+        public JobRequisitionPurchasing()
+        {
+            InitializeComponent();
+            //JobRequiItems = new List<JobRequisitionItem>();
+            Items.Options.Remove(DynamicGridOption.ImportData);
+            Items.Options.Remove(DynamicGridOption.ExportData);
+        }
+        private void LoadOrder(CoreRow row)
+        {
+            Number.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.PONumber);
+
+            SupplierCode.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.SupplierLink.Code);
+            SupplierName.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.SupplierLink.Name);
+
+            Description.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.Notes);
+
+            Issued.Text = row == null ? "" : CheckDate(row.Get<PurchaseOrder, DateTime>(x => x.IssuedDate));
+            IssuedBy.Text = row == null ? "" : row.Get<PurchaseOrder, string>(x => x.IssuedBy.Name);
+
+            DueDate.Text = row == null ? "" : CheckDate(row.Get<PurchaseOrder, DateTime>(x => x.DueDate));
+            ClosedDate.Text = row == null ? "" : CheckDate(row.Get<PurchaseOrder, DateTime>(x => x.ClosedDate));
+        }
+
+        private string CheckDate(DateTime date)
+        {
+            return date.IsEmpty() ? "" : date.ToShortDateString();
+        }
+    }
+}

+ 18 - 16
prs.desktop/Panels/Products/Job Requisitions/JobRequisitionHoldingsReview.xaml

@@ -41,23 +41,24 @@
         </DataTemplate>
 
     </UserControl.Resources>
-    <ScrollViewer HorizontalAlignment="Stretch">
-        <Grid>
-            <Grid.RowDefinitions>
-                <RowDefinition Height="auto"/>
-                <RowDefinition Height="auto"/>
-            </Grid.RowDefinitions>
-
-            <Border Grid.Row="0" BorderThickness="1.25" BorderBrush="Gray" Background="WhiteSmoke" Margin="0, 0, 0, 4">
-                <StackPanel>
-                    <TextBlock  x:Name="productLbl" HorizontalAlignment="Center" FontSize="16" Text="Select a Requisition Line to Reserve Stock"
+
+    <Grid Margin="0">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="auto"/>
+            <RowDefinition Height="auto"/>
+        </Grid.RowDefinitions>
+
+        <Border Grid.Row="0" BorderThickness="1.25" BorderBrush="Gray" Background="WhiteSmoke" Margin="0, 0, 0, 4">
+            <StackPanel>
+                <TextBlock  x:Name="productLbl" HorizontalAlignment="Center" FontSize="16" Text="Select a Requisition Line to Reserve Stock"
                             VerticalAlignment="Center" FontWeight="DemiBold" Margin="3"  TextAlignment="Center"/>
-                    <TextBlock  x:Name="styleLbl" HorizontalAlignment="Center" FontSize="16"  TextWrapping="Wrap" TextAlignment="Center"
+                <TextBlock  x:Name="styleLbl" HorizontalAlignment="Center" FontSize="16"  TextWrapping="Wrap" TextAlignment="Center"
                             VerticalAlignment="Center"  Margin="3"/>
-                </StackPanel>
-            </Border>
+            </StackPanel>
+        </Border>
 
-            <Border Grid.Row="1" BorderThickness="1" BorderBrush="Gray" Background="WhiteSmoke" Margin="0, 0, 0, 5">
+        <ScrollViewer Grid.Row="1" HorizontalAlignment="Stretch">
+            <Border  BorderThickness="1" BorderBrush="Gray" Background="WhiteSmoke" Margin="0, 0, 0, 5">
                 <Grid>
                     <Grid.RowDefinitions>
                         <RowDefinition Height="auto"/>
@@ -175,8 +176,9 @@
 
                 </Grid>
             </Border>
-        </Grid>
+        </ScrollViewer>
+    </Grid>
+
 
 
-    </ScrollViewer>
 </UserControl>

+ 91 - 68
prs.desktop/Panels/Products/Job Requisitions/JobRequisitionReviewGrid.cs

@@ -1,42 +1,63 @@
 using Comal.Classes;
 using InABox.Clients;
+using InABox.Configuration;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.WPF;
-using NPOI.OpenXmlFormats.Dml;
-using Syncfusion.Windows.Shared;
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
-using System.Windows.Media;
 
 namespace PRSDesktop
 {
-    public delegate void JobRequiItemSelect(JobRequisitionItem item);
+    public class JobRequisitionReviewUserSettings : IUserConfigurationSettings
+    {
+        public DynamicGridFilter Filter { get; set; }
+
+        public JobRequisitionReviewUserSettings()
+        {
+            Filter = new DynamicGridFilter();
+        }
+    }
+
+    public delegate void JobRequiItemSelect(CoreRow[] rows);
     public delegate void GridRefresh();
     public class JobRequisitionReviewGrid : DynamicDataGrid<JobRequisitionItem>
     {
         public event JobRequiItemSelect OnJobRequiItemSelected;
         public event GridRefresh OnGridRefresh;
-        List<Guid> filterProductIDs = new List<Guid>();
         public Guid empID = new Guid();
         string empName = "";
         bool bIncludeArchived = false;
         bool bViewCancelled = false;
-        public Guid JobID = Guid.Empty;
+        JobRequisitionReviewUserSettings FilterSettings = new JobRequisitionReviewUserSettings();
+
         Dictionary<Guid, double> JobRequisReservedQty = new Dictionary<Guid, double>();
         public JobRequisitionReviewGrid()
         {
+            FilterSettings = new UserConfiguration<JobRequisitionReviewUserSettings>().Load();
+            if (!string.IsNullOrWhiteSpace(FilterSettings.Filter.Name))
+            {
+                SelectedFilter = new(FilterSettings.Filter.Name, Serialization.Deserialize<Filter<JobRequisitionItem>>(FilterSettings.Filter.Filter));
+                UpdateFilterButton(InABox.Wpf.Resources.filter_set);
+            }
+                
+
             Options.AddRange(
-            DynamicGridOption.FilterRows,
-            DynamicGridOption.SelectColumns,
-            DynamicGridOption.RecordCount,
-            DynamicGridOption.MultiSelect
-            );
+                DynamicGridOption.FilterRows,
+                DynamicGridOption.SelectColumns,
+                DynamicGridOption.RecordCount
+                );
+            Options.Remove(DynamicGridOption.AddRows);
+            Options.Remove(DynamicGridOption.EditRows);
+            Options.Remove(DynamicGridOption.ImportData);
+            Options.Remove(DynamicGridOption.ExportData);
+            Options.Remove(DynamicGridOption.Print);
+            Options.Remove(DynamicGridOption.ShowHelp);
+
             HiddenColumns.Add(x => x.ID);
             HiddenColumns.Add(x => x.Product.ID);
             HiddenColumns.Add(x => x.Product.Code);
@@ -51,6 +72,7 @@ namespace PRSDesktop
             HiddenColumns.Add(x => x.Requisition.Job.JobNumber);
             HiddenColumns.Add(x => x.Requisition.Job.Name);
             HiddenColumns.Add(x => x.Requisition.Number);
+            HiddenColumns.Add(x => x.PurchaseOrderItem.ID);
             HiddenColumns.Add(x => x.PurchaseOrderItem.PurchaseOrderLink.ID);
             HiddenColumns.Add(x => x.PurchaseOrderItem.PurchaseOrderLink.PONumber);
             HiddenColumns.Add(x => x.PurchaseOrderItem.DueDate);
@@ -76,14 +98,13 @@ namespace PRSDesktop
             HiddenColumns.Add(x => x.Dimensions.Unit.Description);
 
             LoadStockMovements();
-            ActionColumns.Add(new DynamicTextColumn(CreateStatus));
 
             if (Security.CanEdit<JobRequisitionItem>())
-                ActionColumns.Add(new DynamicMenuColumn(BuildMenu, EmptyReturnFunction));
-            if (Security.CanEdit<PurchaseOrder>())
-                AddButton("Create Purchase Order", null, CreatePurchaseOrder);
-            if (Security.CanEdit<PurchaseOrder>())
-                AddButton("Create Treatment PO", null, CreateTreatmentPO);           
+                ActionColumns.Add(new DynamicMenuColumn(BuildMenu));
+            //if (Security.CanEdit<PurchaseOrder>())
+            //    AddButton("Create Purchase Order", null, CreatePurchaseOrder);
+            //if (Security.CanEdit<PurchaseOrder>())
+            //    AddButton("Create Treatment PO", null, CreateTreatmentPO);
 
             AddButton("Include Archived", null, ViewArchived);
             AddButton("Include Cancelled", null, ViewCancelled);
@@ -99,15 +120,23 @@ namespace PRSDesktop
                 empName = table.Rows.FirstOrDefault().Values[1].ToString();
             }
 
+            OnFilterSelected += GridOnFilterSelected;
+
             //Migrate();
         }
 
+        private void GridOnFilterSelected(DynamicGridFilter filter, Bitmap image)
+        {
+            new UserConfiguration<JobRequisitionReviewUserSettings>().Save(new JobRequisitionReviewUserSettings { Filter = filter });         
+            OnGridRefresh?.Invoke();
+        }
+
         private void Migrate()
         {
             CoreTable table = new Client<JobRequisitionItem>().Query(null, new Columns<JobRequisitionItem>(x => x.ID, x => x.PurchaseOrderItem.PurchaseOrderLink.ID));
             Dictionary<Guid, Guid> reqPOids = new Dictionary<Guid, Guid>();
             List<JobRequisitionItem> affected = new List<JobRequisitionItem>();
-            foreach(CoreRow row in table.Rows) 
+            foreach (CoreRow row in table.Rows)
             {
                 var item = row.ToObject<JobRequisitionItem>();
                 if (item.PurchaseOrderItem.PurchaseOrderLink.ID != Guid.Empty)
@@ -115,8 +144,8 @@ namespace PRSDesktop
                     reqPOids.Add(row.Get<JobRequisitionItem, Guid>(x => x.ID), item.PurchaseOrderItem.PurchaseOrderLink.ID);
                     affected.Add(row.ToObject<JobRequisitionItem>());
                 }
-                }
-                List<JobRequisitionItem> list = new List<JobRequisitionItem>();
+            }
+            List<JobRequisitionItem> list = new List<JobRequisitionItem>();
             CoreTable POs = new Client<PurchaseOrder>().Query(new Filter<PurchaseOrder>(x => x.ID).InList(reqPOids.Values.ToArray()), new Columns<PurchaseOrder>(x => x.ID, x => x.Created));
             foreach (CoreRow row in POs.Rows)
             {
@@ -154,6 +183,37 @@ namespace PRSDesktop
             }
         }
 
+        public void AddStockMovements(Guid requiItemID)
+        {
+            CoreTable table = new Client<StockMovement>().Query(new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(requiItemID),
+                new Columns<StockMovement>(
+                    x => x.JobRequisitionItem.ID,
+                    x => x.Received
+                    )
+                );
+            if (table.Rows.Any())
+            {
+                foreach (CoreRow row in table.Rows)
+                {
+                    var requiID = row.Get<StockMovement, Guid>(x => x.JobRequisitionItem.ID);
+                    var qty = row.Get<StockMovement, double>(x => x.Received);
+                    if (!JobRequisReservedQty.ContainsKey(requiID))
+                        JobRequisReservedQty.Add(requiID, qty);
+                    else if (JobRequisReservedQty.ContainsKey(requiID) && row == table.Rows.First())
+                    {
+                        JobRequisReservedQty.Remove(requiID);
+                        JobRequisReservedQty.Add(requiID, qty);
+                    }
+                    else
+                    {
+                        double newQty = JobRequisReservedQty[requiID] + qty;
+                        JobRequisReservedQty.Remove(requiID);
+                        JobRequisReservedQty.Add(requiID, newQty);
+                    }
+                }
+            }
+        }
+
         private string? CreateStatus(CoreRow? row)
         {
             Guid id = row.Get<JobRequisitionItem, Guid>(x => x.ID);
@@ -202,7 +262,7 @@ namespace PRSDesktop
 
         private void JobRequisitionReviewGrid_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
         {
-            OnJobRequiItemSelected?.Invoke(SelectedRows[0].ToObject<JobRequisitionItem>());
+            OnJobRequiItemSelected?.Invoke(SelectedRows);
         }
 
         private bool ViewCancelled(Button button, CoreRow[] rows)
@@ -246,6 +306,7 @@ namespace PRSDesktop
             return true;
         }
 
+
         protected override void GenerateColumns(DynamicGridColumns columns)
         {
             columns.Add<JobRequisitionItem, DateTime>(x => x.Created, 80, "Date", "", Alignment.MiddleLeft);
@@ -260,7 +321,6 @@ namespace PRSDesktop
             columns.Add<JobRequisitionItem, string>(x => x.PurchaseOrderItem.PONumber, 80, "PO Number", "", Alignment.MiddleLeft);
             columns.Add<JobRequisitionItem, DateTime>(x => x.PurchaseOrderItem.DueDate, 80, "Due", "", Alignment.MiddleLeft);
             columns.Add<JobRequisitionItem, DateTime>(x => x.PurchaseOrderItem.ReceivedDate, 80, "Received", "", Alignment.MiddleLeft);
-            columns.Add<JobRequisitionItem, JobRequisitionItemStatus>(x => x.Status, 80, "Status", "", Alignment.MiddleLeft);
             columns.Add<JobRequisitionItem, string>(x => x.Notes, 300, "Notes", "", Alignment.MiddleLeft);
         }
 
@@ -346,7 +406,7 @@ namespace PRSDesktop
         private void Archive_Clicked(CoreRow row)
         {
             JobRequisitionItem item = row.ToObject<JobRequisitionItem>();
-
+            item.Archived = DateTime.Now;
             SaveRow(row, JobRequisitionItemStatus.Archived, "Line marked as Archived by " + empName + " on " + DateTime.Now.ToString("dd MMM yy"));
         }
 
@@ -485,16 +545,14 @@ namespace PRSDesktop
             return requiItems;
         }
 
-
-
-        private JobRequisitionItem UpdateJobReqItemWithPODetails(JobRequisitionItem JobReqItem, PurchaseOrderItem item)
+        private JobRequisitionItem UpdateJobReqItemWithPODetails(JobRequisitionItem JobReqItem, PurchaseOrderItem poItem)
         {
-            JobReqItem.PurchaseOrderItem.ID = item.ID;
-            JobReqItem.PurchaseOrderItem.DueDate = item.DueDate;
+            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.Status = JobRequisitionItemStatus.OnOrder;
+                JobReqItem.Ordered = poItem.Created;
             }
             return JobReqItem;
         }
@@ -602,51 +660,16 @@ namespace PRSDesktop
             if (!bIncludeArchived)
                 criteria.Add(new Filter<JobRequisitionItem>(x => x.Status).IsNotEqualTo(JobRequisitionItemStatus.Archived));
 
-            if (filterProductIDs.Count > 0)
-            {
-                Filter<JobRequisitionItem> filter = new Filter<JobRequisitionItem>(x => x.Product.ID).IsEqualTo(filterProductIDs.FirstOrDefault());
-                foreach (Guid id in filterProductIDs)
-                {
-                    if (id != filterProductIDs[0])
-                        filter = filter.Or(x => x.Product.ID).IsEqualTo(id);
-                }
-                criteria.Add(filter);
-            }
-
-            if (JobID != Guid.Empty)
-                criteria.Add(new Filter<JobRequisitionItem>(x => x.Requisition.Job.ID).IsEqualTo(JobID));
-
-
             sort = new SortOrder<JobRequisitionItem>(x => x.Requisition.Number, SortDirection.Descending);
             base.Reload(criteria, columns, ref sort, action);
         }
 
-        public void RefreshOnFilterChanged(Guid id)
-        {
-            filterProductIDs.Clear();
-            if (id != Guid.Empty)
-            {
-                CoreTable table = new Client<SupplierProduct>().Query(
-                    new Filter<SupplierProduct>(x => x.SupplierLink.ID).IsEqualTo(id)
-                        .And(x => x.Product).LinkValid(),
-                    new Columns<SupplierProduct>(x => x.Product.ID));
-                if (table.Rows.Any())
-                {
-                    foreach (CoreRow row in table.Rows)
-                    {
-                        filterProductIDs.Add(Guid.Parse(row.Values[0].ToString()));
-                    }
-                }
-            }
-            OnGridRefresh?.Invoke();
-        }
 
         private void BuildMenu(DynamicMenuColumn column, CoreRow row)
         {
-            column.AddItem("Mark as already reserved", PRSDesktop.Resources.rack, MarkReserved_Clicked);
-            column.AddItem("Treatment Required", PRSDesktop.Resources.palette, TreatmentRequired_Clicked);
+            // column.AddItem("Treatment Required", PRSDesktop.Resources.palette, TreatmentRequired_Clicked);
             column.AddItem("Order Required", PRSDesktop.Resources.purchase, OrderRequired_Clicked);
-            column.AddItem("Mark as Not Checked", PRSDesktop.Resources.disabled, Uncheck_Clicked);
+            //column.AddItem("Mark as Not Checked", PRSDesktop.Resources.disabled, Uncheck_Clicked);
             column.AddItem("Split Line", PRSDesktop.Resources.split, SplitLine_Clicked);
             column.AddItem("Archive", PRSDesktop.Resources.archive, Archive_Clicked);
         }

+ 29 - 3
prs.desktop/Panels/Products/Job Requisitions/JobRequisitionsPanel.xaml

@@ -7,13 +7,39 @@
              mc:Ignorable="d" 
              d:DesignHeight="450" d:DesignWidth="900">
     <dynamicgrid:DynamicSplitPanel MasterCaption="Job Requisition Items" DetailCaption="Available Stock" AnchorWidth="1200" AllowableViews="Combined" View="Combined">
-
+       
         <dynamicgrid:DynamicSplitPanel.Master>
-            <local:JobRequisitionReviewGrid  x:Name="unProcessedJobRequiItems" Margin="0,2,0,0"/>
+            <local:JobRequisitionReviewGrid  x:Name="JobRequiItems" Margin="0,2,0,0"/>
         </dynamicgrid:DynamicSplitPanel.Master>
 
         <dynamicgrid:DynamicSplitPanel.Detail>
-            <local:JobRequisitionHoldingsReview x:Name="holdings" Margin="0,2,0,0"/>
+            <Grid>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto"/>
+                    <RowDefinition Height="*"/>
+                </Grid.RowDefinitions>
+      
+                <Grid Grid.Row="0">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="*" />
+                        <ColumnDefinition Width="*" />
+                    </Grid.ColumnDefinitions>
+                    <Button Grid.Column="0" Content="Reserve Stock" Height="30"  FontWeight="DemiBold" x:Name="reserveBtn"
+                            BorderBrush="DarkGray" Margin="0,2,1,0" Padding="13,3,13,3" BorderThickness="1.25"
+                            Click="ReserveStock_Clicked"/>
+                    <Button Grid.Column="1" Content="Purchase Stock" Height="30" FontWeight="DemiBold" x:Name="purchaseBtn"
+                            BorderBrush="DarkGray" Margin="1,2,0,0" Padding="13,3,13,3"  BorderThickness="1.25"
+                            Click="PurchaseStock_Clicked"/>
+                </Grid>
+                <Grid Grid.Row="1">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="*" x:Name="reserveCol"/>
+                        <ColumnDefinition Width="0" x:Name="purchaseCol"/>
+                    </Grid.ColumnDefinitions>
+                    <local:JobRequisitionHoldingsReview Grid.Column="0" x:Name="holdings" Margin="0,2,0,0"/>
+                    <local:JobRequisitionPurchasing Grid.Column="1" x:Name="purchasing" Margin="0,2,0,0"/>
+                </Grid>
+            </Grid>
         </dynamicgrid:DynamicSplitPanel.Detail>
 
     </dynamicgrid:DynamicSplitPanel>

+ 66 - 95
prs.desktop/Panels/Products/Job Requisitions/JobRequisitionsPanel.xaml.cs

@@ -1,35 +1,23 @@
-using com.sun.tools.javac.file;
-using Comal.Classes;
+using Comal.Classes;
 using InABox.Configuration;
 using InABox.Core;
-using InABox.Core.Notifications;
-using InABox.Database;
 using InABox.DynamicGrid;
 using InABox.WPF;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 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
 {
-    public class ProductPanelSettings : BaseObject, IGlobalConfigurationSettings
+    public class JobRequisitionPanelSettings : BaseObject, IGlobalConfigurationSettings
     {
         [Caption("Default Style for Company", IncludePath = false)]
         public ProductStyleLink ProductStyle { get; set; }
 
-        public ProductPanelSettings()
+        public JobRequisitionPanelSettings()
         {
             ProductStyle = new ProductStyleLink();
         }
@@ -42,74 +30,47 @@ namespace PRSDesktop
     public partial class JobRequisitionsPanel : UserControl, IPanel<JobRequisitionItem>
     {
         Guid JobID = Guid.Empty;
-        private ProductPanelSettings _settings = null;
+        private JobRequisitionPanelSettings _settings = null;
         public JobRequisitionsPanel()
         {
             InitializeComponent();
         }
 
-        private void Run()
+        enum PanelMode
         {
-            Dictionary<Guid, List<String>> dict = new Dictionary<Guid, List<string>>();
+            Reserve,
+            Purchase
+        }
 
-            var ReylandJobs = new List<string>
-            {
-                "2839",
-                "2878",
-                "2837",
-                "2902",
-                "2949",
-                "2819",
-                "2989",
-                "2937",
-                "2823",
-                "2817C",
-            };
+        private PanelMode mode;
 
-            var EdmundJobs = new List<string>
+        private PanelMode Mode
+        {
+            get => mode;
+            set
             {
-                "2838",
-                "2885Y",
-                "2885A",
-                "2885E",
-                "2879",
-                "2869",
-            };
+                mode = value;
+                SetPanelDetail();
+            }
+        }
 
-            var JasysonJobs = new List<string>
+        private void SetPanelDetail()
+        {
+            if (Mode == PanelMode.Reserve)
             {
-                "2881",
-                "2947",
-                "2992",
-                "2819",
-                "2740-3",
-                "2740-2B",
-                "2740-1A",
-                "2995",
-                "2956",
-                "2882",
-            };
-
-            dict.Add(Guid.Parse("1fd0ad29-3cb4-4cde-9252-1b5aab6bb6b6"), ReylandJobs);
-            dict.Add(Guid.Parse("938287b7-bbdb-4fe8-8532-1bba7d9e3806"), EdmundJobs);
-            dict.Add(Guid.Parse("1fd0ad29-3cb4-4cde-9252-1b5aab6bb6b6"), JasysonJobs);
-
-            List<JobForm> JobForms = new List<JobForm>();
-            foreach (JobForm JobForm in JobForms)
+                reserveCol.Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star);
+                purchaseCol.Width = new System.Windows.GridLength(0);
+                JobRequiItems.Options.Remove(DynamicGridOption.MultiSelect);
+                reserveBtn.Background = new SolidColorBrush(Colors.LightGray);
+                purchaseBtn.Background = new SolidColorBrush(Colors.WhiteSmoke);
+            }
+            else if (Mode == PanelMode.Purchase)
             {
-                if (JobForm.Form.ID != Guid.Parse("b5bca5d9-db39-4bd7-901e-08a98e174212"))
-                    continue;
-                foreach (var pair in dict)
-                {
-                    if (pair.Value.Contains(JobForm.Parent.JobNumber))
-                    {
-                        var notification = new Notification();
-                        notification.Employee.ID = pair.Key;
-                        notification.Title = "New Pressing Form Completed for Job " + pair.Value.FirstOrDefault(x => x.Contains(JobForm.Parent.JobNumber));
-                        notification.Created = DateTime.Now;
-                        DbFactory.Provider.Save<Notification>(notification);
-                    }
-                }
+                reserveCol.Width = new System.Windows.GridLength(0);
+                purchaseCol.Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star);
+                JobRequiItems.Options.Add(DynamicGridOption.MultiSelect);
+                reserveBtn.Background = new SolidColorBrush(Colors.WhiteSmoke);
+                purchaseBtn.Background = new SolidColorBrush(Colors.LightGray);
             }
         }
 
@@ -138,7 +99,7 @@ namespace PRSDesktop
                     { UseShellExecute = true });
                 }
             );
-            var propertyEditor = new DynamicEditorForm(typeof(ProductPanelSettings), pages, buttons);
+            var propertyEditor = new DynamicEditorForm(typeof(JobRequisitionPanelSettings), pages, buttons);
             propertyEditor.OnDefineLookups += sender =>
             {
                 var editor = sender.EditorDefinition as ILookupEditor;
@@ -156,13 +117,14 @@ namespace PRSDesktop
 
             if (propertyEditor.ShowDialog() == true)
             {
-                new GlobalConfiguration<ProductPanelSettings>().Save(_settings);
+                new GlobalConfiguration<JobRequisitionPanelSettings>().Save(_settings);
+                holdings.CompanyDefaultStyle = _settings.ProductStyle;
             }
         }
 
         public DataModel DataModel(Selection selection)
         {
-            var ids = unProcessedJobRequiItems.ExtractValues(x => x.ID, selection).ToArray();
+            var ids = JobRequiItems.ExtractValues(x => x.ID, selection).ToArray();
             return new BaseDataModel<JobRequisitionItem>(new Filter<JobRequisitionItem>(x => x.ID).InList(ids));
         }
 
@@ -173,60 +135,60 @@ namespace PRSDesktop
 
         public void Refresh()
         {
-            unProcessedJobRequiItems.Refresh(false, true);
+            JobRequiItems.Refresh(false, true);
         }
 
         public Dictionary<string, object[]> Selected()
         {
             var result = new Dictionary<string, object[]>();
-            result[typeof(JobRequisitionItem).EntityName()] = unProcessedJobRequiItems.SelectedRows;
+            result[typeof(JobRequisitionItem).EntityName()] = JobRequiItems.SelectedRows;
             return result;
         }
 
         public void Setup()
         {
+            Mode = PanelMode.Reserve;
             SetupJobRequiItemGrids();
 
-            _settings = new GlobalConfiguration<ProductPanelSettings>().Load();
+            _settings = new GlobalConfiguration<JobRequisitionPanelSettings>().Load();
             holdings.CompanyDefaultStyle = _settings.ProductStyle;
 
             holdings.OnHoldingsReviewRefresh += Holdings_OnHoldingsReviewRefresh;
         }
 
+
         private void Holdings_OnHoldingsReviewRefresh()
         {
             Refresh();
+            RefreshJobRequiGrids();
         }
 
         private void RefreshJobRequiGrids()
         {
-            unProcessedJobRequiItems.bRefreshing = false;
-            unProcessedJobRequiItems.Refresh(false, true);
+            JobRequiItems.bRefreshing = false;
+            JobRequiItems.Refresh(false, true);
         }
 
-        private void AvailableHoldingsGrid_OnStockReserved()
+        private void SetupJobRequiItemGrids()
         {
-            unProcessedJobRequiItems.Refresh(false, true);
+            JobRequiItems.OnGridRefresh += JobRequiItems_OnGridRefresh;
+            JobRequiItems.OnJobRequiItemSelected += OnJobRequiItemSelected;
+            JobRequiItems.Refresh(true, true);
         }
 
-        private void SetupJobRequiItemGrids()
+        private void OnJobRequiItemSelected(CoreRow[] rows)
         {
-            unProcessedJobRequiItems.OnGridRefresh += JobRequiItems_OnGridRefresh;
-
-            unProcessedJobRequiItems.OnReload += (object sender, Filters<JobRequisitionItem> criteria, Columns<JobRequisitionItem> columns, ref SortOrder<JobRequisitionItem>? sortby) =>
-            {
-                criteria.Add(new Filter<JobRequisitionItem>(x => x.Status).IsEqualTo(JobRequisitionItemStatus.NotChecked));
-            };
-
-            unProcessedJobRequiItems.OnJobRequiItemSelected += OnJobRequiItemSelected;
-
-            unProcessedJobRequiItems.Refresh(true, true);
+            holdings.Item = rows[0].ToObject<JobRequisitionItem>();
+            purchasing.JobRequiItems = CreateList(rows);
         }
 
-        private void OnJobRequiItemSelected(JobRequisitionItem item)
+        private List<JobRequisitionItem> CreateList(CoreRow[] rows)
         {
-            holdings.Item = item;
+            List<JobRequisitionItem> list = new List<JobRequisitionItem>();
+            foreach (var row in rows)
+                list.Add(row.ToObject<JobRequisitionItem>());
 
+            return list;
         }
 
         private void JobRequiItems_OnGridRefresh()
@@ -234,10 +196,19 @@ namespace PRSDesktop
             RefreshJobRequiGrids();
         }
 
-
         public void Shutdown()
         {
 
         }
+
+        private void ReserveStock_Clicked(object sender, System.Windows.RoutedEventArgs e)
+        {
+            Mode = PanelMode.Reserve;
+        }
+
+        private void PurchaseStock_Clicked(object sender, System.Windows.RoutedEventArgs e)
+        {
+            Mode = PanelMode.Purchase;
+        }
     }
 }

+ 19 - 7
prs.desktop/Panels/Suppliers/SupplierPurchaseOrderItems.cs

@@ -15,11 +15,12 @@ namespace PRSDesktop
 {
     internal class SupplierPurchaseOrderItems : DynamicDataGrid<PurchaseOrderItem>
     {
-        private readonly Button bill;
+        private Button bill;
 
-        private readonly Button? consign;
-        private readonly Button receive;
-        private readonly Button? viewconsign;
+        private Button? consign;
+        private Button receive;
+        private Button? viewconsign;
+        private Button assignLocation;
 
         public Guid OrderID { get; set; }
         public Guid SupplierID { get; set; }
@@ -75,7 +76,8 @@ namespace PRSDesktop
             bill = AddButton("Enter Bill", null, EnterBill);
             bill.IsEnabled = false;
 
-            AddButton("Assign Location", null, AssignLocation);
+            assignLocation = AddButton("Assign Location", null, AssignLocation);
+
         }
 
         public static bool AssignLocation(Button btn, CoreRow[] rows)
@@ -91,7 +93,7 @@ namespace PRSDesktop
                 var grid = new StockLocationGrid();
                 var location = new StockLocation();
                 if (grid.EditItems(new StockLocation[] { location }))
-                    AssignLocationToItems(location.ID, rows);               
+                    AssignLocationToItems(location.ID, rows);
             }
             else
             {
@@ -99,7 +101,7 @@ namespace PRSDesktop
 
                 if (popup.ShowDialog() == true)
                     AssignLocationToItems(popup.ID, rows);
-               
+
             }
             return true;
         }
@@ -389,5 +391,15 @@ namespace PRSDesktop
 
             return result;
         }
+
+        public bool bRemoveButtons { get; set; }
+        public void RemoveButtons()
+        {
+            bill = null;
+            receive = null;
+            consign = null;
+            viewconsign = null;
+            assignLocation = null;
+        }
     }
 }

+ 62 - 0
prs.stores/JobRequisitionItemStore.cs

@@ -0,0 +1,62 @@
+using Comal.Classes;
+using Comal.Stores;
+using InABox.Core;
+using System;
+using System.Linq;
+
+namespace PRSStores
+{
+    public class JobRequisitionItemStore : BaseStore<JobRequisitionItem>
+    {
+        protected override void BeforeSave(JobRequisitionItem item)
+        {
+            var table = DoQuery(item);
+            item = DoStatusChecks(item, table);
+            base.BeforeSave(item);
+        }
+
+        private CoreTable DoQuery(JobRequisitionItem item)
+        { 
+            return Provider.Query<StockMovement>(
+               new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(item.ID),
+               new Columns<StockMovement>(
+                   x => x.Received
+                   ));
+        }
+
+        public static JobRequisitionItem DoStatusChecks(JobRequisitionItem item, CoreTable table)
+        {
+            if (item.Cancelled != DateTime.MinValue)
+                item.Status = JobRequisitionItemStatus.Cancelled;
+            else if (item.Archived != DateTime.MinValue)
+                item.Status = JobRequisitionItemStatus.Archived;
+            else if (item.Ordered != DateTime.MinValue && item.PurchaseOrderItem.ReceivedDate == DateTime.MinValue)
+                item.Status = JobRequisitionItemStatus.OnOrder;
+            else if (item.PurchaseOrderItem.ReceivedDate != DateTime.MinValue)
+                item.Status = JobRequisitionItemStatus.Received;
+            else if (item.Status == JobRequisitionItemStatus.OrderRequired)
+                return item;
+            else
+                item = CheckReserved(item, table);          
+
+            return item;
+        }
+
+        private static JobRequisitionItem CheckReserved(JobRequisitionItem item, CoreTable table)
+        {         
+            if (!table.Rows.Any())
+                return item;
+
+            double total = 0;
+            foreach (var row in table.Rows) 
+                total = total + row.Get<StockMovement, double>(x => x.Received);
+
+            if (total >= item.Qty)
+                item.Status = JobRequisitionItemStatus.Reserved;
+            else
+                item.Status = JobRequisitionItemStatus.NotChecked;
+
+            return item;
+        }
+    }    
+}

+ 2 - 0
prs.stores/PRSStores.projitems

@@ -35,6 +35,7 @@
     <Compile Include="$(MSBuildThisFileDirectory)InvoiceReceiptStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)InvoiceStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)JobMaterialRequsitionStore.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)JobRequisitionItemStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)JobRequisitionStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)JobStageStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)JobStore.cs" />
@@ -59,6 +60,7 @@
     <Compile Include="$(MSBuildThisFileDirectory)ShipmentStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)StockAreaStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)StockLocationStore.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)StockMovementStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)StockWarehouseStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)StoreUtils.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)SupplierProductStore.cs" />

+ 45 - 0
prs.stores/StockMovementStore.cs

@@ -0,0 +1,45 @@
+using Comal.Classes;
+using Comal.Stores;
+using InABox.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PRSStores
+{
+    public class StockMovementStore : BaseStore<StockMovement>
+    {
+        protected override void AfterSave(StockMovement sm)
+        {
+            if (sm.JobRequisitionItem.ID != Guid.Empty)
+            {
+                CoreTable table = Provider.Query<JobRequisitionItem>(
+                    new Filter<JobRequisitionItem>(x => x.ID).IsEqualTo(sm.JobRequisitionItem.ID),
+                    new Columns<JobRequisitionItem>(x => x.ID, x => x.Cancelled, x => x.Archived, x => x.PurchaseOrderItem.ReceivedDate, x => x.Ordered)
+                    );
+                var item = table.Rows.FirstOrDefault().ToObject<JobRequisitionItem>();
+
+                item = JobRequisitionItemStore.DoStatusChecks(item, DoQuery(item));
+                Provider.Save(item);
+            }
+
+            base.AfterSave(sm);
+        }
+
+        private JobRequisitionItem QueryJobRequiItem(Guid itemID)
+        {
+            CoreTable table = Provider.Query<JobRequisitionItem>(new Filter<JobRequisitionItem>(x => x.ID).IsEqualTo(itemID));
+            return table.Rows.FirstOrDefault().ToObject<JobRequisitionItem>();
+        }
+
+        private CoreTable DoQuery(JobRequisitionItem item)
+        {
+            return Provider.Query<StockMovement>(
+               new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(item.ID),
+               new Columns<StockMovement>(
+                   x => x.Received
+                   ));
+        }
+    }
+}