using System; using System.Collections.Generic; namespace InABox.Core { public abstract class Dimensions : BaseObject, IEnclosedEntity, IDimensions where TLink : DimensionUnitLink, new() where TUnit : DimensionUnit, new() { [EditorSequence(1)] [RequiredColumn] [Caption("Sizing", IncludePath = false)] public abstract TLink Unit { get; set; } public IDimensionUnit GetUnit() => Unit; [DoubleEditor(Visible = Visible.Hidden)] [EditorSequence(2)] [Caption("Quantity", IncludePath = false)] [RequiredColumn] public abstract double Quantity { get; set; } [DoubleEditor(Visible = Visible.Hidden)] [EditorSequence(3)] [Caption("Length", IncludePath = false)] [RequiredColumn] public abstract double Length { get; set; } [DoubleEditor(Visible = Visible.Hidden)] [EditorSequence(4)] [Caption("Width", IncludePath = false)] [RequiredColumn] public abstract double Width { get; set; } [DoubleEditor(Visible = Visible.Hidden)] [EditorSequence(5)] [Caption("Height", IncludePath = false)] [RequiredColumn] public abstract double Height { get; set; } [DoubleEditor(Visible = Visible.Hidden)] [EditorSequence(6)] [Caption("Weight", IncludePath = false)] [RequiredColumn] public abstract double Weight { get; set; } [DoubleEditor(Visible = Visible.Optional, Editable = Editable.Hidden)] [Caption("Value", IncludePath = false)] [EditorSequence(7)] [RequiredColumn] public abstract double Value { get; set; } [TextBoxEditor(Visible = Visible.Default, Editable=Editable.Hidden)] [EditorSequence(8)] [Caption("Unit Size", IncludePath = false)] [RequiredColumn] public abstract String UnitSize { get; set; } protected override void Init() { base.Init(); Unit = new TLink(); Unit.PropertyChanged += (sender, args) => { var unit = sender as DimensionUnitLink; DoPropertyChanged( String.Format("Unit.{0}",args.PropertyName), unit.GetOriginalValue,object>(args.PropertyName), CoreUtils.GetPropertyValue(unit,args.PropertyName)); }; } private bool bCalculating = false; private static Column> unitid = new Column>(x => x.Unit.ID); private static Column> quantity = new Column>(x => x.Quantity); private static Column> length = new Column>(x => x.Length); private static Column> width = new Column>(x => x.Width); private static Column> height = new Column>(x => x.Height); private static Column> weight = new Column>(x => x.Weight); private static Column> sizeformula = new Column>(x => x.Unit.Formula); private static Column> sizeformat = new Column>(x => x.Unit.Format); protected override void DoPropertyChanged(string name, object? before, object? after) { base.DoPropertyChanged(name, before, after); if (bCalculating) return; bCalculating = true; try { if (unitid.IsEqualTo(name)) Calculate(Quantity, Length, Width, Height, Weight, Unit.Formula, Unit.Format); else if (quantity.IsEqualTo(name)) Calculate(after, Length, Width, Height, Weight, Unit.Formula, Unit.Format); else if (length.IsEqualTo(name)) Calculate(Quantity, after, Width, Height, Weight, Unit.Formula, Unit.Format); else if (width.IsEqualTo(name)) Calculate(Quantity, Length, after, Height, Weight, Unit.Formula, Unit.Format); else if (height.IsEqualTo(name)) Calculate(Quantity, Length, Width, after, Weight, Unit.Formula, Unit.Format); else if (weight.IsEqualTo(name)) Calculate(Quantity, Length, Width, Height, after, Unit.Formula, Unit.Format); else if (sizeformula.IsEqualTo(name)) Calculate(Quantity, Length, Width, Height, Weight, after as string, Unit.Format); else if (sizeformat.IsEqualTo(name)) Calculate(Quantity, Length, Width, Height, Weight, Unit.Formula, after as string); } finally { bCalculating = false; } } public void Set(IDimensionUnit unit, double quantity, double length, double width, double height, double weight) { bCalculating = true; try { Unit.ID = unit.ID; Unit.HasQuantity = unit.HasQuantity; Unit.HasLength = unit.HasLength; Unit.HasWidth = unit.HasWidth; Unit.HasHeight = unit.HasHeight; Unit.HasWeight = unit.HasWeight; Unit.Code = unit.Code; Unit.Description = unit.Description; Unit.Formula = unit.Formula; Unit.Format = unit.Format; Quantity = quantity; Length = length; Width = width; Height = height; Weight = weight; Calculate(quantity, length, width, height, weight, unit.Formula, unit.Format); } finally { bCalculating = false; } } private void Calculate(object? quantity, object? length, object? width, object? height, object? weight, string? formula, string? format) { if (Evaluate(formula, quantity, length, width, height, weight, out double value)) Value = value; if (Evaluate(format, quantity, length, width, height, weight, out string unitsize)) UnitSize = unitsize; } private bool Evaluate(string? formula, object? quantity, object? length, object? width, object? height, object? weight, out T result) { if (!String.IsNullOrWhiteSpace(formula)) { var variables = new Dictionary() { { "Quantity", Convert.ToDouble(quantity) }, { "Length", Convert.ToDouble(length) }, { "Width", Convert.ToDouble(width) }, { "Height", Convert.ToDouble(height) }, { "Weight", Convert.ToDouble(weight) } }; try { var expr = new CoreExpression(formula); var eval = expr.Evaluate(variables); result = (T)CoreUtils.ChangeType(eval,typeof(T)); return true; } catch (Exception e) { Logger.Send(LogType.Information, "", String.Format("Error in Formula: [{0}] ({1})", formula, e.Message)); result = default(T); return false; } } result = default(T); return true; } public void CopyFrom(IDimensions source) { SetObserving(false); Unit.ID = source.GetUnit().ID; Unit.Synchronise(source.GetUnit()); Quantity = source.Quantity; Length = source.Length; Width = source.Width; Height = source.Height; Weight = source.Weight; Value = source.Value; UnitSize = source.UnitSize; SetObserving(true); } } }