Dimensions.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using System.Collections.Generic;
  3. namespace InABox.Core
  4. {
  5. public abstract class Dimensions<TLink,TUnit> : EnclosedEntity, IDimensions
  6. where TLink : DimensionUnitLink<TUnit>, new()
  7. where TUnit : DimensionUnit, new()
  8. {
  9. public Dimensions() : base() { }
  10. public Dimensions(Func<Entity> entity) : base(entity) { }
  11. [EditorSequence(1)]
  12. [RequiredColumn]
  13. [Caption("Sizing", IncludePath = false)]
  14. public abstract TLink Unit { get; set; }
  15. public IDimensionUnit GetUnit() => Unit;
  16. [DoubleEditor(Visible = Visible.Hidden)]
  17. [EditorSequence(2)]
  18. [Caption("Quantity", IncludePath = false)]
  19. [RequiredColumn]
  20. public abstract double Quantity { get; set; }
  21. [DoubleEditor(Visible = Visible.Hidden)]
  22. [EditorSequence(3)]
  23. [Caption("Length", IncludePath = false)]
  24. [RequiredColumn]
  25. public abstract double Length { get; set; }
  26. [DoubleEditor(Visible = Visible.Hidden)]
  27. [EditorSequence(4)]
  28. [Caption("Width", IncludePath = false)]
  29. [RequiredColumn]
  30. public abstract double Width { get; set; }
  31. [DoubleEditor(Visible = Visible.Hidden)]
  32. [EditorSequence(5)]
  33. [Caption("Height", IncludePath = false)]
  34. [RequiredColumn]
  35. public abstract double Height { get; set; }
  36. [DoubleEditor(Visible = Visible.Hidden)]
  37. [EditorSequence(6)]
  38. [Caption("Weight", IncludePath = false)]
  39. [RequiredColumn]
  40. public abstract double Weight { get; set; }
  41. [DoubleEditor(Visible = Visible.Optional, Editable = Editable.Hidden)]
  42. [Caption("Value", IncludePath = false)]
  43. [EditorSequence(7)]
  44. [RequiredColumn]
  45. public abstract double Value { get; set; }
  46. [TextBoxEditor(Visible = Visible.Default, Editable=Editable.Hidden)]
  47. [EditorSequence(8)]
  48. [Caption("Unit Size", IncludePath = false)]
  49. [RequiredColumn]
  50. public abstract String UnitSize { get; set; }
  51. protected override void Init()
  52. {
  53. base.Init();
  54. Unit = Activator.CreateInstance(typeof(TLink), new object[] { new Func<Entity>(LinkedEntity) }) as TLink;
  55. // Unit.PropertyChanged += (sender, args) =>
  56. // {
  57. // var unit = sender as DimensionUnitLink<TUnit>;
  58. // DoPropertyChanged(
  59. // String.Format("Unit.{0}",args.PropertyName),
  60. // unit.GetOriginalValue<DimensionUnitLink<TUnit>,object>(args.PropertyName),
  61. // CoreUtils.GetPropertyValue(unit,args.PropertyName));
  62. // };
  63. }
  64. private bool bCalculating = false;
  65. private static Column<Dimensions<TLink,TUnit>> unitid = new Column<Dimensions<TLink,TUnit>>(x => x.Unit.ID);
  66. private static Column<Dimensions<TLink,TUnit>> quantity = new Column<Dimensions<TLink,TUnit>>(x => x.Quantity);
  67. private static Column<Dimensions<TLink,TUnit>> length = new Column<Dimensions<TLink,TUnit>>(x => x.Length);
  68. private static Column<Dimensions<TLink,TUnit>> width = new Column<Dimensions<TLink,TUnit>>(x => x.Width);
  69. private static Column<Dimensions<TLink,TUnit>> height = new Column<Dimensions<TLink,TUnit>>(x => x.Height);
  70. private static Column<Dimensions<TLink,TUnit>> weight = new Column<Dimensions<TLink,TUnit>>(x => x.Weight);
  71. private static Column<Dimensions<TLink,TUnit>> sizeformula = new Column<Dimensions<TLink,TUnit>>(x => x.Unit.Formula);
  72. private static Column<Dimensions<TLink,TUnit>> sizeformat = new Column<Dimensions<TLink,TUnit>>(x => x.Unit.Format);
  73. protected override void DoPropertyChanged(string name, object? before, object? after)
  74. {
  75. base.DoPropertyChanged(name, before, after);
  76. if (bCalculating)
  77. return;
  78. bCalculating = true;
  79. try
  80. {
  81. if (unitid.IsEqualTo(name))
  82. Calculate(Quantity, Length, Width, Height, Weight, Unit.Formula, Unit.Format);
  83. else if (quantity.IsEqualTo(name))
  84. Calculate(after, Length, Width, Height, Weight, Unit.Formula, Unit.Format);
  85. else if (length.IsEqualTo(name))
  86. Calculate(Quantity, after, Width, Height, Weight, Unit.Formula, Unit.Format);
  87. else if (width.IsEqualTo(name))
  88. Calculate(Quantity, Length, after, Height, Weight, Unit.Formula, Unit.Format);
  89. else if (height.IsEqualTo(name))
  90. Calculate(Quantity, Length, Width, after, Weight, Unit.Formula, Unit.Format);
  91. else if (weight.IsEqualTo(name))
  92. Calculate(Quantity, Length, Width, Height, after, Unit.Formula, Unit.Format);
  93. else if (sizeformula.IsEqualTo(name))
  94. Calculate(Quantity, Length, Width, Height, Weight, after as string, Unit.Format);
  95. else if (sizeformat.IsEqualTo(name))
  96. Calculate(Quantity, Length, Width, Height, Weight, Unit.Formula, after as string);
  97. }
  98. finally
  99. {
  100. bCalculating = false;
  101. }
  102. }
  103. public void Set(IDimensionUnit unit, double quantity, double length, double width, double height, double weight)
  104. {
  105. bCalculating = true;
  106. try
  107. {
  108. Unit.ID = unit.ID;
  109. Unit.HasQuantity = unit.HasQuantity;
  110. Unit.HasLength = unit.HasLength;
  111. Unit.HasWidth = unit.HasWidth;
  112. Unit.HasHeight = unit.HasHeight;
  113. Unit.HasWeight = unit.HasWeight;
  114. Unit.Code = unit.Code;
  115. Unit.Description = unit.Description;
  116. Unit.Formula = unit.Formula;
  117. Unit.Format = unit.Format;
  118. Quantity = quantity;
  119. Length = length;
  120. Width = width;
  121. Height = height;
  122. Weight = weight;
  123. Calculate(quantity, length, width, height, weight, unit.Formula, unit.Format);
  124. }
  125. finally
  126. {
  127. bCalculating = false;
  128. }
  129. }
  130. private void Calculate(object? quantity, object? length, object? width, object? height, object? weight, string? formula, string? format)
  131. {
  132. if (Evaluate<double>(formula, quantity, length, width, height, weight, out double value))
  133. Value = value;
  134. if (Evaluate<String>(format, quantity, length, width, height, weight, out string unitsize))
  135. UnitSize = unitsize;
  136. }
  137. private bool Evaluate<T>(string? formula, object? quantity, object? length, object? width, object? height, object? weight, out T result)
  138. {
  139. if (!String.IsNullOrWhiteSpace(formula))
  140. {
  141. var variables = new Dictionary<string, object?>()
  142. {
  143. { "Quantity", Convert.ToDouble(quantity) },
  144. { "Length", Convert.ToDouble(length) },
  145. { "Width", Convert.ToDouble(width) },
  146. { "Height", Convert.ToDouble(height) },
  147. { "Weight", Convert.ToDouble(weight) }
  148. };
  149. try
  150. {
  151. var expr = new CoreExpression(formula);
  152. var eval = expr.Evaluate(variables);
  153. result = (T)CoreUtils.ChangeType(eval,typeof(T));
  154. return true;
  155. }
  156. catch (Exception e)
  157. {
  158. Logger.Send(LogType.Information, "", String.Format("Error in Formula: [{0}] ({1})", formula, e.Message));
  159. result = default(T);
  160. return false;
  161. }
  162. }
  163. result = default(T);
  164. return true;
  165. }
  166. public void CopyFrom(IDimensions source, bool observing = false)
  167. {
  168. if (!observing)
  169. SetObserving(false);
  170. Unit.ID = source.GetUnit().ID;
  171. Unit.Synchronise(source.GetUnit());
  172. Quantity = source.Quantity;
  173. Length = source.Length;
  174. Width = source.Width;
  175. Height = source.Height;
  176. Weight = source.Weight;
  177. Value = source.Value;
  178. UnitSize = source.UnitSize;
  179. if (!observing)
  180. SetObserving(true);
  181. }
  182. }
  183. }