Dimensions.cs 8.1 KB

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