|
@@ -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
|
|
|
- }
|
|
|
-}
|