StockHoldingModel.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using InABox.Core;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.Linq;
  7. using System.Linq.Expressions;
  8. using Comal.Classes;
  9. using InABox.Mobile;
  10. using Xamarin.Forms.Xaml;
  11. namespace PRS.Mobile
  12. {
  13. public class StockHoldingModel : CoreRepository<StockHoldingModel, StockHoldingShell, StockHolding>
  14. {
  15. public StockHoldingModel(IModelHost host, Func<Filter<StockHolding>> filter): base(host, filter)
  16. {
  17. }
  18. protected override void Initialize()
  19. {
  20. base.Initialize();
  21. UnitSizes = new StockHoldingGroup[] { };
  22. }
  23. protected override void BeforeLoad(MultiQuery query)
  24. {
  25. base.BeforeLoad(query);
  26. query.Add(
  27. new Filter<StockMovement>(x=>x.Location.ID).InQuery(Filter(),x=>x.Location.ID),
  28. new Columns<StockMovement>(ColumnTypeFlags.None).Add(x=>x.ID)
  29. .Add(x => x.Job.ID)
  30. .Add(x => x.Location.ID)
  31. .Add(x => x.Product.ID)
  32. .Add(x => x.Style.ID)
  33. .Add(x => x.Dimensions.Unit.ID)
  34. .Add(x => x.Dimensions.Quantity)
  35. .Add(x => x.Dimensions.Length)
  36. .Add(x => x.Dimensions.Width)
  37. .Add(x => x.Dimensions.Height)
  38. .Add(x => x.Dimensions.Weight)
  39. .Add(x => x.Dimensions.UnitSize)
  40. .Add(x => x.JobRequisitionItem.ID)
  41. .Add(x => x.JobRequisitionItem.Job.ID)
  42. .Add(x => x.JobRequisitionItem.Requisition.Number)
  43. .Add(x => x.JobRequisitionItem.Requisition.Description)
  44. .Add(x => x.Units),
  45. new SortOrder<StockMovement>(x=>x.JobRequisitionItem.Requisition.Number)
  46. );
  47. }
  48. public StockHoldingGroup[] UnitSizes { get; private set; }
  49. protected override void AfterLoad(MultiQuery query)
  50. {
  51. base.AfterLoad(query);
  52. UnitSizes = this
  53. .Select(x => new StockHoldingGroup(x.DimensionsUnitSize))
  54. .Distinct(new StockHoldingGroupEqualityComparer())
  55. .OrderBy(x=>x.UnitSize)
  56. .ToArray();
  57. _movements = query.Get<StockMovement>();
  58. }
  59. private CoreTable _movements = null;
  60. public StockTransactionAllocation[] GetAllocations(StockHoldingShell shell)
  61. {
  62. List<StockTransactionAllocation> result = null;
  63. if (_movements != null)
  64. {
  65. var movements = _movements.Rows
  66. .Where(r =>
  67. r.Get<StockMovement, Guid>(c => c.Product.ID) == shell.ProductID
  68. && r.Get<StockMovement, Guid>(c => c.Job.ID) == shell.JobID
  69. && r.Get<StockMovement, Guid>(c => c.Style.ID) == shell.StyleID
  70. && r.Get<StockMovement, Guid>(c => c.Dimensions.Unit.ID) == shell.DimensionsUnitID
  71. && String.Equals(r.Get<StockMovement, String>(c => c.Dimensions.UnitSize),
  72. shell.DimensionsUnitSize)
  73. );
  74. var groups = movements
  75. .GroupBy(r => new Tuple<Guid, Guid, int, string>(
  76. r.Get<StockMovement, Guid>(c => c.JobRequisitionItem.Job.ID),
  77. r.Get<StockMovement, Guid>(c => c.JobRequisitionItem.ID),
  78. r.Get<StockMovement, int>(c => c.JobRequisitionItem.Requisition.Number),
  79. r.Get<StockMovement, string>(c => c.JobRequisitionItem.Requisition.Description)
  80. ));
  81. result = groups
  82. .Select(g => new StockTransactionAllocation()
  83. {
  84. JobID = g.Key.Item1,
  85. ID = g.Key.Item2,
  86. Description = g.Key.Item2 != Guid.Empty
  87. ? $"{g.Key.Item3}: {g.Key.Item4}"
  88. : "Un-requisitioned items",
  89. Quantity = g.Aggregate(0.0, (t, r) => t += r.Get<StockMovement, double>(c => c.Units)),
  90. Maximum = g.Aggregate(0.0, (t, r) => t += r.Get<StockMovement, double>(c => c.Units))
  91. }
  92. ).ToList();
  93. }
  94. else
  95. result = new List<StockTransactionAllocation>();
  96. if (!result.Any(x=>x.ID == Guid.Empty))
  97. {
  98. var balance = result.Aggregate(shell.Units, (t, a) => t -= a.Quantity);
  99. result.Insert(0, new StockTransactionAllocation()
  100. {
  101. JobID = Guid.Empty,
  102. ID = Guid.Empty,
  103. Description = "Un-requisitioned Items",
  104. Quantity = balance,
  105. Maximum = balance
  106. });
  107. }
  108. return result.ToArray();
  109. }
  110. protected override Expression<Func<StockHolding, object>> ImageColumn => x => x.Product.Image.ID;
  111. private StockTransactions? _transactions = null;
  112. protected override void ItemsChanged(IEnumerable<StockHoldingShell> items)
  113. {
  114. UpdateShells(items);
  115. }
  116. private void TransactionsChanged(object sender, NotifyCollectionChangedEventArgs e)
  117. {
  118. UpdateShells(AllItems);
  119. }
  120. public void UpdateShells(IEnumerable<StockHoldingShell> items)
  121. {
  122. foreach (var shell in items)
  123. shell.Transactions.ReplaceRange(_transactions != null ? _transactions.Get(shell) : new StockTransaction[] { });
  124. OnPropertyChanged(nameof(Items));
  125. }
  126. public StockTransactions? Transactions
  127. {
  128. get => _transactions;
  129. set
  130. {
  131. if (_transactions != null)
  132. _transactions.CollectionChanged -= TransactionsChanged;
  133. _transactions = value;
  134. if (_transactions != null)
  135. _transactions.CollectionChanged += TransactionsChanged;
  136. UpdateShells(AllItems);
  137. }
  138. }
  139. }
  140. }