Browse Source

Added Open Forms Indicator to Leave Request Grid
Added extra columns to Product Lookups
Made Recieved Date in Purchase Order Items editable and cleaned up PurchaseOrderItemStore
Added BarcodeQty to Staged Design Packets and fixed ReadOnly and Watermark inconsistencies

frogsoftware 2 years ago
parent
commit
faf0d9ad14

+ 1 - 0
prs.classes/Entities/Job/Requisitions/JobRequisitionItem.cs

@@ -74,6 +74,7 @@ namespace Comal.Classes
         [EnumLookupEditor(typeof(JobRequisitionItemStatus))]
         public JobRequisitionItemStatus Status { get; set; }
 
+        [EntityRelationship(DeleteAction.SetNull)]
         public PurchaseOrderItemLink PurchaseOrderItem { get; set; }
 
         public DateTime Cancelled { get; set; }

+ 20 - 0
prs.classes/Entities/LeaveRequest/LeaveRequest.cs

@@ -1,4 +1,6 @@
 using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
 using InABox.Core;
 
 namespace Comal.Classes
@@ -10,6 +12,20 @@ namespace Comal.Classes
         Rejected
     }
 
+
+    public class LeaveRequestOpenFormCount : CoreAggregate<LeaveRequest, LeaveRequestForm, Guid>
+    {
+        public override Expression<Func<LeaveRequestForm, Guid>> Aggregate => x => x.ID;
+
+        public override AggregateCalculation Calculation => AggregateCalculation.Count;
+
+        public override Dictionary<Expression<Func<LeaveRequestForm, object>>, Expression<Func<LeaveRequest, object>>> Links =>
+            new Dictionary<Expression<Func<LeaveRequestForm, object>>, Expression<Func<LeaveRequest, object>>>()
+            {
+                { LeaveRequestForm => LeaveRequestForm.Parent.ID, LeaveRequest => LeaveRequest.ID }
+            };
+    }
+
     [UserTracking("Holiday Calendar")]
     [Caption("Leave Requests")]
     public class LeaveRequest : Entity, IRemotable, IPersistent, ILicense<LeaveManagementLicense>, IDataEntryInstance
@@ -77,6 +93,10 @@ namespace Comal.Classes
         [NullEditor]
         [EntityRelationship(DeleteAction.Cascade)]
         public StandardLeaveLink PublicHoliday { get; set; }
+        
+        [IntegerEditor(Visible = Visible.Optional,Editable = Editable.Hidden)]
+        [Aggregate(typeof(LeaveRequestOpenFormCount))]
+        public int OpenForms { get; set; }
 
         protected override void Init()
         {

+ 19 - 2
prs.classes/Entities/Product/ProductLookups.cs

@@ -55,10 +55,27 @@ namespace Comal.Classes
                 x => x.Name,
                 x => x.TaxCode.ID,
                 x => x.PurchaseGL.ID,
-                x => x.NettCost
+                x => x.NettCost, 
+                x => x.Dimensions.Unit.ID, 
+                x => x.Dimensions.Unit.Code, 
+                x => x.Dimensions.Unit.Description, 
+                x => x.Dimensions.Unit.HasLength,
+                x => x.Dimensions.Unit.HasHeight, 
+                x => x.Dimensions.Unit.HasQuantity, 
+                x => x.Dimensions.Unit.HasWeight, 
+                x => x.Dimensions.Unit.HasWidth, 
+                x => x.Dimensions.Unit.Formula, 
+                x => x.Dimensions.Unit.Format, 
+                x => x.Dimensions.Height, 
+                x => x.Dimensions.Length, 
+                x => x.Dimensions.Quantity, 
+                x => x.Dimensions.Weight, 
+                x => x.Dimensions.Width, 
+                x => x.Dimensions.Value, 
+                x => x.Dimensions.UnitSize
             );
         }
-
+        
         public override string FormatLookup(Dictionary<string, object?> values, IEnumerable<string> exclude)
         {
             return $"{values["Name"]}";

+ 2 - 3
prs.classes/Entities/PurchaseOrder/PurchaseOrderItem.cs

@@ -114,7 +114,7 @@ namespace Comal.Classes
         [EntityRelationship(DeleteAction.SetNull)]
         public ConsignmentLink Consignment { get; set; }
 
-        [DateTimeEditor(Visible = Visible.Default, Editable = Editable.Disabled)]
+        [DateTimeEditor(Visible = Visible.Default)]
         [EditorSequence(16)]
         public DateTime ReceivedDate { get; set; }
 
@@ -154,8 +154,7 @@ namespace Comal.Classes
         [NullEditor]
         [Aggregate(typeof(PurchaseOrderItemOpenForms))]
         public int OpenForms { get; set; }
-
-
+        
         public StockLocationLink StockLocation { get; set; }
 
         [CurrencyEditor(Visible = Visible.Default, Summary = Summary.Sum)]

+ 3 - 3
prs.classes/Entities/Staging/Manufacturing/Packet/StagingManufacturingPacket.cs

@@ -31,7 +31,7 @@ namespace Comal.Classes
 
         public int Quantity { get; set; }
 
-        public int BarcodeQuantity { get; set; }
+        public String BarcodeQuantity { get; set; }
         
         public ManufacturingTemplateGroupLink Group { get; set; }
 
@@ -45,7 +45,7 @@ namespace Comal.Classes
             Title = "";
             Job = new JobLink();
             Quantity = 1;
-            BarcodeQuantity = 1;
+            BarcodeQuantity = "";
             StagingSetout = new StagingSetoutLink();    
             Serial = "";
             Watermark = "";
@@ -55,6 +55,6 @@ namespace Comal.Classes
             Group = new ManufacturingTemplateGroupLink();
             base.Init();
         }
-
+        
     }
 }

+ 26 - 1
prs.desktop/Grids/LeaveRequestGrid.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media.Imaging;
 using Comal.Classes;
@@ -18,12 +19,36 @@ namespace PRSDesktop
         protected override void Init()
         {
             base.Init();
+            
+            HiddenColumns.Add(x=>x.OpenForms);
+            ActionColumns.Add(new DynamicImageColumn(OpenFormsImage) { Position = DynamicActionColumnPosition.Start, ToolTip = OpenFormsToolTip});
+            
             ActionColumns.Add(new DynamicImageColumn(PRSDesktop.Resources.contract.AsBitmapImage(), FormAction) { Position = DynamicActionColumnPosition.End });
 
             AddButton("Include Complete", null, IncompleteOnlyClick);
             AddButton("Include History", null, ToggleAllRequests);
         }
-
+        
+        
+        private readonly BitmapImage _openforms = PRSDesktop.Resources.warning.AsBitmapImage();
+        
+        private BitmapImage? OpenFormsImage(CoreRow? row)
+        {
+            return row?.Get<LeaveRequest, int>(x => x.OpenForms) != 0
+                ? _openforms
+                : null;
+        }
+        
+        private FrameworkElement? OpenFormsToolTip(DynamicActionColumn column, CoreRow? row)
+        {
+            if (row == null)
+                return column.TextToolTip("Do incomplete forms exist?");
+            int open = row.Get<LeaveRequest, int>(x => x.OpenForms);
+            if (open != 0)
+                return column.TextToolTip($"{open} incomplete forms");
+            return null;
+        }
+        
         protected override void DoReconfigure(FluentList<DynamicGridOption> options)
         {
             base.DoReconfigure(options);

+ 6 - 1
prs.desktop/Panels/LeaveRequests/LeaveRequests.cs

@@ -4,6 +4,11 @@ using System.Linq;
 using Comal.Classes;
 using InABox.Core;
 using System.ComponentModel;
+using System.Windows;
+using System.Windows.Media.Imaging;
+using InABox.DynamicGrid;
+using InABox.WPF;
+using Syncfusion.UI.Xaml.Grid;
 
 namespace PRSDesktop
 {
@@ -31,7 +36,7 @@ namespace PRSDesktop
             var ids = ExtractValues(x => x.ID, selection).ToArray();
             return new LeaveRequestDataModel(new Filter<LeaveRequest>(x => x.ID).InList(ids));
         }
-
+        
         public void Refresh()
         {
             Refresh(false, true);

+ 12 - 11
prs.desktop/Panels/Staging/Manufacturing/StagingManufacturingPacketComponentGrid.cs

@@ -23,19 +23,20 @@ namespace PRSDesktop
             }
         }
         
-        private bool _readOnly = false;
-        public bool ReadOnly
-        {
-            get => _readOnly;
-            set
-            {
-                _readOnly = value;
-                Reconfigure();
-            }
-        }
+        // private bool _readOnly = false;
+        // public bool ReadOnly
+        // {
+        //     get => _readOnly;
+        //     set
+        //     {
+        //         _readOnly = value;
+        //         Reconfigure();
+        //     }
+        // }
 
         public StagingManufacturingPacketComponentGrid()
         {
+            IsEnabledChanged += (sender, args) => Reconfigure(); 
             HiddenColumns.Add(x=>x.Product.Code);
             Refresh(true, false);
         }
@@ -48,7 +49,7 @@ namespace PRSDesktop
                 .Clear()
                 .Add(DynamicGridOption.SelectColumns);
 
-            if ((Packet.ID != Guid.Empty) && !ReadOnly)
+            if ((Packet.ID != Guid.Empty) && IsEnabled)
             {
                 options.Add(DynamicGridOption.AddRows);
                 options.Add(DynamicGridOption.EditRows);

+ 1 - 1
prs.desktop/Panels/Staging/Manufacturing/StagingManufacturingPacketList.xaml.cs

@@ -64,6 +64,7 @@ namespace PRSDesktop
                                     .Add(x => x.Group.ID)
                                     .Add(x => x.Group.Code)
                                     .Add(x => x.Group.Description)
+                                    .Add(x => x.Group.Watermark)
                                     .Add(x => x.Template.ID)
                                     .Add(x => x.Template.Code)
                                     .Add(x => x.ManufacturingPacket.ID)));
@@ -138,7 +139,6 @@ namespace PRSDesktop
             {
                 newPacket.Group.ID = group.ID;
                 newPacket.Group.Synchronise(group);
-                newPacket.Watermark = group.Watermark;
             }
 
             newPacket.StagingSetout.ID = Setout.ID;

+ 92 - 66
prs.desktop/Panels/Staging/Manufacturing/StagingManufacturingPacketListItem.xaml

@@ -9,7 +9,8 @@
              d:DesignHeight="450" d:DesignWidth="800"
              x:Name="Control"
              xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
-             xmlns:wpf="clr-namespace:InABox.WPF;assembly=InABox.Wpf">
+             xmlns:wpf="clr-namespace:InABox.WPF;assembly=InABox.Wpf"
+             >
     <UserControl.Resources>
         <Style x:Key="StagesRowStyle" TargetType="RowDefinition">
             <Style.Setters>
@@ -33,16 +34,6 @@
             </Style.Triggers>
         </Style>
         
-        
-        <Style x:Key="PlaceHolderText" TargetType="TextBox">
-            <Style.Triggers>
-                <DataTrigger Binding="{Binding Path=ReadOnly,ElementName=Control}" Value="True">
-                    <Setter Property="IsEnabled" Value="False"/>
-                </DataTrigger>
-            </Style.Triggers>
-        </Style>
-
-        
     </UserControl.Resources>
     
     <Border 
@@ -83,7 +74,7 @@
                     <Button.Style>
                         <Style TargetType="Button">
                             <Style.Triggers>
-                                <DataTrigger Binding="{Binding Path=ReadOnly,ElementName=Control}" Value="True">
+                                <DataTrigger Binding="{Binding Path=IsEditable,ElementName=Control}" Value="False">
                                     <Setter Property="Visibility" Value="Collapsed"/>
                                 </DataTrigger>
                             </Style.Triggers>
@@ -103,7 +94,7 @@
                     <Button.Style>
                         <Style TargetType="Button">
                             <Style.Triggers>
-                                <DataTrigger Binding="{Binding Path=ReadOnly,ElementName=Control}" Value="True">
+                                <DataTrigger Binding="{Binding Path=IsEditable,ElementName=Control}" Value="False">
                                     <Setter Property="Visibility" Value="Collapsed"/>
                                 </DataTrigger>
                             </Style.Triggers>
@@ -111,29 +102,21 @@
                     </Button.Style>
                 </Button>
                 
-                <Button Margin="0,0,2,0" Height="30" Padding="5,0"
-                        DockPanel.Dock="Right"
-                        x:Name="TemplateButton"
-                        MinWidth="110"
-                        BorderBrush="Gray"
-                        BorderThickness="0.75"
-                        Click="TemplateButton_Click">
-                    <Button.Style>
-                        <Style TargetType="Button">
-                            <Style.Triggers>
-                                <DataTrigger Binding="{Binding Path=ReadOnly,ElementName=Control}" Value="True">
-                                    <Setter Property="IsEnabled" Value="False"/>
-                                </DataTrigger>
-                            </Style.Triggers>
-                        </Style>
-                    </Button.Style>
+                <Button 
+                    Margin="0,0,2,0" 
+                    Height="30" 
+                    Padding="5,0"
+                    DockPanel.Dock="Right"
+                    x:Name="TemplateButton"
+                    MinWidth="110"
+                    BorderBrush="Gray"
+                    BorderThickness="0.75"
+                    Click="TemplateButton_Click"
+                    IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
                 </Button>
                 
                 <TextBox 
                     x:Name="QtyBox"
-                    PreviewTextInput="QtyBox_OnPreviewTextInput"
-                    TextChanged="QtyBox_OnTextChanged"
-                    LostFocus="QtyBox_OnLostFocus"
                     Background="LightYellow"
                     Height="30"
                     Width="50"
@@ -143,8 +126,10 @@
                     VerticalContentAlignment="Center"
                     HorizontalContentAlignment="Center"
                     DockPanel.Dock="Right"
-                    Style="{StaticResource PlaceHolderText}">
+                    Text="{Binding ElementName=Control, Path=Packet.Quantity, Mode=TwoWay}"
+                    IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
                     <behaviors:Interaction.Behaviors>
+                        <wpf:TextBoxIntegerMaskBehavior />
                         <wpf:TextBoxEnterAsTabBehavior />
                         <wpf:TextBoxPlaceholderBehaviour Text="Qty" />
                     </behaviors:Interaction.Behaviors>
@@ -152,28 +137,18 @@
                 
                 <TextBox 
                     x:Name="SerialBox"
-                    TextChanged="SerialBox_TextChanged"
-                    LostFocus="SerialBox_LostFocus"
                     Background="LightYellow"
                     Height="30"
                     Margin="0,0,5,0"
                     Padding="2,0,2,0"
                     VerticalAlignment="Center" VerticalContentAlignment="Center"
                     DockPanel.Dock="Left"
-                    Style="{StaticResource PlaceHolderText}">
+                    Text="{Binding ElementName=Control, Path=Packet.Serial, Mode=TwoWay}"
+                    IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
                     <behaviors:Interaction.Behaviors>
                         <wpf:TextBoxEnterAsTabBehavior />
                         <wpf:TextBoxPlaceholderBehaviour Text="Serial #" />
                     </behaviors:Interaction.Behaviors>
-                    <!-- <TextBox.Style> -->
-                    <!--     <Style TargetType="TextBox"> -->
-                    <!--         <Style.Triggers> -->
-                    <!--             <DataTrigger Binding="{Binding Path=ReadOnly,ElementName=Control}" Value="True"> -->
-                    <!--                 <Setter Property="IsEnabled" Value="False"/> -->
-                    <!--             </DataTrigger> -->
-                    <!--         </Style.Triggers> -->
-                    <!--     </Style> -->
-                    <!-- </TextBox.Style> -->
                 </TextBox>
                 
             </DockPanel>
@@ -189,6 +164,7 @@
                             <RowDefinition Height="Auto" />
                             <RowDefinition Height="Auto" />
                             <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
                         </Grid.RowDefinitions>
                         
                         <Grid.ColumnDefinitions>
@@ -196,27 +172,36 @@
                             <ColumnDefinition Width="*" />
                         </Grid.ColumnDefinitions>
                         
+                        <Label
+                            Grid.Row="0"
+                            Grid.Column="0"
+                            Content="Title"
+                            VerticalContentAlignment="Center"/>
                         
                         <TextBox 
                             x:Name="TitleBox"
                             Grid.Row="0"
-                            Grid.Column="0"
-                            Grid.ColumnSpan="2"
-                            TextChanged="TitleBox_TextChanged"
-                            LostFocus="TitleBox_LostFocus"
+                            Grid.Column="1"
+
                             Background="LightYellow"
                             Height="30"
                             Margin="2,0,2,0"
                             Padding="2,0,2,0"
                             VerticalAlignment="Center" 
                             VerticalContentAlignment="Center"
-                            Style="{StaticResource PlaceHolderText}">
+                            Text="{Binding ElementName=Control, Path=Packet.Title, Mode=TwoWay}"
+                            IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
                             <behaviors:Interaction.Behaviors>
                                 <wpf:TextBoxEnterAsTabBehavior />
-                                <wpf:TextBoxPlaceholderBehaviour Text="Enter Title" />
                             </behaviors:Interaction.Behaviors>
                         </TextBox>
                         
+                        <Label
+                            Grid.Row="1"
+                            Grid.Column="0"
+                            Content="ITP"
+                            VerticalContentAlignment="Center"/>
+                        
                         <DockPanel
                             Grid.Row="1"
                             Grid.Column="1"
@@ -232,10 +217,10 @@
                                 Padding="2,0,2,0"
                                 VerticalContentAlignment="Center"
                                 DockPanel.Dock="Left"
-                                Style="{StaticResource PlaceHolderText}">
+                                Text="{Binding ElementName=Control, Path=Packet.ITP.Code, Mode=TwoWay}"
+                                IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
                                 <behaviors:Interaction.Behaviors>
                                     <wpf:TextBoxEnterAsTabBehavior />
-                                    <wpf:TextBoxPlaceholderBehaviour Text="ITP Code" />
                                 </behaviors:Interaction.Behaviors>
                             </TextBox>
                             
@@ -248,7 +233,8 @@
                                 Margin="5,0,0,0"
                                 BorderBrush="Gray"
                                 BorderThickness="0.75"
-                                Click="ITPLookup_Click"/>
+                                Click="ITPLookup_Click"
+                                IsEnabled="{Binding ElementName=Control, Path=IsEditable}"/>
                                 
                             <TextBox
                                 x:Name="ITPDescription"
@@ -256,48 +242,85 @@
                                 DockPanel.Dock="Right"
                                 Margin="5,0,0,0"
                                 Padding="2,0,2,0"
-                                IsReadOnly="True"
+                                IsEnabled="False"
                                 Background="WhiteSmoke"/>
                             
                         </DockPanel>
                         
+                        <Label
+                            Grid.Row="2"
+                            Grid.Column="0"
+                            Content="Location"
+                            VerticalContentAlignment="Center"/>
+                        
                         <TextBox 
                             x:Name="LocationBox"
                             Grid.Row="2"
                             Grid.Column="1"
-                            TextChanged="LocationBox_TextChanged"
-                            LostFocus="LocationBox_LostFocus"
                             Background="LightYellow"
                             Height="30"
                             Margin="2,5,2,0"
                             Padding="2,0,2,0"
                             VerticalAlignment="Center" 
                             VerticalContentAlignment="Center"
-                            Style="{StaticResource PlaceHolderText}">
+                            Text="{Binding ElementName=Control, Path=Packet.Location, Mode=TwoWay}"
+                            IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
                             <behaviors:Interaction.Behaviors>
                                 <wpf:TextBoxEnterAsTabBehavior />
-                                <wpf:TextBoxPlaceholderBehaviour Text="Enter Location" />
                             </behaviors:Interaction.Behaviors>
                         </TextBox>
+                                                
+                        <Label
+                            Grid.Row="3"
+                            Grid.Column="0"
+                            Content="Watermark"
+                            VerticalContentAlignment="Center"/>
                         
                         <TextBox 
                             x:Name="WatermarkBox"
                             Grid.Row="3"
                             Grid.Column="1"
-                            TextChanged="WatermarkBox_TextChanged"
-                            LostFocus="WatermarkBox_LostFocus"
                             Background="LightYellow"
                             Height="30"
                             Margin="2,5,2,0"
                             Padding="2,0,2,0"
                             VerticalAlignment="Center" 
                             VerticalContentAlignment="Center"
-                            Style="{StaticResource PlaceHolderText}">
+                            Text="{Binding ElementName=Control, Path=Packet.Watermark, Mode=TwoWay}"
+                            IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
+                            <behaviors:Interaction.Behaviors>
+                                <wpf:TextBoxEnterAsTabBehavior />
+                                <wpf:TextBoxPlaceholderBehaviour Text="{Binding ElementName=Control, Path=Packet.Group.Watermark}" />
+                            </behaviors:Interaction.Behaviors>
+                        </TextBox>
+                        
+                                                
+                        <Label
+                            Grid.Row="4"
+                            Grid.Column="0"
+                            Content="Barcodes"
+                            VerticalContentAlignment="Center"/>
+                        
+                        <TextBox 
+                            Grid.Row="4"
+                            Grid.Column="1"
+                            x:Name="BarcodeQtyBox"
+                            DockPanel.Dock="Right"
+                            Background="LightYellow"
+                            Height="30"
+                            Margin="5,5,2,0"
+                            Padding="2,0,2,0"
+                            VerticalAlignment="Center" 
+                            VerticalContentAlignment="Center"
+                            Text="{Binding ElementName=Control, Path=Packet.BarcodeQuantity, Mode=TwoWay}"
+                            IsEnabled="{Binding ElementName=Control, Path=IsEditable}">
                             <behaviors:Interaction.Behaviors>
                                 <wpf:TextBoxEnterAsTabBehavior />
-                                <wpf:TextBoxPlaceholderBehaviour Text="Enter Watermark" />
+                                <wpf:TextBoxIntegerMaskBehavior />
+                                <wpf:TextBoxPlaceholderBehaviour x:Name="BarcodeQtyPlaceHolder" Text="{Binding ElementName=Control, Path=Packet.Quantity}" />
                             </behaviors:Interaction.Behaviors>
                         </TextBox>
+
                         
                     </Grid>
                 </dynamicGrid:DynamicTabItem>
@@ -306,21 +329,24 @@
                     <local:StagingManufacturingPacketStageGrid
                         x:Name="StagesGrid" 
                         AfterRefresh="DetailGrid_OnAfterRefresh"  
-                        OnChanged="DetailGrid_OnOnChanged"/>
+                        OnChanged="DetailGrid_OnOnChanged"
+                        IsEnabled="{Binding ElementName=Control, Path=IsEditable}"/>
                 </dynamicGrid:DynamicTabItem>
                 
                 <dynamicGrid:DynamicTabItem Header="Components" Background="WhiteSmoke">
                     <local:StagingManufacturingPacketComponentGrid
                         x:Name="ComponentGrid"
                         AfterRefresh="DetailGrid_OnAfterRefresh"
-                        OnChanged="DetailGrid_OnOnChanged"/>
+                        OnChanged="DetailGrid_OnOnChanged"
+                        IsEnabled="{Binding ElementName=Control, Path=IsEditable}"/>
                 </dynamicGrid:DynamicTabItem>
                 
                 <dynamicGrid:DynamicTabItem Header="Treatments" Background="WhiteSmoke">
                     <local:StagingManufacturingPacketTreatmentGrid
                         x:Name="TreatmentGrid"
                         AfterRefresh="DetailGrid_OnAfterRefresh"
-                        OnChanged="DetailGrid_OnOnChanged"/>
+                        OnChanged="DetailGrid_OnOnChanged"
+                        IsEnabled="{Binding ElementName=Control, Path=IsEditable}"/>
                 </dynamicGrid:DynamicTabItem>
                 
             </dynamicGrid:DynamicTabControl>

+ 136 - 130
prs.desktop/Panels/Staging/Manufacturing/StagingManufacturingPacketListItem.xaml.cs

@@ -22,16 +22,13 @@ namespace PRSDesktop
             "Collapsed", typeof(bool), typeof(StagingManufacturingPacketListItem),
             new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(OnCollapsedChanged)));
 
-        public static readonly DependencyProperty ReadOnlyProperty = DependencyProperty.Register(
-            "ReadOnly", typeof(bool), typeof(StagingManufacturingPacketListItem),
-            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(OnReadOnlyChanged)));
-
+        
         /// <summary>
         /// Height of the uncollapsed stages grid.
         /// </summary>
         public static readonly DependencyProperty StagesGridHeightProperty = DependencyProperty.Register(
             "StagesGridHeight", typeof(double), typeof(StagingManufacturingPacketListItem),
-            new FrameworkPropertyMetadata(200.0));
+            new FrameworkPropertyMetadata(205.0));
 
         private static BitmapImage collapsedImg = PRSDesktop.Resources.rightarrow.ToBitmapImage();
         private static BitmapImage uncollapsedImg = PRSDesktop.Resources.downarrow.ToBitmapImage();
@@ -43,14 +40,9 @@ namespace PRSDesktop
 
         //private StagingManufacturingPacketStageGrid StagesGrid;
 
-        public event EventHandler Changed;
-
-        private bool _serialChanged = false;
-        private bool _titleChanged = false;
-        private bool _locationChanged = false;
-        private bool _watermarkChanged = false;
+        public event EventHandler? Changed;
+        
         private bool _itpChanged = false;
-        private bool _qtychanged = false;
         
         public TimeSpan TimeRequired()
         {
@@ -72,16 +64,26 @@ namespace PRSDesktop
             get => (double)GetValue(StagesGridHeightProperty);
             set => SetValue(StagesGridHeightProperty, value);
         }
-
-        public bool ReadOnly
+        
+        public static readonly DependencyProperty IsEditableProperty = DependencyProperty.Register(
+            nameof(IsEditable), typeof(bool), typeof(StagingManufacturingPacketListItem),
+            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.None));
+        
+        public bool IsEditable
         {
-            get => (bool)GetValue(ReadOnlyProperty);
-            set => SetValue(ReadOnlyProperty, value);
+            get => (bool)GetValue(IsEditableProperty);
+            set => SetValue(IsEditableProperty, value);
         }
-
+        
         public StagingManufacturingPacketListItem(StagingManufacturingPacket packet, bool collapsed)
         {
             Packet = packet;
+            Packet.PropertyChanged += (sender, args) =>
+            {
+                SaveTemplate();
+                if (String.Equals(args.PropertyName, nameof(StagingManufacturingPacket.Quantity)))
+                    BarcodeQtyPlaceHolder.Text = packet.Quantity.ToString();
+            };
 
             InitializeComponent();
 
@@ -91,25 +93,10 @@ namespace PRSDesktop
             ComponentGrid.Packet = Packet;
             TreatmentGrid.Packet = Packet;
             
-            SerialBox.Text = Packet.Serial;
-            _serialChanged = false;
-
-            TitleBox.Text = Packet.Title;
-            _titleChanged = false;
-
             ITPCode.Text = Packet.ITP.Code;
             ITPDescription.Text = Packet.ITP.Description;
             _itpChanged = false;
             
-            LocationBox.Text = Packet.Location;
-            _locationChanged = false;
-            
-            WatermarkBox.Text = Packet.Watermark;
-            _watermarkChanged = false;
-            
-            QtyBox.Text = Packet.Quantity.ToString();
-            _qtychanged = false;
-
             if (collapsed)
             {
                 Collapse();
@@ -119,7 +106,7 @@ namespace PRSDesktop
                 Uncollapse();
             }
 
-            ReadOnly = packet.ManufacturingPacket.ID != Guid.Empty;
+            IsEditable = packet.ManufacturingPacket.ID == Guid.Empty;
         }
 
         private void EditButton_Click(object sender, RoutedEventArgs e)
@@ -229,23 +216,7 @@ namespace PRSDesktop
                 UpdateTemplateButton();
             }
         }
-
-        private void SerialBox_TextChanged(object sender, TextChangedEventArgs e)
-        {
-            _serialChanged = true;
-        }
-
-        private void SerialBox_LostFocus(object sender, RoutedEventArgs e)
-        {
-            if (_serialChanged)
-            {
-                Packet.Serial = SerialBox.Text;
-                SaveTemplate();
-                _serialChanged = false;
-                Changed?.Invoke(this, EventArgs.Empty); 
-            }
-        }
-
+        
         private void Collapse()
         {
             CollapseButton.Content = new Image { Source = collapsedImg };
@@ -276,40 +247,52 @@ namespace PRSDesktop
             }
         }
 
-        private static void OnReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
-        {
-            var item = (StagingManufacturingPacketListItem)d;
-            var readOnly = (bool)e.NewValue;
-            item.StagesGrid.ReadOnly = readOnly;
-            item.ComponentGrid.ReadOnly = readOnly;
-            item.TreatmentGrid.ReadOnly = readOnly;
-            item.TitleBox.IsReadOnly = !readOnly;
-            item.ITPCode.IsReadOnly = !readOnly;
-            item.LocationBox.IsReadOnly = !readOnly;
-        }
 
-        private void QtyBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
-        {
-            if (!int.TryParse(e.Text, out int _))
-                e.Handled = true;
-        }
         
-        private void QtyBox_OnTextChanged(object sender, TextChangedEventArgs e)
-        {
-            _qtychanged = true;
-        }
-
-        private void QtyBox_OnLostFocus(object sender, RoutedEventArgs e)
-        {
-            if (_qtychanged)
-            {
-                int.TryParse(QtyBox.Text, out int qty);
-                Packet.Quantity = qty;
-                SaveTemplate();
-                _qtychanged = false;
-                Changed?.Invoke(this, EventArgs.Empty); 
-            }
-        }
+        
+        // private void SerialBox_TextChanged(object sender, TextChangedEventArgs e)
+        // {
+        //     _serialChanged = true;
+        // }
+        //
+        // private void SerialBox_LostFocus(object sender, RoutedEventArgs e)
+        // {
+        //     if (_serialChanged)
+        //     {
+        //         Packet.Serial = SerialBox.Text;
+        //         SaveTemplate();
+        //         _serialChanged = false;
+        //         Changed?.Invoke(this, EventArgs.Empty); 
+        //     }
+        // }
+        //
+        // private void QtyBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
+        // {
+        //     if (!int.TryParse(e.Text, out int _))
+        //         e.Handled = true;
+        // }
+        //
+        // private void QtyBox_OnTextChanged(object sender, TextChangedEventArgs e)
+        // {
+        //     _qtychanged = true;
+        //     if (String.IsNullOrWhiteSpace(BarcodeQtyBox.Text) || String.Equals(QtyBox.Text, BarcodeQtyBox.Text))
+        //     {
+        //         BarcodeQtyBox.Text = QtyBox.Text;
+        //         _barcodeQtyChanged = false;
+        //     }
+        // }
+        //
+        // private void QtyBox_OnLostFocus(object sender, RoutedEventArgs e)
+        // {
+        //     if (_qtychanged)
+        //     {
+        //         int.TryParse(QtyBox.Text, out int qty);
+        //         Packet.Quantity = qty;
+        //         SaveTemplate();
+        //         _qtychanged = false;
+        //         Changed?.Invoke(this, EventArgs.Empty); 
+        //     }
+        // }
 
         private void DetailGrid_OnAfterRefresh(object sender, AfterRefreshEventArgs args)
         {
@@ -321,54 +304,21 @@ namespace PRSDesktop
             Changed?.Invoke(this, EventArgs.Empty);
         }
 
-        private void TitleBox_TextChanged(object sender, TextChangedEventArgs e)
-        {
-            _titleChanged = true;
-        }
-        
-        private void TitleBox_LostFocus(object sender, RoutedEventArgs e)
-        {
-            if (_titleChanged)
-            {
-                Packet.Title = TitleBox.Text;
-                SaveTemplate();
-                Changed?.Invoke(this, EventArgs.Empty); 
-                _titleChanged = false;
-            }
-        }
-        
-        private void LocationBox_TextChanged(object sender, TextChangedEventArgs e)
-        {
-            _locationChanged = true;
-        }
-
-        private void LocationBox_LostFocus(object sender, RoutedEventArgs e)
-        {
-            if (_locationChanged)
-            {
-                Packet.Location = LocationBox.Text;
-                SaveTemplate();
-                _locationChanged = false;
-                Changed?.Invoke(this, EventArgs.Empty); 
-            }
-        }
-        
-                
-        private void WatermarkBox_TextChanged(object sender, TextChangedEventArgs e)
-        {
-            _watermarkChanged = true;
-        }
-
-        private void WatermarkBox_LostFocus(object sender, RoutedEventArgs e)
-        {
-            if (_watermarkChanged)
-            {
-                Packet.Watermark = WatermarkBox.Text;
-                SaveTemplate();
-                _watermarkChanged = false;
-                Changed?.Invoke(this, EventArgs.Empty); 
-            }
-        }
+        // private void TitleBox_TextChanged(object sender, TextChangedEventArgs e)
+        // {
+        //     _titleChanged = true;
+        // }
+        //
+        // private void TitleBox_LostFocus(object sender, RoutedEventArgs e)
+        // {
+        //     if (_titleChanged)
+        //     {
+        //         Packet.Title = TitleBox.Text;
+        //         SaveTemplate();
+        //         Changed?.Invoke(this, EventArgs.Empty); 
+        //         _titleChanged = false;
+        //     }
+        // }
         
         private void ITPCode_TextChanged(object sender, TextChangedEventArgs e)
         {
@@ -450,5 +400,61 @@ namespace PRSDesktop
             return result;
         }
         
+        // private void LocationBox_TextChanged(object sender, TextChangedEventArgs e)
+        // {
+        //     _locationChanged = true;
+        // }
+        //
+        // private void LocationBox_LostFocus(object sender, RoutedEventArgs e)
+        // {
+        //     if (_locationChanged)
+        //     {
+        //         Packet.Location = LocationBox.Text;
+        //         SaveTemplate();
+        //         _locationChanged = false;
+        //         Changed?.Invoke(this, EventArgs.Empty); 
+        //     }
+        // }
+        //
+        //         
+        // private void WatermarkBox_TextChanged(object sender, TextChangedEventArgs e)
+        // {
+        //     _watermarkChanged = true;
+        // }
+        //
+        // private void WatermarkBox_LostFocus(object sender, RoutedEventArgs e)
+        // {
+        //     if (_watermarkChanged)
+        //     {
+        //         Packet.Watermark = WatermarkBox.Text;
+        //         SaveTemplate();
+        //         _watermarkChanged = false;
+        //         Changed?.Invoke(this, EventArgs.Empty); 
+        //     }
+        // }
+        //
+        // private void BarcodeQtyBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
+        // {
+        //     if (!int.TryParse(e.Text, out int _))
+        //         e.Handled = true;
+        // }
+        //
+        // private void BarcodeQtyBox_TextChanged(object sender, TextChangedEventArgs e)
+        // {
+        //     _barcodeQtyChanged = true;
+        // }
+        //
+        // private void BarcodeQtyBox_LostFocus(object sender, RoutedEventArgs e)
+        // {
+        //     if (_barcodeQtyChanged)
+        //     {
+        //         int.TryParse(BarcodeQtyBox.Text, out int barcodes);
+        //         Packet.BarcodeQuantity = barcodes;
+        //         SaveTemplate();
+        //         _barcodeQtyChanged = false;
+        //         Changed?.Invoke(this, EventArgs.Empty); 
+        //     }
+        //
+        // }
     }
 }

+ 13 - 11
prs.desktop/Panels/Staging/Manufacturing/StagingManufacturingPacketStageGrid.cs

@@ -4,6 +4,7 @@ using InABox.Core;
 using InABox.DynamicGrid;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -24,19 +25,20 @@ namespace PRSDesktop
             }
         }
 
-        private bool _readOnly = false;
-        public bool ReadOnly
-        {
-            get => _readOnly;
-            set
-            {
-                _readOnly = value;
-                Reconfigure();
-            }
-        }
+        // private bool _readOnly = false;
+        // public bool ReadOnly
+        // {
+        //     get => _readOnly;
+        //     set
+        //     {
+        //         _readOnly = value;
+        //         Reconfigure();
+        //     }
+        // }
 
         public StagingManufacturingPacketStageGrid()
         {
+            IsEnabledChanged += (sender, args) => Reconfigure();
             Refresh(true, false);
         }
 
@@ -54,7 +56,7 @@ namespace PRSDesktop
                 .Clear()
                 .Add(DynamicGridOption.SelectColumns);
             
-            if ((Packet.ID != Guid.Empty) && !ReadOnly)
+            if ((Packet.ID != Guid.Empty) && IsEnabled)
             {
                 options.Add(DynamicGridOption.AddRows);
                 options.Add(DynamicGridOption.EditRows);

+ 12 - 11
prs.desktop/Panels/Staging/Manufacturing/StagingManufacturingPacketTreatmentGrid.cs

@@ -19,19 +19,20 @@ public class StagingManufacturingPacketTreatmentGrid : DynamicDataGrid<StagingMa
         }
     }
         
-    private bool _readOnly = false;
-    public bool ReadOnly
-    {
-        get => _readOnly;
-        set
-        {
-            _readOnly = value;
-            Reconfigure();
-        }
-    }
+    // private bool _readOnly = false;
+    // public bool ReadOnly
+    // {
+    //     get => _readOnly;
+    //     set
+    //     {
+    //         _readOnly = value;
+    //         Reconfigure();
+    //     }
+    // }
 
     public StagingManufacturingPacketTreatmentGrid()
     {
+        IsEnabledChanged += (sender, args) => Reconfigure(); 
         HiddenColumns.Add(x=>x.Product.Code);
         Refresh(true, false);
     }
@@ -44,7 +45,7 @@ public class StagingManufacturingPacketTreatmentGrid : DynamicDataGrid<StagingMa
             .Clear()
             .Add(DynamicGridOption.SelectColumns);
 
-        if ((Packet.ID != Guid.Empty) && !ReadOnly)
+        if ((Packet.ID != Guid.Empty) && IsEnabled)
         {
             options.Add(DynamicGridOption.AddRows);
             options.Add(DynamicGridOption.EditRows);

+ 7 - 2
prs.desktop/Panels/Staging/StagingPanel.xaml.cs

@@ -430,6 +430,7 @@ public class Module
                         .Add(x => x.Quantity)
                         .Add(x => x.BarcodeQuantity)
                         .Add(x => x.Watermark)
+                        .Add(x => x.Group.Watermark)
                         .Add(x => x.Location)
                         .Add(x => x.ITP.ID)
                         .Add(x => x.Job.ID)
@@ -447,8 +448,12 @@ public class Module
                     Serial = stagingPacket.Serial,
                     Title = stagingPacket.Title,
                     Quantity = stagingPacket.Quantity,
-                    BarcodeQty = stagingPacket.BarcodeQuantity != 0 ? stagingPacket.BarcodeQuantity : stagingPacket.Quantity,
-                    WaterMark = stagingPacket.Watermark,
+                    BarcodeQty = String.IsNullOrWhiteSpace(stagingPacket.BarcodeQuantity) 
+                        ? stagingPacket.Quantity 
+                        : int.Parse(stagingPacket.BarcodeQuantity),
+                    WaterMark = String.IsNullOrWhiteSpace(stagingPacket.Watermark) 
+                        ? stagingPacket.Group.Watermark
+                        : stagingPacket.Watermark,
                     Location = stagingPacket.Location
                 };
                 packet.SetoutLink.ID = setout.ID;

+ 15 - 9
prs.stores/PurchaseOrderItemStore.cs

@@ -244,16 +244,22 @@ namespace Comal.Stores
         protected override void AfterSave(PurchaseOrderItem entity)
         {
             base.AfterSave(entity);
-
-            if (entity.ReceivedDate == DateTime.MinValue && entity.HasOriginalValue<PurchaseOrderItem>("ReceivedDate"))
-            {                 
-                if(DateTime.Parse(entity.OriginalValues["ReceivedDate"].ToString()) != entity.ReceivedDate)
-                    DeleteStockMovements(entity);
-            }            
-            else if(!entity.ReceivedDate.IsEmpty())
+            
+            if (entity.HasOriginalValue<PurchaseOrderItem,DateTime>(x=>x.ReceivedDate))
             {
-                UpdateStockMovements(entity);
-                UpdateJobRequiItems(entity);
+                if (entity.ReceivedDate.IsEmpty())
+                    DeleteStockMovements(entity);
+                else
+                {
+                    var item = Provider
+                        .Query(new Filter<PurchaseOrderItem>(x => x.ID).IsEqualTo(entity.ID))
+                        .Rows.FirstOrDefault()?.ToObject<PurchaseOrderItem>();
+                    if (item != null)
+                    {
+                        UpdateStockMovements(item);
+                        UpdateJobRequiItems(item);
+                    }
+                }
             }
         }