Quellcode durchsuchen

Improvements to Mobile Warehouse Stocktake Module

frogsoftware vor 2 Monaten
Ursprung
Commit
afcfb1e0e1

+ 5 - 4
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseReceive/WarehouseReceiveViewModel.cs

@@ -1,3 +1,4 @@
+using System;
 using System.Threading.Tasks;
 using Comal.Classes;
 using CommunityToolkit.Mvvm.ComponentModel;
@@ -18,15 +19,15 @@ public partial class WarehouseReceiveViewModel : ModuleViewModel
     {
         Consignments = new ConsignmentModel(
             DataAccess, 
-            () => new Filter<Consignment>().All(),
+            () => new Filter<Consignment>(x=>x.Closed).IsEqualTo(DateTime.MinValue).And(x=>x.UnreceivedItems).IsNotEqualTo(0),
             () => DefaultCacheFileName<ConsignmentShell>()
         );
     }
 
-    protected override Task OnActivated()
+    protected override async Task OnActivated()
     {
-        Consignments.Refresh(false);
-        return base.OnActivated();
+        await Consignments.RefreshAsync(true);
+        await base.OnActivated();
     }
 
     [RelayCommand]

+ 12 - 12
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseStockTake/WarehouseStockTakeEditView.axaml

@@ -61,12 +61,12 @@
             Classes="Standard"
             Grid.Row="1"
             Grid.Column="0"
-            Padding="5,0"
+            Padding="5"
             Background="{StaticResource PrsSurfaceBackground}">
             <Label 
                 HorizontalAlignment="Stretch" 
                 Content="{Binding Holding.ProductDisplay, FallbackValue='', Converter={StaticResource ProductDefaultConverter}}"
-                FontSize="{StaticResource PrsFontSizeSmall}"
+                FontSize="{StaticResource PrsFontSizeNormal}"
                 Foreground="{StaticResource PrsSurfaceForeground}"
                 VerticalContentAlignment="Center"/>
         </Border>
@@ -78,18 +78,18 @@
             IsEnabled="{Binding NewHolding}"
             Command="{Binding SelectProductCommand}"
             Content="{SvgImage /Images/lines.svg}"
-            Padding="0"/>
+            Padding="5"/>
         
         <Border 
             Classes="Standard"
             Grid.Row="3"
             Grid.Column="0"
-            Padding="5,0"
+            Padding="5"
             Background="{StaticResource PrsSurfaceBackground}">
             <Label 
                 HorizontalAlignment="Stretch" 
                 Content="{Binding Holding.DimensionsUnitSize, FallbackValue='', Converter={StaticResource DimensionsDefaultConverter}}"
-                FontSize="{StaticResource PrsFontSizeSmall}"
+                FontSize="{StaticResource PrsFontSizeNormal}"
                 Foreground="{StaticResource PrsSurfaceForeground}"
                 VerticalContentAlignment="Center"
             />
@@ -102,18 +102,18 @@
             IsEnabled="{Binding NewHolding}"
             Command="{Binding EditDimensionsCommand}"
             Content="{SvgImage /Images/lines.svg}" 
-            Padding="0"/>
+            Padding="5"/>
         
         <Border
             Classes="Standard"
             Grid.Row="2"
             Grid.Column="0"
-            Padding="5,0"
+            Padding="5"
             Background="{StaticResource PrsSurfaceBackground}">
             <Label 
                 HorizontalAlignment="Stretch" 
                 Content="{Binding Holding.StyleDescription, FallbackValue='', Converter={StaticResource StyleDefaultConverter}}"
-                FontSize="{StaticResource PrsFontSizeSmall}"
+                FontSize="{StaticResource PrsFontSizeNormal}"
                 Foreground="{StaticResource PrsSurfaceForeground}"
                 VerticalContentAlignment="Center" />
         </Border>
@@ -124,19 +124,19 @@
             Grid.Column="1"
             IsEnabled="{Binding NewHolding}"
             Content="{SvgImage /Images/lines.svg}"
-            Padding="0"
+            Padding="5"
             Command="{Binding SelectStyleCommand}" />
         
         <Border
             Classes="Standard"
             Grid.Row="4"
             Grid.Column="0"
-            Padding="5,0"
+            Padding="5"
             Background="{StaticResource PrsSurfaceBackground}">
             <Label 
                 HorizontalAlignment="Stretch" 
                 Content="{Binding Holding.JobDisplay, FallbackValue='', Converter={StaticResource JobDefaultConverter}}"
-                FontSize="{StaticResource PrsFontSizeSmall}"
+                FontSize="{StaticResource PrsFontSizeNormal}"
                 Foreground="{StaticResource PrsSurfaceForeground}"
                 VerticalContentAlignment="Center"
             />
@@ -148,7 +148,7 @@
             Grid.Column="1"
             IsEnabled="{Binding NewHolding}"
             Content="{SvgImage /Images/lines.svg}"
-            Padding="0"
+            Padding="5"
             Command="{Binding SelectJobCommand}" />
         
         <Button

+ 10 - 5
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseStockTake/WarehouseStockTakeEditViewModel.cs

@@ -352,9 +352,9 @@ public partial class WarehouseStockTakeEditViewModel : ModuleViewModel
             return false;
         
         var _batch = await GetBatch();
-        
-        
-        var _movement = Movements.FirstOrDefault(x=>
+
+
+        var _movement = Movements.FirstOrDefault(x =>
             x.LocationID == Holding.LocationID
             && x.ProductID == Holding.ProductID
             && x.StyleID == Holding.StyleID
@@ -390,8 +390,13 @@ public partial class WarehouseStockTakeEditViewModel : ModuleViewModel
         }
         
         _movement.Date = DateTime.Now;
-        
-        var _delta = Holding.Units - (Holding.Entity.HasOriginalValue(x=>x.Units) ? Holding.Entity.GetOriginalValue(x=>x.Units) : Holding.Units);
+
+        var hunits = Holding.Units;
+        var orig_hunits = Holding.Entity.HasOriginalValue(x => x.Units)
+            ? Holding.Entity.GetOriginalValue(x => x.Units)
+            : Holding.Units;
+        var munits = _movement.Units;
+        var _delta = hunits - (orig_hunits - munits);
         _movement.Issued = _delta.IsEffectivelyLessThan(0.0) ? Math.Abs(_delta) : 0.0;
         _movement.Received = _delta.IsEffectivelyGreaterThan(0.0) ? _delta : 0.0;
         

+ 33 - 21
PRS.Avalonia/PRS.Avalonia/Modules/WarehouseModule/WarehouseStockTake/WarehouseStockTakeViewModel.cs

@@ -70,23 +70,16 @@ public partial class WarehouseStockTakeViewModel : ModuleViewModel
             return;
         
         bDisableAreaChangedSave = true;
-
+        
+        Units.Refresh(false);
         Holdings.Refresh(false);
         Batches.Refresh(false);
         Movements.Refresh(false);
         Areas.Refresh(false);
         Documents.Refresh(false);
         
-        // Task[] _tasks =
-        // [
-        //     Holdings.RefreshAsync(false), 
-        //     Batches.RefreshAsync(false),
-        //     Movements.RefreshAsync(false),
-        //     Areas.RefreshAsync(false),
-        //     Documents.RefreshAsync(false),
-        // ];
-        // Task.WaitAll(_tasks);
-
+        CheckDeletedHoldings();
+        
         Batch = Batches.FirstOrDefault();
         
         // On the off chance that there is more than one batch, lets limit this to the first batch only
@@ -136,17 +129,23 @@ public partial class WarehouseStockTakeViewModel : ModuleViewModel
         );
         
         Batches = new(DataAccess,
-            () => new Filter<StockMovementBatch>(x => x.ID).IsEqualTo(Location?.StocktakeId ?? CoreUtils.FullGuid),
+            () => Location == null || Location.StocktakeId == Guid.Empty 
+                ? new Filter<StockMovementBatch>().None() 
+                : new Filter<StockMovementBatch>(x=>x.ID).IsEqualTo(Location.StocktakeId),
             null //() => DefaultCacheFileName<StockMovementBatchShell>(Location?.ID ?? Guid.Empty)
         );
 
         Movements = new(DataAccess,
-            () => new Filter<StockMovement>(x=>x.Batch.ID).IsEqualTo(Location?.StocktakeId ?? CoreUtils.FullGuid),
-            null //() => DefaultCacheFileName<StockMovement>(Location?.ID ?? Guid.Empty)
+            () => Location == null || Location.StocktakeId == Guid.Empty 
+                ? new Filter<StockMovement>().None() 
+                : new Filter<StockMovement>(x=>x.Batch.ID).IsEqualTo(Location.StocktakeId),
+            null 
         );
         
         Documents = new(DataAccess,
-            () => new Filter<StockMovementBatchDocument>(x=>x.EntityLink.ID).IsEqualTo(Location?.StocktakeId ?? CoreUtils.FullGuid),
+            () => Location == null || Location.StocktakeId == Guid.Empty 
+                ? new Filter<StockMovementBatchDocument>().None() 
+                : new Filter<StockMovementBatchDocument>(x=>x.EntityLink.ID).IsEqualTo(Location.StocktakeId),
             null //() => DefaultCacheFileName<StockMovementBatchDocumentShell>(Location?.ID ?? Guid.Empty)
         );
         
@@ -156,9 +155,10 @@ public partial class WarehouseStockTakeViewModel : ModuleViewModel
         );
 
         Holdings = new(DataAccess,
-            () => new Filter<StockHolding>(x => x.Location.ID).IsEqualTo(Location.ID),
+            () => Location == null 
+                ? new Filter<StockHolding>().None() 
+                : new Filter<StockHolding>(x=>x.Location.ID).IsEqualTo(Location.ID),
             null);
-        Holdings.Transactions = new StockTransactions();
         
         _add = new AvaloniaMenuItem(Images.plus, AddHolding);
         PrimaryMenu.Add(_add);
@@ -444,10 +444,19 @@ public partial class WarehouseStockTakeViewModel : ModuleViewModel
     private async Task RefreshHoldingsIncludingDeletedItems()
     {
         await Holdings.RefreshAsync(true);
-        await Units.RefreshAsync(false);
+        CheckDeletedHoldings();
+    }
+
+    private void CheckDeletedHoldings()
+    {
+        
         foreach (var _m in Movements.Items.Where(x=>x.Balance.IsEffectivelyEqual(0.0)))
         {
             var _h = Holdings.CreateItem();
+            _h.LocationID = Location?.ID ?? Guid.Empty;
+            _h.LocationCode = Location?.Code ?? "";
+            _h.LocationDescription = Location?.Description ?? "";
+            
             _h.ProductID = _m.ProductID;
             _h.ProductCode = _m.ProductCode;
             _h.ProductName = _m.ProductName;
@@ -457,11 +466,13 @@ public partial class WarehouseStockTakeViewModel : ModuleViewModel
             _h.JobID = _m.JobID;
             _h.JobNumber = _m.JobNumber;
             _h.JobName = _m.JobName;
-            _h.Units = _m.Issued;
+            _h.Units = 0.0;
             _h.AverageCost = _m.Cost;
-
+            
+            var _u = Units.Items.FirstOrDefault(x=>x.ID == _m.DimensionsUnitID);
             _h.DimensionsUnitID = _m.DimensionsUnitID;
-            var _u = Units.Items.FirstOrDefault();
+            _h.DimensionsUnitFormula = _u?.Formula ?? "";
+            _h.DimensionsUnitFormat = _u?.Format ?? "";
             _h.DimensionsHasWidth = _u?.HasWidth ?? false;
             _h.DimensionsHasLength = _u?.HasLength ?? false;
             _h.DimensionsHasHeight = _u?.HasHeight ?? false;
@@ -474,6 +485,7 @@ public partial class WarehouseStockTakeViewModel : ModuleViewModel
             _h.DimensionsWeight = _m.DimensionsWeight;
             _h.DimensionsQuantity = _m.DimensionsQuantity;
             
+            
             Holdings.CommitItem(_h);
         }
     }

+ 0 - 30
PRS.Avalonia/PRS.Avalonia/Repositories/StockHolding/StockHoldingGroup.cs

@@ -1,30 +0,0 @@
-using System.Collections.Generic;
-
-namespace PRS.Avalonia;
-
-public class StockHoldingGroup
-{
-    public StockHoldingGroup(string unitsize)
-    {
-        UnitSize = unitsize;
-    }
-
-    public string UnitSize { get; }
-}
-
-public class StockHoldingGroupEqualityComparer : IEqualityComparer<StockHoldingGroup>
-{
-    public bool Equals(StockHoldingGroup x, StockHoldingGroup y)
-    {
-        if (ReferenceEquals(x, y)) return true;
-        if (ReferenceEquals(x, null)) return false;
-        if (ReferenceEquals(y, null)) return false;
-        if (x.GetType() != y.GetType()) return false;
-        return x.UnitSize == y.UnitSize;
-    }
-
-    public int GetHashCode(StockHoldingGroup obj)
-    {
-        return obj.UnitSize != null ? obj.UnitSize.GetHashCode() : 0;
-    }
-}

+ 4 - 125
PRS.Avalonia/PRS.Avalonia/Repositories/StockHolding/StockHoldingModel.cs

@@ -11,39 +11,13 @@ namespace PRS.Avalonia;
 
 public class StockHoldingModel : CoreRepository<StockHoldingModel, StockHoldingShell, StockHolding>
 {
-    private CoreTable _movements;
-
-    private StockTransactions? _transactions;
-
+    
     public StockHoldingModel(IModelHost host, Func<Filter<StockHolding>> filter, Func<String>? cachefile) : base(host, filter, cachefile)
     {
     }
-
-    public StockHoldingGroup[] UnitSizes { get; private set; }
-
+    
     protected override Expression<Func<StockHolding, object>> ImageColumn => x => x.Product.Image.ID;
-
-    public StockTransactions? Transactions
-    {
-        get => _transactions;
-        set
-        {
-            if (_transactions != null)
-                _transactions.CollectionChanged -= TransactionsChanged;
-            _transactions = value;
-            if (_transactions != null)
-                _transactions.CollectionChanged += TransactionsChanged;
-            UpdateShells(AllItems);
-        }
-    }
-
-    protected override void Initialize()
-    {
-        base.Initialize();
-        UnitSizes = new StockHoldingGroup[] { };
-    }
-
-
+    
     protected override void BeforeLoad(MultiQuery query)
     {
         base.BeforeLoad(query);
@@ -69,100 +43,5 @@ public class StockHoldingModel : CoreRepository<StockHoldingModel, StockHoldingS
             new SortOrder<StockMovement>(x => x.JobRequisitionItem.Requisition.Number)
         );
     }
-
-    protected override void AfterLoad(MultiQuery query)
-    {
-        base.AfterLoad(query);
-
-        UnitSizes = this
-            .Select(x => new StockHoldingGroup(x.DimensionsUnitSize))
-            .Distinct(new StockHoldingGroupEqualityComparer())
-            .OrderBy(x => x.UnitSize)
-            .ToArray();
-
-        _movements = query.Get<StockMovement>();
-    }
-
-    public StockTransactionAllocation[] GetAllocations(StockHoldingShell shell)
-    {
-        List<StockTransactionAllocation> result = null;
-        if (_movements != null)
-        {
-            var movements = _movements.Rows
-                .Where(r =>
-                    r.Get<StockMovement, Guid>(c => c.Product.ID) == shell.ProductID
-                    && r.Get<StockMovement, Guid>(c => c.Job.ID) == shell.JobID
-                    && r.Get<StockMovement, Guid>(c => c.Style.ID) == shell.StyleID
-                    && r.Get<StockMovement, Guid>(c => c.Dimensions.Unit.ID) == shell.DimensionsUnitID
-                    && string.Equals(r.Get<StockMovement, string>(c => c.Dimensions.UnitSize),
-                        shell.DimensionsUnitSize)
-                );
-
-            var groups = movements
-                .GroupBy(r => new Tuple<Guid, Guid, int, string>(
-                    r.Get<StockMovement, Guid>(c => c.JobRequisitionItem.Job.ID),
-                    r.Get<StockMovement, Guid>(c => c.JobRequisitionItem.ID),
-                    r.Get<StockMovement, int>(c => c.JobRequisitionItem.Requisition.Number),
-                    r.Get<StockMovement, string>(c => c.JobRequisitionItem.Requisition.Description)
-                ));
-
-            result = groups
-                .Select(g => new StockTransactionAllocation
-                    {
-                        JobID = g.Key.Item1,
-                        ID = g.Key.Item2,
-                        Description = g.Key.Item2 != Guid.Empty
-                            ? $"{g.Key.Item3}: {g.Key.Item4}"
-                            : "Un-requisitioned items",
-                        Quantity = g.Aggregate(0.0, (t, r) => t += r.Get<StockMovement, double>(c => c.Units)),
-                        Maximum = g.Aggregate(0.0, (t, r) => t += r.Get<StockMovement, double>(c => c.Units))
-                    }
-                ).ToList();
-        }
-        else
-        {
-            result = new List<StockTransactionAllocation>();
-        }
-
-        if (!result.Any(x => x.ID == Guid.Empty))
-        {
-            var balance = result.Aggregate(shell.Units, (t, a) => t -= a.Quantity);
-            result.Insert(0, new StockTransactionAllocation
-            {
-                JobID = Guid.Empty,
-                ID = Guid.Empty,
-                Description = "Un-requisitioned Items",
-                Quantity = balance,
-                Maximum = balance
-            });
-        }
-
-        return result.ToArray();
-    }
-
-    protected override void ItemsChanged(IEnumerable<StockHoldingShell> items)
-    {
-        UpdateShells(items);
-    }
-
-    private void TransactionsChanged(object sender, NotifyCollectionChangedEventArgs e)
-    {
-        UpdateShells(AllItems);
-    }
-
-    public void UpdateShells(IEnumerable<StockHoldingShell> items)
-    {
-
-        foreach (var shell in items)
-        {
-            shell.Transactions.Clear();
-            foreach (var transaction in _transactions.Get(shell))
-                shell.Transactions.Add(transaction);
-
-            // shell.Transactions.ReplaceRange(_transactions != null
-            //     ? _transactions.Get(shell)
-            //     : new StockTransaction[] { });
-        }
-        OnPropertyChanged(nameof(Items));
-    }
+    
 }

+ 5 - 29
PRS.Avalonia/PRS.Avalonia/Repositories/StockHolding/StockHoldingShell.cs

@@ -7,11 +7,6 @@ namespace PRS.Avalonia;
 
 public class StockHoldingShell : Shell<StockHoldingModel, StockHolding>
 {
-    public StockHoldingShell()
-    {
-        Transactions = new ObservableCollection<StockTransaction>();
-        Transactions.CollectionChanged += (sender, args) => { DoPropertyChanged(nameof(Transactions)); };
-    }
 
     public Guid ProductID
     {
@@ -36,11 +31,7 @@ public class StockHoldingShell : Shell<StockHoldingModel, StockHolding>
     public Guid JobID
     {
         get => Get<Guid>();
-        set
-        {
-            Set(value);
-            Parent?.UpdateShells(new[] { this });
-        }
+        set => Set(value);
     }
 
     public string JobNumber
@@ -60,11 +51,7 @@ public class StockHoldingShell : Shell<StockHoldingModel, StockHolding>
     public Guid LocationID
     {
         get => Get<Guid>();
-        set
-        {
-            Set(value);
-            Parent?.UpdateShells(new[] { this });
-        }
+        set => Set(value);
     }
 
     public string LocationCode
@@ -100,11 +87,7 @@ public class StockHoldingShell : Shell<StockHoldingModel, StockHolding>
     public Guid StyleID
     {
         get => Get<Guid>();
-        set
-        {
-            Set(value);
-            Parent?.UpdateShells(new[] { this });
-        }
+        set => Set(value);
     }
 
     public string StyleCode
@@ -221,11 +204,7 @@ public class StockHoldingShell : Shell<StockHoldingModel, StockHolding>
     public string DimensionsUnitSize
     {
         get => Get<string>();
-        set
-        {
-            Set(value);
-            Parent?.UpdateShells(new[] { this });
-        }
+        set => Set(value); 
     }
 
     public Guid ImageID
@@ -267,10 +246,7 @@ public class StockHoldingShell : Shell<StockHoldingModel, StockHolding>
     }
 
     public DateTime LastStocktake => Get<DateTime>();
-
-    public ObservableCollection<StockTransaction> Transactions { get; private set; }
-
-    public StockTransactionAllocation[] Allocations => Parent.GetAllocations(this);
+    
 
     protected override void ConfigureColumns(ShellColumns<StockHoldingModel, StockHolding> columns)
     {

+ 0 - 477
PRS.Avalonia/PRS.Avalonia/Repositories/StockMovementBatch/StockTransaction.cs

@@ -1,477 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using Comal.Classes;
-using CommunityToolkit.Mvvm.ComponentModel;
-using InABox.Avalonia;
-using InABox.Core;
-
-namespace PRS.Avalonia;
-
-public enum StockTransactionType
-{
-    Transfer,
-    Issue,
-    Receive,
-    StockTake
-}
-
-public enum StockTransactionView
-{
-    Source,
-    Target
-}
-
-public enum StockTransactionProperty
-{
-    Location,
-    Style,
-    Job
-}
-
-public partial class StockTransactionHolding : ObservableObject
-{
-    public StockTransactionHolding(StockHoldingShell? shell)
-    {
-        Shell = shell;
-        LocationID = shell?.LocationID ?? Guid.Empty;
-        LocationCode = shell?.LocationCode ?? string.Empty;
-        LocationDescription = shell?.LocationDescription ?? string.Empty;
-        StyleID = shell?.StyleID ?? Guid.Empty;
-        StyleCode = shell?.StyleCode ?? string.Empty;
-        StyleDescription = shell?.StyleDescription ?? string.Empty;
-        JobID = shell?.JobID ?? Guid.Empty;
-        JobNumber = shell?.JobNumber ?? string.Empty;
-        JobName = shell?.JobName ?? string.Empty;
-        Units = shell?.Units ?? 0.0d;
-    }
-
-    public StockHoldingShell? Shell { get; set; }
-    public Guid LocationID { get; set; }
-    public string LocationCode { get; set; }
-    public string LocationDescription { get; set; }
-    public string LocationDisplay => LocationID == Guid.Empty ? "" : $"{LocationCode}: {LocationDescription}";
-
-    public Guid StyleID { get; set; }
-    public string StyleCode { get; set; }
-    public string StyleDescription { get; set; }
-    public string StyleDisplay => StyleID == Guid.Empty ? "" : $"{StyleCode}: {StyleDescription}";
-
-    public Guid JobID { get; set; }
-    public string JobNumber { get; set; }
-    public string JobName { get; set; }
-    public string JobDisplay => JobID == Guid.Empty ? "" : $"{JobNumber}: {JobName}";
-    public double Units { get; set; }
-
-    public bool HasAllocations => !(Shell?.Units ?? 0.0).IsEffectivelyEqual(Shell?.Available ?? 0.0);
-}
-
-public class StockTransactionAllocation : ObservableObject
-{
-    public Guid ID { get; set; }
-
-    public Guid JobID { get; set; }
-
-    public string Description { get; set; }
-
-    public double Quantity { get; set; }
-
-    public double Maximum { get; set; }
-}
-
-public class StockTransaction : ObservableObject
-{
-    private double _dimensionsHeight;
-    private double _dimensionsLength;
-    private double _dimensionsQuantity;
-    private double _dimensionsWeight;
-    private double _dimensionsWidth;
-
-    public StockTransaction(StockTransactionType type, StockHoldingShell? source, StockHoldingShell? target, Guid employeeid)
-    {
-        var shell = source ?? target;
-        Type = type;
-        TransactionID = Guid.NewGuid();
-        EmployeeID = employeeid;
-
-        ProductID = shell?.ProductID ?? Guid.Empty;
-        ProductCode = shell?.ProductCode ?? string.Empty;
-        ProductName = shell?.ProductName ?? string.Empty;
-        ImageID = shell?.ImageID ?? Guid.Empty;
-        Image = shell?.Image ?? new byte[] { };
-        DimensionsUnitID = shell?.DimensionsUnitID ?? Guid.Empty;
-        DimensionsUnitFormat = shell?.DimensionsUnitFormula ?? string.Empty;
-        DimensionsUnitFormula = shell?.DimensionsUnitFormat ?? string.Empty;
-
-        DimensionsQuantity = shell?.DimensionsQuantity ?? 0.0;
-        DimensionsLength = shell?.DimensionsLength ?? 0.0;
-        DimensionsWidth = shell?.DimensionsWidth ?? 0.0;
-        DimensionsHeight = shell?.DimensionsHeight ?? 0.0;
-        DimensionsWeight = shell?.DimensionsWeight ?? 0.0;
-        DimensionsUnitSize = shell?.DimensionsUnitSize ?? string.Empty;
-        DimensionsValue = shell?.DimensionsValue ?? 0.0;
-        Cost = shell?.AverageCost ?? 0.0;
-
-        Source = new StockTransactionHolding(source);
-        Source.PropertyChanged += (sender, args) => OnPropertyChanged(nameof(Source));
-        Target = new StockTransactionHolding(target);
-        Target.PropertyChanged += (sender, args) => OnPropertyChanged(nameof(Target));
-    }
-
-    public StockTransactionType Type { get; set; }
-
-    public Guid TransactionID { get; }
-
-    public Guid EmployeeID { get; }
-
-    public Guid ProductID { get; set; }
-
-    public string ProductCode { get; set; }
-
-    public string ProductName { get; set; }
-
-    public string ProductDisplay => ProductID == Guid.Empty ? "" : $"{ProductCode}: {ProductName}";
-
-    public Guid ImageID { get; set; }
-
-    public byte[]? Image { get; set; }
-
-    public Guid DimensionsUnitID { get; set; }
-
-    public double DimensionsQuantity
-    {
-        get => _dimensionsQuantity;
-        set
-        {
-            _dimensionsQuantity = value;
-            CalculateDimensions();
-        }
-    }
-
-    public double DimensionsLength
-    {
-        get => _dimensionsLength;
-        set
-        {
-            _dimensionsLength = value;
-            CalculateDimensions();
-        }
-    }
-
-    public double DimensionsWidth
-    {
-        get => _dimensionsWidth;
-        set
-        {
-            _dimensionsWidth = value;
-            CalculateDimensions();
-        }
-    }
-
-    public double DimensionsHeight
-    {
-        get => _dimensionsHeight;
-        set
-        {
-            _dimensionsHeight = value;
-            CalculateDimensions();
-        }
-    }
-
-    public double DimensionsWeight
-    {
-        get => _dimensionsWeight;
-        set
-        {
-            _dimensionsWeight = value;
-            CalculateDimensions();
-        }
-    }
-
-    public string DimensionsUnitFormula { get; set; }
-    
-    public string DimensionsUnitFormat { get; set; }
-    
-    public string DimensionsUnitSize { get; set; }
-
-    public double DimensionsValue { get; set; }
-
-    public double Cost { get; set; }
-
-    public StockTransactionAllocation[]? Allocations { get; set; }
-
-    public double Quantity => Allocations?.Aggregate(0.0, (t, a) => t += a.Quantity) ?? 0.0;
-
-    public bool HasAllocations => Allocations?.Any(x => x.ID != Guid.Empty) ?? false;
-
-    public StockTransactionHolding Source { get; private set; }
-
-    public StockTransactionHolding Target { get; private set; }
-
-    public bool LocationChanged => (Source?.LocationID ?? Guid.Empty) != (Target?.LocationID ?? Guid.Empty);
-    public bool StyleChanged => (Source?.StyleID ?? Guid.Empty) != (Target?.StyleID ?? Guid.Empty);
-    public bool JobChanged => (Source?.JobID ?? Guid.Empty) != (Target?.JobID ?? Guid.Empty);
-
-    public void RefreshQuantity()
-    {
-        OnPropertyChanged(nameof(Quantity));
-    }
-
-    private void CalculateDimensions()
-    {
-        //var dimensions = App.Data.ProductDimensionUnits.FirstOrDefault(x => x.ID == DimensionsUnitID);
-        Dictionary<string, object?> variables = new();
-
-        variables["Length"] = DimensionsLength;
-        variables["Width"] = DimensionsWidth;
-        variables["Height"] = DimensionsHeight;
-        variables["Quantity"] = DimensionsQuantity;
-        variables["Weight"] = DimensionsHeight;
-
-        if (!string.IsNullOrWhiteSpace(DimensionsUnitFormat))
-            DimensionsUnitSize = new CoreExpression(DimensionsUnitFormat).Evaluate(variables)?.ToString() ?? string.Empty;
-
-        if (!string.IsNullOrWhiteSpace(DimensionsUnitFormula))
-        {
-            var value = new CoreExpression(DimensionsUnitFormula).Evaluate(variables)?.ToString() ?? "0.0";
-            DimensionsValue = double.TryParse(value, out var val)
-                ? val
-                : 0.0;
-        }
-    }
-
-
-    public string Display(StockTransactionView? view = null)
-    {
-        List<string> results = new();
-
-        if ((Source?.LocationID ?? Guid.Empty) != (Target?.LocationID ?? Guid.Empty))
-        {
-            var location = Type switch
-            {
-                StockTransactionType.Issue => "Issued",
-                StockTransactionType.Receive => "Received",
-                _ => "Transferred"
-            };
-            var fromlocation = "";
-            var tolocation = "";
-
-            if (view == null || view == StockTransactionView.Target)
-                fromlocation = (Source?.LocationID ?? Guid.Empty) != Guid.Empty
-                    ? $" From {Source?.LocationCode ?? "--"}"
-                    : " From --";
-            if (view == null || view == StockTransactionView.Source)
-                tolocation = (Target?.LocationID ?? Guid.Empty) != Guid.Empty
-                    ? $" To {Target?.LocationCode ?? "--"}"
-                    : " To --";
-            results.Add($"{location}{fromlocation}{tolocation}");
-        }
-
-        if ((Source?.StyleID ?? Guid.Empty) != (Target?.StyleID ?? Guid.Empty))
-        {
-            var fromstyle = "";
-            var tostyle = "";
-
-            if (view == null || view == StockTransactionView.Target)
-                fromstyle = (Source?.StyleID ?? Guid.Empty) != Guid.Empty
-                    ? $" From {Source?.StyleCode ?? "(none)"}"
-                    : " From (none)";
-
-            if (view == null || view == StockTransactionView.Source)
-                tostyle = (Target?.StyleID ?? Guid.Empty) != Guid.Empty
-                    ? $" To {Target?.StyleCode ?? "(none)"}"
-                    : " To (none)";
-
-            results.Add($"Changed Style{fromstyle}{tostyle}");
-        }
-
-        if ((Source?.JobID ?? Guid.Empty) != (Target?.JobID ?? Guid.Empty))
-        {
-            var fromjob = "";
-            var tojob = "";
-
-            if (view == null || view == StockTransactionView.Target)
-                fromjob = (Source?.JobID ?? Guid.Empty) != Guid.Empty
-                    ? $" From {Source?.JobNumber ?? "(none)"}"
-                    : " From (none)";
-
-            if (view == null || view == StockTransactionView.Source)
-                tojob = (Target?.JobID ?? Guid.Empty) != Guid.Empty
-                    ? $" To {Target?.JobNumber ?? "(none)"}"
-                    : " To (none)";
-
-            results.Add($"Changed Job{fromjob}{tojob}");
-        }
-
-        return string.Join("\n", results);
-    }
-}
-
-public class StockTransactionImage : ObservableObject
-{
-    public StockTransactionImage(MobileDocument document, byte[] thumbnail)
-    {
-        Document = document;
-        Thumbnail = thumbnail;
-    }
-
-    public MobileDocument Document { get; private set; }
-    public byte[] Thumbnail { get; set; }
-}
-
-public class StockTransactions : ObservableCollection<StockTransaction>
-{
-    public void ProcessTransactions(StockMovementModel model, Guid batchid)
-    {
-        void CreateMovement(
-            StockMovementType type,
-            StockTransaction transaction,
-            Guid locationid,
-            Guid styleid,
-            Guid jobid,
-            DateTime timestamp,
-            TransactionDirection direction,
-            Action<StockTransaction, StockTransactionAllocation, StockMovementShell>? oncreate = null
-        )
-        {
-            foreach (var allocation in transaction.Allocations)
-            {
-                var movement = model.AddItem();
-                movement.BatchID = batchid;
-                movement.Date = timestamp;
-                movement.Type = type;
-                movement.TransactionID = transaction.TransactionID;
-                movement.ProductID = transaction.ProductID;
-                movement.DimensionsUnitID = transaction.DimensionsUnitID;
-                movement.DimensionsQuantity = transaction.DimensionsQuantity;
-                movement.DimensionsLength = transaction.DimensionsLength;
-                movement.DimensionsWidth = transaction.DimensionsWidth;
-                movement.DimensionsHeight = transaction.DimensionsHeight;
-                movement.DimensionsWeight = transaction.DimensionsWeight;
-                movement.DimensionsValue = transaction.DimensionsValue;
-                movement.DimensionsUnitSize = transaction.DimensionsUnitSize;
-                movement.LocationID = locationid;
-                movement.StyleID = styleid;
-                movement.JobID = jobid;
-                movement.RequisitionItemID = allocation.ID;
-                movement.Received = direction == TransactionDirection.Receive ? allocation.Quantity : 0.0F;
-                movement.Issued = direction == TransactionDirection.Issue ? allocation.Quantity : 0.0F;
-                movement.Cost = transaction.Cost;
-                movement.EmployeeID = transaction.EmployeeID;
-                oncreate?.Invoke(transaction, allocation, movement);
-            }
-        }
-
-        var now = DateTime.Now;
-        foreach (var transaction in this)
-            if (transaction.Type == StockTransactionType.Receive)
-            {
-                CreateMovement(
-                    StockMovementType.Receive,
-                    transaction,
-                    transaction.Target.LocationID,
-                    transaction.Target.StyleID,
-                    transaction.Target.JobID,
-                    now,
-                    TransactionDirection.Receive
-                );
-            }
-            else if (transaction.Type == StockTransactionType.Issue)
-            {
-                if (transaction.Source.StyleID != transaction.Target.StyleID ||
-                    transaction.Source.JobID != transaction.Target.JobID)
-                {
-                    CreateMovement(
-                        StockMovementType.TransferOut,
-                        transaction,
-                        transaction.Source.LocationID,
-                        transaction.Source.StyleID,
-                        transaction.Source.JobID,
-                        now,
-                        TransactionDirection.Issue);
-
-                    CreateMovement(
-                        StockMovementType.TransferIn,
-                        transaction,
-                        transaction.Source.LocationID,
-                        transaction.Target.StyleID,
-                        transaction.Target.JobID,
-                        now,
-                        TransactionDirection.Receive);
-                }
-
-                CreateMovement(
-                    StockMovementType.Issue,
-                    transaction,
-                    transaction.Source.LocationID,
-                    transaction.Target.StyleID,
-                    transaction.Target.JobID,
-                    now,
-                    TransactionDirection.Issue);
-            }
-            else if (transaction.Type == StockTransactionType.Transfer)
-            {
-                CreateMovement(
-                    StockMovementType.TransferOut,
-                    transaction,
-                    transaction.Source.LocationID,
-                    transaction.Source.StyleID,
-                    transaction.Source.JobID,
-                    now,
-                    TransactionDirection.Issue);
-                CreateMovement(
-                    StockMovementType.TransferIn,
-                    transaction,
-                    transaction.Target.LocationID,
-                    transaction.Target.StyleID,
-                    transaction.Target.JobID,
-                    now,
-                    TransactionDirection.Receive);
-            }
-            else if (transaction.Type == StockTransactionType.StockTake)
-            {
-                CreateMovement(
-                    StockMovementType.StockTake,
-                    transaction,
-                    transaction.Target.LocationID,
-                    transaction.Target.StyleID,
-                    transaction.Target.JobID,
-                    now,
-                    transaction.Quantity > 0 ? TransactionDirection.Receive : TransactionDirection.Issue,
-                    (t, a, m) =>
-                    {
-                        var srcAlloc = t.Source.Shell.Allocations.FirstOrDefault(x => x.ID == a.ID);
-                        m.Issued = Math.Max(0, (srcAlloc?.Quantity ?? t.Source.Units) - a.Quantity);
-                        m.Received = Math.Max(0, a.Quantity - (srcAlloc?.Quantity ?? t.Source.Units));
-                        m.Notes = m.Issued.IsEffectivelyEqual(0.0F) && m.Received.IsEffectivelyEqual(0.0F)
-                            ? "Correct Quantity Confirmed"
-                            : $"Quantity Adjusted from {srcAlloc?.Quantity ?? t.Source.Units:F2} to {a.Quantity:F2}";
-                        m.Balance = a.Quantity;
-                    }
-                );
-            }
-    }
-
-    public IEnumerable<StockTransaction> Get(StockHoldingShell shell)
-    {
-        bool IsHoldingReferenced(StockTransactionHolding holding)
-        {
-            return holding.LocationID == shell.LocationID
-                   && holding.StyleID == shell.StyleID
-                   && holding.JobID == shell.JobID;
-        }
-
-        var results = this.Where(x => x.ProductID == shell.ProductID
-                                      && string.Equals(x.DimensionsUnitSize, shell.DimensionsUnitSize)
-                                      && (IsHoldingReferenced(x.Source) || IsHoldingReferenced(x.Target))).ToArray();
-
-        return results;
-    }
-
-    private enum TransactionDirection
-    {
-        Issue,
-        Receive
-    }
-}