after refactor cleanup

This commit is contained in:
2025-11-28 11:21:22 +01:00
parent 5db6de1503
commit 07423023a0
305 changed files with 80 additions and 13326 deletions

View File

@@ -0,0 +1,170 @@
using System.Globalization;
using AngouriMath;
using DiunaBI.Domain.Entities;
namespace DiunaBI.Infrastructure.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 double Calculate(IReadOnlyDictionary<string, double> ingredients)
{
if (ingredients == null)
{
throw new ArgumentNullException(nameof(ingredients));
}
var codes = GetCodes();
var missing = codes.Where(x => !ingredients.ContainsKey(x)).ToList();
if (missing.Any())
{
throw new ArgumentException($"Missing ingredients: {string.Join(", ", missing)}");
}
var formula = ingredients.Aggregate(Formula,
(current, ingredient) => current.Replace($"[{ingredient.Key}]", ingredient.Value.ToString(CultureInfo.InvariantCulture)));
if (formula.Contains('['))
{
throw new Exception($"Not all placeholders were replaced. Value{1} [{formula}]");
}
Entity expr = formula;
return (double)expr.EvalNumerical();
}
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;
}
}
public 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;
}
public string GetResultCode()
{
return ResultCode;
}
}

View File

@@ -0,0 +1,38 @@
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
namespace DiunaBI.Infrastructure.Services;
public class GoogleDriveHelper
{
public DriveService? Service { get; private set; }
private const string ApplicationName = "Diuna";
private static readonly string[] Scopes = [DriveService.Scope.Drive];
public GoogleDriveHelper()
{
InitializeService();
}
private void InitializeService()
{
var credential = GetCredentialsFromFile();
Service = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
}
private static GoogleCredential GetCredentialsFromFile()
{
#if DEBUG
using var stream = new FileStream("client_secrets.Development.json", FileMode.Open, FileAccess.Read);
return GoogleCredential.FromStream(stream).CreateScoped(Scopes);
#else
var json = Environment.GetEnvironmentVariable("GOOGLE_SERVICE_ACCOUNT_JSON");
if (string.IsNullOrWhiteSpace(json))
throw new InvalidOperationException("GOOGLE_SERVICE_ACCOUNT_JSON environment variable is not set.");
json = json.Replace("\\n", "\n");
return GoogleCredential.FromJson(json).CreateScoped(Scopes);
#endif
}
}

View File

@@ -0,0 +1,48 @@
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Sheets.v4;
namespace DiunaBI.Infrastructure.Services;
public class GoogleSheetsHelper
{
public SheetsService? Service { get; private set; }
private const string ApplicationName = "Diuna";
private static readonly string[] Scopes = [SheetsService.Scope.Spreadsheets];
public GoogleSheetsHelper()
{
InitializeService();
}
private void InitializeService()
{
var credential = GetCredentialsFromFile();
Service = new SheetsService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
}
private static GoogleCredential GetCredentialsFromFile()
{
#if DEBUG
using var stream = new FileStream("client_secrets.Development.json", FileMode.Open, FileAccess.Read);
return GoogleCredential.FromStream(stream).CreateScoped(Scopes);
#else
var json = Environment.GetEnvironmentVariable("GOOGLE_SERVICE_ACCOUNT_JSON");
if (string.IsNullOrWhiteSpace(json))
throw new InvalidOperationException("GOOGLE_SERVICE_ACCOUNT_JSON environment variable is not set.");
Console.WriteLine($"[GoogleSheetsHelper] Loading credentials from environment variable (length: {json.Length})");
try
{
return GoogleCredential.FromJson(json).CreateScoped(Scopes);
}
catch (Exception ex)
{
Console.WriteLine($"[GoogleSheetsHelper] ERROR: Failed to parse credentials - {ex.Message}");
throw new InvalidOperationException("Failed to parse Google service account credentials. Ensure GOOGLE_SERVICE_ACCOUNT_JSON is properly formatted.", ex);
}
#endif
}
}

View File

@@ -0,0 +1,132 @@
using System.Reflection;
using DiunaBI.Infrastructure.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace DiunaBI.Infrastructure.Services;
public class PluginManager
{
private readonly ILogger<PluginManager> _logger;
private readonly IServiceProvider _serviceProvider;
private readonly List<Type> _processorTypes = new();
private readonly List<Type> _importerTypes = new();
private readonly List<IDataExporter> _exporters = new();
private readonly List<IPlugin> _plugins = new();
public PluginManager(ILogger<PluginManager> logger, IServiceProvider serviceProvider)
{
_logger = logger;
_serviceProvider = serviceProvider;
}
public void LoadPluginsFromDirectory(string pluginsPath)
{
if (!Directory.Exists(pluginsPath))
{
_logger.LogWarning("Plugins directory not found: {Path}", pluginsPath);
return;
}
var dllFiles = Directory.GetFiles(pluginsPath, "*.dll", SearchOption.AllDirectories);
foreach (var dllFile in dllFiles)
{
try
{
LoadPluginFromAssembly(dllFile);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to load plugin from {File}", dllFile);
}
}
_logger.LogInformation("Loaded {ProcessorCount} processors and {ImporterCount} importers from {AssemblyCount} assemblies",
_processorTypes.Count,
_importerTypes.Count,
dllFiles.Length); // Zmień z _plugins.Count na assemblyFiles.Length
}
private void LoadPluginFromAssembly(string assemblyPath)
{
_logger.LogDebug("Loading assembly from: {Path}", assemblyPath); // Information -> Debug
try
{
var assembly = Assembly.LoadFrom(assemblyPath);
_logger.LogDebug("Assembly loaded successfully: {Name}", assembly.FullName); // Information -> Debug
foreach (var type in assembly.GetTypes())
{
if (typeof(IDataProcessor).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract)
{
_processorTypes.Add(type);
_logger.LogDebug("Registered processor: {Type}", type.Name); // Information -> Debug
}
if (typeof(IDataImporter).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract)
{
_importerTypes.Add(type);
_logger.LogDebug("Registered importer: {Type}", type.Name); // Information -> Debug
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to load assembly from {Path}", assemblyPath); // ZOSTAW jako Error
}
}
public IDataProcessor? GetProcessor(string processorType)
{
foreach (var type in _processorTypes)
{
try
{
using var scope = _serviceProvider.CreateScope();
var instance = (IDataProcessor)ActivatorUtilities.CreateInstance(scope.ServiceProvider, type);
if (instance.CanProcess(processorType))
{
var scopedProvider = _serviceProvider.CreateScope().ServiceProvider;
return (IDataProcessor)ActivatorUtilities.CreateInstance(scopedProvider, type);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to create processor instance of type {Type}", type.Name);
}
}
return null;
}
public IDataImporter? GetImporter(string importerType)
{
foreach (var type in _importerTypes)
{
try
{
using var scope = _serviceProvider.CreateScope();
var instance = (IDataImporter)ActivatorUtilities.CreateInstance(scope.ServiceProvider, type);
if (instance.CanImport(importerType))
{
var scopedProvider = _serviceProvider.CreateScope().ServiceProvider;
return (IDataImporter)ActivatorUtilities.CreateInstance(scopedProvider, type);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to create importer instance of type {Type}", type.Name);
}
}
return null;
}
public IDataExporter? GetExporter(string exporterType)
{
return _exporters.FirstOrDefault(e => e.CanExport(exporterType));
}
public int GetPluginsCount() => _processorTypes.Count + _importerTypes.Count + _exporters.Count;
}

View File

@@ -0,0 +1,211 @@
using System.Text.RegularExpressions;
using DiunaBI.Domain.Entities;
namespace DiunaBI.Infrastructure.Services;
public static class ProcessHelper
{
public static void SetValue(Record record, int number, double? value)
{
value = (double)Math.Round((decimal)(value ?? 0), 2);
switch (number)
{
case 1:
record.Value1 = value;
break;
case 2:
record.Value2 = value;
break;
case 3:
record.Value3 = value;
break;
case 4:
record.Value4 = value;
break;
case 5:
record.Value5 = value;
break;
case 6:
record.Value6 = value;
break;
case 7:
record.Value7 = value;
break;
case 8:
record.Value8 = value;
break;
case 9:
record.Value9 = value;
break;
case 10:
record.Value10 = value;
break;
case 11:
record.Value11 = value;
break;
case 12:
record.Value12 = value;
break;
case 13:
record.Value13 = value;
break;
case 14:
record.Value14 = value;
break;
case 15:
record.Value15 = value;
break;
case 16:
record.Value16 = value;
break;
case 17:
record.Value17 = value;
break;
case 18:
record.Value18 = value;
break;
case 19:
record.Value19 = value;
break;
case 20:
record.Value20 = value;
break;
case 21:
record.Value21 = value;
break;
case 22:
record.Value22 = value;
break;
case 23:
record.Value23 = value;
break;
case 24:
record.Value24 = value;
break;
case 25:
record.Value25 = value;
break;
case 26:
record.Value26 = value;
break;
case 27:
record.Value27 = value;
break;
case 28:
record.Value28 = value;
break;
case 29:
record.Value29 = value;
break;
case 30:
record.Value30 = value;
break;
case 31:
record.Value31 = value;
break;
case 32:
record.Value32 = value;
break;
}
}
public static double? GetValue(Record record, int number)
{
return number switch
{
1 => record.Value1,
2 => record.Value2,
3 => record.Value3,
4 => record.Value4,
5 => record.Value5,
6 => record.Value6,
7 => record.Value7,
8 => record.Value8,
9 => record.Value9,
10 => record.Value10,
11 => record.Value11,
12 => record.Value12,
13 => record.Value13,
14 => record.Value14,
15 => record.Value15,
16 => record.Value16,
17 => record.Value17,
18 => record.Value18,
19 => record.Value19,
20 => record.Value20,
21 => record.Value21,
22 => record.Value22,
23 => record.Value23,
24 => record.Value24,
25 => record.Value25,
26 => record.Value26,
27 => record.Value27,
28 => record.Value28,
29 => record.Value29,
30 => record.Value30,
31 => record.Value31,
32 => record.Value32,
_ => null
};
}
public static List<int> ParseCodes(string codes)
{
var codesList = new List<int>();
foreach (var code in codes.Split(';'))
{
var range = code.Split('-');
switch (range.Length)
{
case 1:
codesList.Add(int.Parse(range[0]));
break;
case 2:
{
for (var i = int.Parse(range[0]); i <= int.Parse(range[1]); i++)
{
codesList.Add(i);
}
break;
}
default:
throw new Exception($"Invalid code range: {code}");
}
}
return codesList;
}
public static string? ExtractMonthFromLayerName(string layerName)
{
string pattern = @"L\d+-P-\d{4}/(\d{2})-";
var match = Regex.Match(layerName, pattern);
if (match.Success && match.Groups.Count > 1)
{
return match.Groups[1].Value;
}
return null;
}
public static string GetSheetName(int month, int year)
{
if (month < 1 || month > 12)
{
throw new ArgumentOutOfRangeException(nameof(month), "Month must be between 1 and 12.");
}
var polishMonths = new[]
{
"Styczen",
"Luty",
"Marzec",
"Kwiecien",
"Maj",
"Czerwiec",
"Lipiec",
"Sierpien",
"Wrzesien",
"Pazdziernik",
"Listopad",
"Grudzien"
};
var monthName = polishMonths[month - 1];
return $"{monthName}_{year}";
}
}