Add new Backend structure with proper .NET 8 projects
This commit is contained in:
146
src/Backend/DiunaBI.Core/Services/Calculations/BaseCalc.cs
Normal file
146
src/Backend/DiunaBI.Core/Services/Calculations/BaseCalc.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using AngouriMath;
|
||||
using DiunaBI.Core.Models;
|
||||
|
||||
namespace DiunaBI.Core.Services.Calculations;
|
||||
|
||||
public class BaseCalc
|
||||
{
|
||||
public string Expression { get; }
|
||||
private string ResultCode { get; set; }
|
||||
private string Formula { get; }
|
||||
|
||||
public BaseCalc(string expression)
|
||||
{
|
||||
Expression = expression;
|
||||
Formula = Expression.Split("=")[1];
|
||||
ResultCode = Expression.Split("=")[0];
|
||||
}
|
||||
|
||||
public bool IsFormulaCorrect()
|
||||
{
|
||||
// check left side of expression
|
||||
if (!ResultCode.StartsWith('[') || !ResultCode.EndsWith(']'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ResultCode.Substring(1, ResultCode.Length - 2).All(char.IsDigit))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ResultCode = ResultCode.Substring(1, ResultCode.Length - 2);
|
||||
|
||||
// check right side of expression
|
||||
return !string.IsNullOrEmpty(Formula) &&
|
||||
Formula.All(c => char.IsDigit(c) || c == '[' || c == ']' || c == '+' || c == '-');
|
||||
}
|
||||
|
||||
public Record CalculateT3(List<Record> records)
|
||||
{
|
||||
var resultCode = ResultCode;
|
||||
{
|
||||
var result = new Record
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Code = resultCode,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
ModifiedAt = DateTime.UtcNow
|
||||
};
|
||||
var codes = GetCodes();
|
||||
var ingredients = new List<Record>();
|
||||
foreach (var code in codes)
|
||||
{
|
||||
var ingredient = records.FirstOrDefault(r => r.Code == code);
|
||||
if (ingredient == null)
|
||||
{
|
||||
throw new Exception($"Record for code {code} not found.");
|
||||
}
|
||||
|
||||
ingredients.Add(ingredient);
|
||||
}
|
||||
|
||||
for (var i = 1; i <= 32; i++)
|
||||
{
|
||||
var formula = ingredients.Aggregate(Formula,
|
||||
(current, ingredient) => current.Replace($"[{ingredient.Code}]",
|
||||
ProcessHelper.GetValue(ingredient, i)?.ToString(CultureInfo.InvariantCulture)));
|
||||
if (formula.Contains('['))
|
||||
{
|
||||
throw new Exception($"Not all placeholders were replaced. Value{i} [{formula}]");
|
||||
}
|
||||
|
||||
Entity expr = formula;
|
||||
ProcessHelper.SetValue(result, i, (double)expr.EvalNumerical());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public Record CalculateT1(List<Record> records)
|
||||
{
|
||||
var resultCode = ResultCode;
|
||||
{
|
||||
var result = new Record
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Code = resultCode,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
ModifiedAt = DateTime.UtcNow
|
||||
};
|
||||
var codes = GetCodes();
|
||||
var ingredients = new List<Record>();
|
||||
foreach (var code in codes)
|
||||
{
|
||||
var ingredient = records.FirstOrDefault(r => r.Code == code);
|
||||
if (ingredient == null)
|
||||
{
|
||||
throw new Exception($"Record for code {code} not found.");
|
||||
}
|
||||
|
||||
ingredients.Add(ingredient);
|
||||
}
|
||||
|
||||
|
||||
var formula = ingredients.Aggregate(Formula,
|
||||
(current, ingredient) => current.Replace($"[{ingredient.Code}]",
|
||||
ProcessHelper.GetValue(ingredient, 32)?.ToString(CultureInfo.InvariantCulture)));
|
||||
if (formula.Contains('['))
|
||||
{
|
||||
throw new Exception($"Not all placeholders were replaced. Value{1} [{formula}]");
|
||||
}
|
||||
|
||||
Entity expr = formula;
|
||||
ProcessHelper.SetValue(result, 32, (double)expr.EvalNumerical());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> GetCodes()
|
||||
{
|
||||
var codes = new List<string>();
|
||||
var endIndex = -1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var startIndex = Formula.IndexOf("[", endIndex + 1, StringComparison.CurrentCulture);
|
||||
endIndex = Formula.IndexOf("]", startIndex + 1, StringComparison.CurrentCulture);
|
||||
|
||||
if (startIndex == -1 || endIndex == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var valueCode = Formula.Substring(startIndex + 1, endIndex - startIndex - 1);
|
||||
codes.Add(valueCode);
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user