using System.Linq.Expressions; using Comal.Classes; using InABox.Core; using InABox.Scripting; namespace PRSDimensionUtils; public static class DimensionUtils { private static Dictionary? _dimensionscriptcache; public static void ResetDimensionScriptCache() => _dimensionscriptcache = null; public static void ReloadDimensionScriptCache(Guid[]? ids, Func?,Columns,CoreTable> reload) { _dimensionscriptcache ??= new Dictionary(); var _scripts = reload( ids != null ? new Filter(x => x.ID).InList(ids) : null, Columns.None() .Add(x => x.ID) .Add(x => x.Conversion) ).ToDictionary(x => x.ID, x => x.Conversion); foreach (var _id in _scripts.Keys) { var _doc = !String.IsNullOrWhiteSpace(_scripts[_id]) ? new ScriptDocument(_scripts[_id]) : null; if (_doc?.Compile() == true) _dimensionscriptcache[_id] = _doc; else _dimensionscriptcache.Remove(_id); } } public static void ReloadDimensionScriptCache(Guid[]? ids, IQueryProvider query) { ReloadDimensionScriptCache(ids, (f, c) => query.Query(f, c)); } private static bool DoConvertDimensions( IDimensions? dimensions, ref double quantity, ref double cost, IQueryProvider reload) => DoConvertDimensions(dimensions, ref quantity, ref cost, (f, c) => reload.Query(f, c)); private static bool DoConvertDimensions( IDimensions? dimensions, ref double quantity, ref double cost, Func?,Columns,CoreTable> reload) { if (dimensions == null || quantity.IsEffectivelyEqual(0.0)) return false; if (_dimensionscriptcache == null) ReloadDimensionScriptCache(null, reload); if (_dimensionscriptcache?.TryGetValue(dimensions.Unit.ID, out ScriptDocument? _script) == true) { _script.SetValue("Quantity", quantity); _script.SetValue("Cost", cost); _script.SetValue("Dimensions", dimensions); if (_script.Execute("Module", DimensionUnit.ConvertDimensionsMethodName())) { quantity = Convert.ToDouble(_script.GetValue("Quantity")); cost = Convert.ToDouble(_script.GetValue("Cost")); return true; } } return false; } public static bool ConvertDimensions(IDimensions dimensions, ref double quantity, ref double cost, Func?, Columns, CoreTable> reload) { return DoConvertDimensions(dimensions, ref quantity, ref cost, reload); } public static bool ConvertDimensions(IDimensions dimensions, ref double quantity, ref double cost, IQueryProvider query) { return DoConvertDimensions(dimensions, ref quantity, ref cost, query); } public static (double quantity, double cost) ConvertDimensions(IDimensions dimensions, double quantity, double cost, Func?, Columns, CoreTable> reload) { DoConvertDimensions(dimensions, ref quantity, ref cost, reload); return (quantity, cost); } public static (double quantity, double cost) ConvertDimensions(IDimensions dimensions, double quantity, double cost, IQueryProvider query) { DoConvertDimensions(dimensions, ref quantity, ref cost, query); return (quantity, cost); } /// /// Convert the dimensions on a , and adjust /// its and accordingly. /// public static bool ConvertDimensions(this PurchaseOrderItem entity, IQueryProvider query) { var _dimensions = entity.Dimensions; var _qty = entity.Qty; var _cost = entity.Cost; if (DoConvertDimensions(_dimensions, ref _qty, ref _cost, query)) { entity.Cost = entity.Cost * entity.Qty / (_qty.IsEffectivelyEqual(0.0) ? 1.0 : _qty); entity.Qty = _qty; entity.Cost = _cost; return true; } return false; } public static bool ConvertDimensions( this T sender, Expression> dimensions, Expression> quantity, Expression> cost, IQueryProvider reload) where T : BaseObject { var dimensionsProp = DatabaseSchema.PropertyStrict(dimensions); var qtyProp = DatabaseSchema.PropertyStrict(quantity); var costProp = DatabaseSchema.PropertyStrict(cost); var dimVal = (IDimensions)dimensionsProp.Getter()(sender); var qtyVal = Convert.ToDouble(qtyProp.Getter()(sender)); var costVal = Convert.ToDouble(costProp.Getter()(sender)); if (DoConvertDimensions(dimVal, ref qtyVal, ref costVal, reload)) { qtyProp.Setter()(sender, qtyVal); costProp.Setter()(sender, costVal); return true; } return false; } }