Files
DiunaBI/src/Backend/DiunaBI.WebAPI/Controllers/LayersController.cs

728 lines
28 KiB
C#
Raw Normal View History

using System.Globalization;
using System.Text;
using Google.Apis.Sheets.v4;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DiunaBI.Core.Models;
using DiunaBI.Core.Database.Context;
using DiunaBI.Core.Services;
2025-06-07 12:33:33 +02:00
using DiunaBI.Core.Interfaces;
namespace DiunaBI.WebAPI.Controllers;
[ApiController]
[Route("api/[controller]")]
public class LayersController : Controller
{
private readonly AppDbContext _db;
private readonly SpreadsheetsResource.ValuesResource? _googleSheetValues;
private readonly GoogleDriveHelper _googleDriveHelper;
private readonly IConfiguration _configuration;
2025-06-02 16:54:33 +02:00
private readonly PluginManager _pluginManager;
2025-06-06 20:23:36 +02:00
private readonly ILogger<LayersController> _logger;
public LayersController(
AppDbContext db,
2025-06-06 20:23:36 +02:00
SpreadsheetsResource.ValuesResource? googleSheetValues,
GoogleDriveHelper googleDriveHelper,
IConfiguration configuration,
2025-06-02 18:53:25 +02:00
PluginManager pluginManager,
2025-06-08 11:08:48 +02:00
ILogger<LayersController> logger
)
{
_db = db;
2025-06-02 18:53:25 +02:00
_googleSheetValues = googleSheetValues;
_googleDriveHelper = googleDriveHelper;
_configuration = configuration;
2025-06-02 16:54:33 +02:00
_pluginManager = pluginManager;
2025-06-02 18:53:25 +02:00
_logger = logger;
}
[HttpGet]
public IActionResult GetAll(int start, int limit, string? name, LayerType? type)
{
try
{
var response = _db.Layers.Where(x => !x.IsDeleted);
if (name != null)
{
response = response.Where(x => x.Name != null && x.Name.Contains(name));
}
if (type != null)
{
response = response.Where(x => x.Type == type);
}
2025-06-02 18:53:25 +02:00
var result = response
.OrderByDescending(x => x.Number)
2025-06-02 18:53:25 +02:00
.Skip(start).Take(limit).AsNoTracking().ToList();
2025-06-06 20:23:36 +02:00
_logger.LogDebug("GetAll: Retrieved {Count} layers with filter name={Name}, type={Type}",
2025-06-02 18:53:25 +02:00
result.Count, name, type);
return Ok(result);
}
catch (Exception e)
{
2025-06-02 18:53:25 +02:00
_logger.LogError(e, "GetAll: Error retrieving layers");
return BadRequest(e.ToString());
}
}
[HttpGet]
[Route("{id:guid}")]
public IActionResult Get(Guid id)
{
try
{
2025-06-02 18:53:25 +02:00
var layer = _db.Layers
.Include(x => x.CreatedBy)
.Include(x => x.ModifiedBy)
2025-06-02 18:53:25 +02:00
.Include(x => x.Records).AsNoTracking().First(x => x.Id == id && !x.IsDeleted);
_logger.LogDebug("Get: Retrieved layer {LayerId} {LayerName}", id, layer.Name);
return Ok(layer);
}
catch (Exception e)
{
2025-06-02 18:53:25 +02:00
_logger.LogError(e, "Get: Error retrieving layer {LayerId}", id);
return BadRequest(e.ToString());
}
}
[HttpGet]
[Route("getForPowerBI/{apiKey}/{number:int}")]
public IActionResult GetByNumber(string apiKey, int number)
{
if (apiKey != _configuration["apiKey"])
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("PowerBI: Unauthorized request - wrong apiKey for layer {LayerNumber}", number);
return Unauthorized();
}
try
{
2025-06-02 18:53:25 +02:00
if (!Request.Headers.TryGetValue("Authorization", out var authHeader))
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("PowerBI: Unauthorized request - no authorization header for layer {LayerNumber}", number);
return Unauthorized();
}
var credentialsArr = authHeader.ToString().Split(" ");
if (credentialsArr.Length != 2)
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("PowerBI: Unauthorized request - wrong auth header format for layer {LayerNumber}", number);
return Unauthorized();
}
var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1]));
var username = authValue.Split(':')[0];
var password = authValue.Split(':')[1];
if (username != _configuration["powerBI-user"] || password != _configuration["powerBI-pass"])
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("PowerBI: Unauthorized request - bad credentials for layer {LayerNumber}", number);
return Unauthorized();
}
2025-06-02 18:53:25 +02:00
_logger.LogInformation("PowerBI: Sending data for layer {LayerNumber}", number);
2025-06-02 18:53:25 +02:00
var layer = _db.Layers
.Include(x => x.CreatedBy)
2025-06-02 18:53:25 +02:00
.Include(x => x.Records).AsNoTracking().First(x => x.Number == number && !x.IsDeleted);
return Ok(layer);
}
catch (Exception e)
{
2025-06-02 18:53:25 +02:00
_logger.LogError(e, "PowerBI: Error occurred while processing layer {LayerNumber}", number);
return BadRequest(e.ToString());
}
}
[HttpGet]
[Route("getConfiguration/{apiKey}/{number:int}")]
public IActionResult GetConfigurationByNumber(string apiKey, int number)
{
if (apiKey != _configuration["apiKey"])
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("Configuration: Unauthorized request - wrong apiKey for layer {LayerNumber}", number);
return Unauthorized();
}
try
{
2025-06-02 18:53:25 +02:00
if (!Request.Headers.TryGetValue("Authorization", out var authHeader))
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("Configuration: Unauthorized request - no authorization header for layer {LayerNumber}", number);
return Unauthorized();
}
var credentialsArr = authHeader.ToString().Split(" ");
if (credentialsArr.Length != 2)
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("Configuration: Unauthorized request - wrong auth header format for layer {LayerNumber}", number);
return Unauthorized();
}
var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1]));
var username = authValue.Split(':')[0];
var password = authValue.Split(':')[1];
if (username != _configuration["morska-user"] || password != _configuration["morska-pass"])
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("Configuration: Unauthorized request - bad credentials for layer {LayerNumber}", number);
return Unauthorized();
}
var config = _db.Layers
.Include(x => x.Records)
.AsNoTracking()
.First(x => x.Number == number && !x.IsDeleted);
if (config is null)
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("Configuration: Layer {LayerNumber} not found", number);
return BadRequest();
}
var type = config.Records?.Where(x => x.Code == "Type").FirstOrDefault();
if (type is null || type.Desc1 != "ExternalConfiguration")
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("Configuration: Layer {LayerNumber} is not ExternalConfiguration type", number);
return BadRequest();
}
2025-06-02 18:53:25 +02:00
_logger.LogInformation("Configuration: Sending configuration for layer {LayerNumber}", number);
return Ok(config);
}
2025-06-02 18:53:25 +02:00
catch (Exception e)
{
2025-06-02 18:53:25 +02:00
_logger.LogError(e, "Configuration: Error occurred while processing layer {LayerNumber}", number);
return BadRequest();
}
}
[HttpGet]
[Route("exportToGoogleSheet/{id:guid}")]
public IActionResult ExportToGoogleSheet(Guid id)
{
if (_googleSheetValues is null)
{
2025-06-02 18:53:25 +02:00
_logger.LogError("Export: Google Sheets API not initialized");
throw new Exception("Google Sheets API not initialized");
}
2025-06-02 18:53:25 +02:00
try
{
var layer = _db.Layers
.Include(x => x.Records!.OrderByDescending(y => y.Code)).AsNoTracking().First(x => x.Id == id && !x.IsDeleted);
2025-06-02 18:53:25 +02:00
var export = _pluginManager.GetExporter("GoogleSheet");
if (export == null)
{
_logger.LogError("Export: GoogleSheet exporter not found for layer {LayerId}", id);
throw new Exception("GoogleSheet exporter not found");
}
_logger.LogInformation("Export: Starting GoogleSheet export for layer {LayerId} {LayerName}", id, layer.Name);
export.Export(layer);
_logger.LogInformation("Export: Successfully exported layer {LayerId} to GoogleSheet", id);
2025-06-06 20:23:36 +02:00
2025-06-02 18:53:25 +02:00
return Ok(true);
}
catch (Exception e)
2025-06-02 16:54:33 +02:00
{
2025-06-02 18:53:25 +02:00
_logger.LogError(e, "Export: Failed to export layer {LayerId} to GoogleSheet", id);
throw;
2025-06-02 16:54:33 +02:00
}
}
[HttpGet]
[Route("ProcessQueue/{apiKey}")]
[AllowAnonymous]
public IActionResult ProcessQueue(string apiKey)
{
2025-06-02 18:53:25 +02:00
if (Request.Host.Value != _configuration["apiLocalUrl"] || apiKey != _configuration["apiKey"])
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("ProcessQueue: Unauthorized request with apiKey {ApiKey}", apiKey);
return Unauthorized();
}
2025-06-02 18:53:25 +02:00
_logger.LogInformation("ProcessQueue: Starting queue processing");
// Queue processing implementation would go here
return Ok();
}
[HttpGet]
[Route("AutoImport/{apiKey}/{nameFilter}")]
[AllowAnonymous]
public IActionResult AutoImport(string apiKey, string nameFilter)
{
if (Request.Host.Value != _configuration["apiLocalUrl"] || apiKey != _configuration["apiKey"])
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("AutoImport: Unauthorized request with apiKey {ApiKey}", apiKey);
return Unauthorized();
}
if (_googleSheetValues is null)
{
2025-06-02 18:53:25 +02:00
_logger.LogError("AutoImport: Google Sheets API not initialized");
throw new Exception("Google Sheets API not initialized");
}
var importWorkerLayers = _db.Layers
.Include(x => x.Records)
.Where(x =>
x.Name != null && x.Name.Contains(nameFilter) &&
x.Records!.Any(y => y.Code == "Type" && y.Desc1 == "ImportWorker") &&
2025-06-02 20:11:29 +02:00
x.Records!.Any(y => y.Code == "IsEnabled" && y.Desc1 == "True"
)
)
.OrderByDescending(x => x.CreatedAt)
.AsNoTracking()
.ToList();
2025-06-02 18:53:25 +02:00
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoImport: Starting import with filter {NameFilter}, found {LayerCount} layers",
2025-06-02 18:53:25 +02:00
nameFilter, importWorkerLayers.Count);
try
{
if (importWorkerLayers.Count == 0)
{
2025-06-02 18:53:25 +02:00
_logger.LogInformation("AutoImport: No layers to import");
return Ok();
}
foreach (var importWorker in importWorkerLayers)
{
try
{
2025-06-02 18:53:25 +02:00
var type = importWorker.Records!.FirstOrDefault(x => x.Code == "ImportType")?.Desc1 ?? "Standard";
var source = importWorker.Records!.FirstOrDefault(x => x.Code == "Source")?.Desc1 ?? "GoogleSheet";
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoImport: Processing layer {LayerName} with type {ImportType} and source {Source}",
2025-06-02 18:53:25 +02:00
importWorker.Name, type, source);
if (source == "DataInbox" && type == "Import-D3")
{
2025-06-02 16:54:33 +02:00
var d3Importer = _pluginManager.GetImporter("MorskaD3");
if (d3Importer == null)
{
throw new Exception("MorskaD3 importer not found");
}
d3Importer.Import(importWorker);
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoImport: Successfully processed D3 import for {LayerName} ({LayerId})",
2025-06-02 18:53:25 +02:00
importWorker.Name, importWorker.Id);
continue;
}
2025-06-02 18:53:25 +02:00
switch (type)
{
case "D1":
2025-06-02 16:54:33 +02:00
var d1importer = _pluginManager.GetImporter("MorskaD1");
if (d1importer == null)
{
throw new Exception("MorskaD1 importer not found");
}
d1importer.Import(importWorker);
Thread.Sleep(5000); // be aware of GSheet API quota
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoImport: Successfully processed D1 import for {LayerName} ({LayerId})",
2025-06-02 18:53:25 +02:00
importWorker.Name, importWorker.Id);
break;
2025-06-02 18:53:25 +02:00
case "FK2":
2025-06-02 18:53:25 +02:00
var fk2importer = _pluginManager.GetImporter("MorskaFK2");
if (fk2importer == null)
{
2025-06-02 18:53:25 +02:00
throw new Exception("MorskaFK2 importer not found");
}
2025-06-02 18:53:25 +02:00
fk2importer.Import(importWorker);
Thread.Sleep(5000); // be aware of GSheet API quota
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoImport: Successfully processed FK2 import for {LayerName} ({LayerId})",
2025-06-02 18:53:25 +02:00
importWorker.Name, importWorker.Id);
break;
default:
2025-06-02 18:53:25 +02:00
var startDate = importWorker.Records!.FirstOrDefault(x => x.Code == "StartDate")?.Desc1;
if (startDate == null)
{
2025-06-02 18:53:25 +02:00
throw new Exception("StartDate record not found");
}
2025-06-02 18:53:25 +02:00
var endDate = importWorker.Records!.First(x => x.Code == "EndDate").Desc1;
if (endDate == null)
{
throw new Exception("EndDate record not found");
}
2025-06-02 18:53:25 +02:00
var startDateParsed = DateTime.ParseExact(startDate, "yyyy.MM.dd", null);
var endDateParsed = DateTime.ParseExact(endDate, "yyyy.MM.dd", null);
2025-06-06 20:23:36 +02:00
2025-06-02 18:53:25 +02:00
if (startDateParsed.Date <= DateTime.UtcNow.Date && endDateParsed.Date >= DateTime.UtcNow.Date)
{
var importer = _pluginManager.GetImporter("MorskaImporter");
if (importer == null)
{
2025-06-02 18:53:25 +02:00
throw new Exception("MorskaImporter not found");
}
2025-06-02 18:53:25 +02:00
importer.Import(importWorker);
Thread.Sleep(5000); // be aware of GSheet API quota
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoImport: Successfully processed standard import for {LayerName} ({LayerId})",
2025-06-02 18:53:25 +02:00
importWorker.Name, importWorker.Id);
}
else if (IsImportedLayerUpToDate(importWorker) == false)
{
var importer = _pluginManager.GetImporter("MorskaImporter");
if (importer == null)
{
2025-06-02 18:53:25 +02:00
throw new Exception("MorskaImporter not found");
}
2025-06-02 18:53:25 +02:00
importer.Import(importWorker);
Thread.Sleep(5000); // be aware of GSheet API quota
2025-06-06 20:23:36 +02:00
_logger.LogWarning("AutoImport: Reimported out-of-date layer {LayerName} ({LayerId})",
2025-06-02 18:53:25 +02:00
importWorker.Name, importWorker.Id);
}
2025-06-02 18:53:25 +02:00
else
{
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoImport: Layer {LayerName} ({LayerId}) is up to date, skipping",
2025-06-02 18:53:25 +02:00
importWorker.Name, importWorker.Id);
}
break;
}
}
catch (Exception e)
{
2025-06-06 20:23:36 +02:00
_logger.LogError(e, "AutoImport: Failed to process layer {LayerName} ({LayerId})",
2025-06-02 18:53:25 +02:00
importWorker.Name, importWorker.Id);
}
}
2025-06-02 18:53:25 +02:00
_logger.LogInformation("AutoImport: Completed processing {LayerCount} layers", importWorkerLayers.Count);
return Ok();
}
catch (Exception e)
{
2025-06-02 18:53:25 +02:00
_logger.LogError(e, "AutoImport: Process error");
return BadRequest(e.ToString());
}
}
[HttpGet]
[Route("AutoProcess/{apiKey}")]
[AllowAnonymous]
public IActionResult AutoProcess(string apiKey)
{
if (Request.Host.Value != _configuration["apiLocalUrl"] || apiKey != _configuration["apiKey"])
{
2025-06-02 18:53:25 +02:00
_logger.LogWarning("AutoProcess: Unauthorized request with apiKey {ApiKey}", apiKey);
return Unauthorized();
}
if (_googleSheetValues is null)
{
2025-06-02 18:53:25 +02:00
_logger.LogError("AutoProcess: Google Sheets API not initialized");
throw new Exception("Google Sheets API not initialized");
}
string[] processTypes =
[
"T3-SingleSource",
"T3-SourceYearSummary",
2025-06-02 18:53:25 +02:00
"T3-MultiSourceSummary",
"T3-MultiSourceYearSummary",
"T4-SingleSource",
"T5-LastValues",
"T1-R1",
"T4-R2",
"T1-R3"
];
2025-06-02 18:53:25 +02:00
_logger.LogInformation("AutoProcess: Starting processing for {ProcessTypeCount} process types", processTypes.Length);
foreach (var type in processTypes)
{
try
{
var processWorkerLayers = _db.Layers
.Include(x => x.Records)
.Where(x =>
x.Records!.Any(y => y.Code == "Type" && y.Desc1 == "ProcessWorker") &&
x.Records!.Any(y => y.Code == "IsEnabled" && y.Desc1 == "True") &&
x.Records!.Any(y => y.Code == "ProcessType" && y.Desc1 == type)
)
.OrderBy(x => x.CreatedAt)
.AsNoTracking()
.ToList();
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoProcess: Processing type {ProcessType}, found {LayerCount} layers",
2025-06-02 18:53:25 +02:00
type, processWorkerLayers.Count);
foreach (var processWorker in processWorkerLayers)
{
try
{
ProcessLayer(processWorker);
2025-06-06 20:23:36 +02:00
_logger.LogInformation("AutoProcess: Successfully processed {LayerName} ({LayerId}) with type {ProcessType}",
2025-06-02 18:53:25 +02:00
processWorker.Name, processWorker.Id, type);
}
catch (Exception e)
{
2025-06-06 20:23:36 +02:00
_logger.LogError(e, "AutoProcess: Failed to process {LayerName} ({LayerId}) with type {ProcessType}",
2025-06-02 18:53:25 +02:00
processWorker.Name, processWorker.Id, type);
}
}
}
catch (Exception e)
{
2025-06-02 18:53:25 +02:00
_logger.LogError(e, "AutoProcess: Error processing type {ProcessType}", type);
}
}
2025-06-02 18:53:25 +02:00
_logger.LogInformation("AutoProcess: Completed processing all process types");
return Ok();
}
private void ProcessLayer(Layer processWorker)
{
if (_googleSheetValues == null)
{
throw new Exception("Google Sheets API not initialized");
}
var year = processWorker.Records?.SingleOrDefault(x => x.Code == "Year")?.Desc1;
if (year == null)
{
2025-06-02 18:53:25 +02:00
throw new Exception("Year record not found");
}
var processType = processWorker.Records?.SingleOrDefault(x => x.Code == "ProcessType")?.Desc1;
switch (processType)
{
case null:
throw new Exception("ProcessType record not found");
case "T3-SourceYearSummary":
{
2025-06-02 16:54:33 +02:00
var processor = _pluginManager.GetProcessor("T3.SourceYearSummary");
if (processor == null)
{
throw new Exception("T3.SourceYearSummary processor not found");
}
processor.Process(processWorker);
return;
}
case "T3-MultiSourceYearSummary":
{
2025-06-02 16:54:33 +02:00
var processor = _pluginManager.GetProcessor("T3.MultiSourceYearSummary");
if (processor == null)
{
throw new Exception("T3.MultiSourceYearSummary processor not found");
}
processor.Process(processWorker);
return;
}
case "T3-MultiSourceCopySelectedCodesYearSummary":
{
2025-06-02 16:54:33 +02:00
var processor = _pluginManager.GetProcessor("T3.MultiSourceCopySelectedCodesYearSummary");
if (processor == null)
{
throw new Exception("T3.MultiSourceCopySelectedCodesYearSummary processor not found");
}
processor.Process(processWorker);
return;
}
case "T1-R1":
{
2025-06-02 16:54:33 +02:00
var processor = _pluginManager.GetProcessor("T1.R1");
if (processor == null)
{
throw new Exception("T1.R1 processor not found");
}
processor.Process(processWorker);
return;
}
case "T4-R2":
{
2025-06-02 16:54:33 +02:00
var processor = _pluginManager.GetProcessor("T4.R2");
if (processor == null)
{
throw new Exception("T4.R2 processor not found");
}
processor.Process(processWorker);
return;
}
case "T1-R3":
{
2025-06-02 16:54:33 +02:00
var processor = _pluginManager.GetProcessor("T1.R3");
if (processor == null)
{
throw new Exception("T1.R3 processor not found");
}
processor.Process(processWorker);
return;
}
}
var month = processWorker.Records?.SingleOrDefault(x => x.Code == "Month")?.Desc1;
if (month == null)
{
throw new Exception("Month record not found");
}
switch (processType!)
{
case "T3-SingleSource":
{
2025-06-02 16:54:33 +02:00
var t3SingleSource = _pluginManager.GetProcessor("T3.SingleSource");
if (t3SingleSource == null)
{
throw new Exception("T3.SingleSource processor not found");
}
t3SingleSource.Process(processWorker);
break;
}
case "T4-SingleSource":
{
2025-06-02 16:54:33 +02:00
var t4SingleSource = _pluginManager.GetProcessor("T4.SingleSource");
if (t4SingleSource == null)
{
throw new Exception("T4.SingleSource processor not found");
}
t4SingleSource.Process(processWorker);
break;
}
case "T5-LastValues":
{
2025-06-02 16:54:33 +02:00
var t5LastValues = _pluginManager.GetProcessor("T5.LastValues");
if (t5LastValues == null)
{
throw new Exception("T5.LastValues processor not found");
}
t5LastValues.Process(processWorker);
break;
}
case "T3-MultiSourceSummary":
{
2025-06-02 16:54:33 +02:00
var t3MultiSourceSummary = _pluginManager.GetProcessor("T3.MultiSourceSummary");
if (t3MultiSourceSummary == null)
{
throw new Exception("T3.MultiSourceSummary processor not found");
}
t3MultiSourceSummary.Process(processWorker);
break;
}
case "T3-MultiSourceCopySelectedCodes":
{
2025-06-02 16:54:33 +02:00
var t3MultiSourceCopySelectedCode = _pluginManager.GetProcessor("T3.MultiSourceCopySelectedCodes");
if (t3MultiSourceCopySelectedCode == null)
{
throw new Exception("T3.MultiSourceCopySelectedCodes processor not found");
}
t3MultiSourceCopySelectedCode.Process(processWorker);
break;
}
}
}
2025-06-06 20:23:36 +02:00
[HttpGet]
2025-06-07 16:34:36 +02:00
[Route("CheckProcessors")]
2025-06-06 20:23:36 +02:00
[AllowAnonymous]
2025-06-08 10:18:52 +02:00
private static void WriteToConsole(params string[] messages)
{
foreach (var message in messages)
{
Console.WriteLine($"DiunaLog: {message}");
}
}
private bool IsImportedLayerUpToDate(Layer importWorker)
{
if (_googleSheetValues is null)
{
throw new Exception("Google Sheets API not initialized");
}
var newestLayer = _db.Layers
.Include(x => x.Records)
.Where(x => x.ParentId == importWorker.Id)
.OrderByDescending(x => x.CreatedAt)
.AsNoTracking()
.FirstOrDefault();
if (newestLayer is null)
{
2025-06-02 18:53:25 +02:00
_logger.LogDebug("IsImportedLayerUpToDate: No child layers found for {LayerName}, treating as up to date", importWorker.Name);
return true; // importWorker is not active yet, no check needed
}
var sheetId = importWorker.Records!.FirstOrDefault(x => x.Code == "SheetId")?.Desc1;
if (sheetId == null)
{
throw new Exception($"SheetId not found, {importWorker.Name}");
}
var sheetTabName = importWorker.Records!.FirstOrDefault(x => x.Code == "SheetTabName")?.Desc1;
if (sheetTabName == null)
{
throw new Exception($"SheetTabName not found, {importWorker.Name}");
}
var dataRange = importWorker.Records!.FirstOrDefault(x => x.Code == "DataRange")?.Desc1;
if (dataRange == null)
{
throw new Exception($"DataRange not found, {importWorker.Name}");
}
2025-06-02 18:53:25 +02:00
try
{
var dataRangeResponse = _googleSheetValues.Get(sheetId, $"{sheetTabName}!{dataRange}").Execute();
var data = dataRangeResponse.Values;
2025-06-02 18:53:25 +02:00
var isUpToDate = true;
2025-06-02 18:53:25 +02:00
for (var i = 0; i < data[1].Count; i++)
{
2025-06-02 18:53:25 +02:00
if (data[0][i].ToString() == "") continue;
var record = newestLayer.Records!.FirstOrDefault(x => x.Code == data[0][i].ToString());
if (record == null)
{
2025-06-06 20:23:36 +02:00
_logger.LogDebug("IsImportedLayerUpToDate: Code {Code} not found in DiunaBI for layer {LayerName}",
2025-06-02 18:53:25 +02:00
data[0][i].ToString(), importWorker.Name);
isUpToDate = false;
continue;
}
if (!double.TryParse(data[1][i].ToString(), CultureInfo.GetCultureInfo("pl-PL"), out var value) ||
double.Abs((double)(record.Value1 - value)!) < 0.01) continue;
isUpToDate = false;
}
2025-06-02 18:53:25 +02:00
foreach (var record in newestLayer.Records!)
{
2025-06-02 18:53:25 +02:00
if (data[0].Contains(record.Code))
{
continue;
}
2025-06-06 20:23:36 +02:00
_logger.LogDebug("IsImportedLayerUpToDate: Code {Code} not found in GoogleSheet for layer {LayerName}",
2025-06-02 18:53:25 +02:00
record.Code, importWorker.Name);
isUpToDate = false;
}
2025-06-06 20:23:36 +02:00
_logger.LogDebug("IsImportedLayerUpToDate: Layer {LayerName} is {Status}",
2025-06-02 18:53:25 +02:00
importWorker.Name, isUpToDate ? "up to date" : "outdated");
2025-06-02 18:53:25 +02:00
return isUpToDate;
}
catch (Exception e)
{
_logger.LogError(e, "IsImportedLayerUpToDate: Error checking if layer {LayerName} is up to date", importWorker.Name);
throw;
}
}
}