diverse Aenderungen
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TrafagSalesExporter.Data;
|
||||
using TrafagSalesExporter.Models;
|
||||
@@ -6,55 +7,50 @@ namespace TrafagSalesExporter.Services;
|
||||
|
||||
public class CentralSalesRecordService : ICentralSalesRecordService
|
||||
{
|
||||
private readonly IDbContextFactory<AppDbContext> _dbFactory;
|
||||
private const int BatchSize = 25;
|
||||
|
||||
public CentralSalesRecordService(IDbContextFactory<AppDbContext> dbFactory)
|
||||
private readonly IDbContextFactory<AppDbContext> _dbFactory;
|
||||
private readonly IAppEventLogService _appEventLogService;
|
||||
|
||||
public CentralSalesRecordService(IDbContextFactory<AppDbContext> dbFactory, IAppEventLogService appEventLogService)
|
||||
{
|
||||
_dbFactory = dbFactory;
|
||||
_appEventLogService = appEventLogService;
|
||||
}
|
||||
|
||||
public async Task ReplaceForSiteAsync(Site site, IEnumerable<SalesRecord> records)
|
||||
public async Task ReplaceForSiteAsync(Site site, IEnumerable<SalesRecord> records, Action<string>? updateStatus = null)
|
||||
{
|
||||
using var db = await _dbFactory.CreateDbContextAsync();
|
||||
var existing = await db.CentralSalesRecords.Where(r => r.SiteId == site.Id).ToListAsync();
|
||||
if (existing.Count > 0)
|
||||
db.CentralSalesRecords.RemoveRange(existing);
|
||||
var recordList = records.ToList();
|
||||
|
||||
var sourceSystem = string.IsNullOrWhiteSpace(site.SourceSystem) ? "SAP" : site.SourceSystem;
|
||||
db.CentralSalesRecords.AddRange(records.Select(record => new CentralSalesRecord
|
||||
await db.Database.OpenConnectionAsync();
|
||||
var connection = (SqliteConnection)db.Database.GetDbConnection();
|
||||
|
||||
try
|
||||
{
|
||||
StoredAtUtc = DateTime.UtcNow,
|
||||
SiteId = site.Id,
|
||||
SourceSystem = sourceSystem,
|
||||
ExtractionDate = record.ExtractionDate,
|
||||
Tsc = record.Tsc,
|
||||
InvoiceNumber = record.InvoiceNumber,
|
||||
PositionOnInvoice = record.PositionOnInvoice,
|
||||
Material = record.Material,
|
||||
Name = record.Name,
|
||||
ProductGroup = record.ProductGroup,
|
||||
Quantity = record.Quantity,
|
||||
SupplierNumber = record.SupplierNumber,
|
||||
SupplierName = record.SupplierName,
|
||||
SupplierCountry = record.SupplierCountry,
|
||||
CustomerNumber = record.CustomerNumber,
|
||||
CustomerName = record.CustomerName,
|
||||
CustomerCountry = record.CustomerCountry,
|
||||
CustomerIndustry = record.CustomerIndustry,
|
||||
StandardCost = record.StandardCost,
|
||||
StandardCostCurrency = record.StandardCostCurrency,
|
||||
PurchaseOrderNumber = record.PurchaseOrderNumber,
|
||||
SalesPriceValue = record.SalesPriceValue,
|
||||
SalesCurrency = record.SalesCurrency,
|
||||
Incoterms2020 = record.Incoterms2020,
|
||||
SalesResponsibleEmployee = record.SalesResponsibleEmployee,
|
||||
InvoiceDate = record.InvoiceDate,
|
||||
OrderDate = record.OrderDate,
|
||||
Land = record.Land,
|
||||
DocumentType = record.DocumentType
|
||||
}));
|
||||
updateStatus?.Invoke("Zentrale Tabelle: bestehende Saetze zaehlen...");
|
||||
var existingCount = await CountExistingAsync(connection, site.Id);
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
if (existingCount > 0)
|
||||
{
|
||||
updateStatus?.Invoke("Zentrale Tabelle: alte Saetze loeschen...");
|
||||
await DeleteExistingAsync(connection, site.Id);
|
||||
}
|
||||
|
||||
updateStatus?.Invoke("Zentrale Tabelle: neue Saetze vorbereiten...");
|
||||
await InsertRecordsInCommittedBatchesAsync(connection, site, recordList, updateStatus);
|
||||
|
||||
await _appEventLogService.WriteAsync(
|
||||
"Export",
|
||||
"Zentrale Tabelle aktualisiert",
|
||||
siteId: site.Id,
|
||||
land: site.Land,
|
||||
details: $"Geloescht={existingCount} | Neu={recordList.Count}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await db.Database.CloseConnectionAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<SalesRecord>> GetAllAsync()
|
||||
@@ -94,4 +90,147 @@ public class CentralSalesRecordService : ICentralSalesRecordService
|
||||
})
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
private static async Task<int> CountExistingAsync(SqliteConnection connection, int siteId)
|
||||
{
|
||||
await using var command = connection.CreateCommand();
|
||||
command.CommandText = "SELECT COUNT(1) FROM CentralSalesRecords WHERE SiteId = $siteId;";
|
||||
command.Parameters.AddWithValue("$siteId", siteId);
|
||||
var scalar = await command.ExecuteScalarAsync();
|
||||
return scalar is null or DBNull ? 0 : Convert.ToInt32(scalar);
|
||||
}
|
||||
|
||||
private static async Task DeleteExistingAsync(SqliteConnection connection, int siteId)
|
||||
{
|
||||
await using var transaction = connection.BeginTransaction();
|
||||
await using var command = connection.CreateCommand();
|
||||
command.Transaction = transaction;
|
||||
command.CommandText = "DELETE FROM CentralSalesRecords WHERE SiteId = $siteId;";
|
||||
command.Parameters.AddWithValue("$siteId", siteId);
|
||||
await command.ExecuteNonQueryAsync();
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
|
||||
private static async Task InsertRecordsInCommittedBatchesAsync(
|
||||
SqliteConnection connection,
|
||||
Site site,
|
||||
IReadOnlyList<SalesRecord> records,
|
||||
Action<string>? updateStatus)
|
||||
{
|
||||
var sourceSystem = string.IsNullOrWhiteSpace(site.SourceSystem) ? "SAP" : site.SourceSystem;
|
||||
var total = records.Count;
|
||||
var totalBatches = Math.Max(1, (int)Math.Ceiling(total / (double)BatchSize));
|
||||
var processed = 0;
|
||||
|
||||
for (var batchIndex = 0; batchIndex < totalBatches; batchIndex++)
|
||||
{
|
||||
updateStatus?.Invoke($"Zentrale Tabelle: Batch {batchIndex + 1}/{totalBatches} speichern...");
|
||||
|
||||
await using var transaction = connection.BeginTransaction();
|
||||
await using var command = CreateInsertCommand(connection, transaction);
|
||||
|
||||
var batchRecords = records
|
||||
.Skip(batchIndex * BatchSize)
|
||||
.Take(BatchSize);
|
||||
|
||||
foreach (var record in batchRecords)
|
||||
{
|
||||
SetInsertParameters(command, site, sourceSystem, record);
|
||||
await command.ExecuteNonQueryAsync();
|
||||
processed++;
|
||||
}
|
||||
|
||||
updateStatus?.Invoke($"Zentrale Tabelle: Batch {batchIndex + 1}/{totalBatches} abschliessen...");
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
|
||||
updateStatus?.Invoke($"Zentrale Tabelle: {processed} Datensaetze gespeichert.");
|
||||
}
|
||||
|
||||
private static SqliteCommand CreateInsertCommand(SqliteConnection connection, SqliteTransaction transaction)
|
||||
{
|
||||
var command = connection.CreateCommand();
|
||||
command.Transaction = transaction;
|
||||
command.CommandText = """
|
||||
INSERT INTO CentralSalesRecords (
|
||||
StoredAtUtc, SiteId, SourceSystem, ExtractionDate, Tsc, InvoiceNumber, PositionOnInvoice,
|
||||
Material, Name, ProductGroup, Quantity, SupplierNumber, SupplierName, SupplierCountry,
|
||||
CustomerNumber, CustomerName, CustomerCountry, CustomerIndustry, StandardCost,
|
||||
StandardCostCurrency, PurchaseOrderNumber, SalesPriceValue, SalesCurrency, Incoterms2020,
|
||||
SalesResponsibleEmployee, InvoiceDate, OrderDate, Land, DocumentType
|
||||
)
|
||||
VALUES (
|
||||
$storedAtUtc, $siteId, $sourceSystem, $extractionDate, $tsc, $invoiceNumber, $positionOnInvoice,
|
||||
$material, $name, $productGroup, $quantity, $supplierNumber, $supplierName, $supplierCountry,
|
||||
$customerNumber, $customerName, $customerCountry, $customerIndustry, $standardCost,
|
||||
$standardCostCurrency, $purchaseOrderNumber, $salesPriceValue, $salesCurrency, $incoterms2020,
|
||||
$salesResponsibleEmployee, $invoiceDate, $orderDate, $land, $documentType
|
||||
);
|
||||
""";
|
||||
|
||||
command.Parameters.Add("$storedAtUtc", SqliteType.Text);
|
||||
command.Parameters.Add("$siteId", SqliteType.Integer);
|
||||
command.Parameters.Add("$sourceSystem", SqliteType.Text);
|
||||
command.Parameters.Add("$extractionDate", SqliteType.Text);
|
||||
command.Parameters.Add("$tsc", SqliteType.Text);
|
||||
command.Parameters.Add("$invoiceNumber", SqliteType.Text);
|
||||
command.Parameters.Add("$positionOnInvoice", SqliteType.Integer);
|
||||
command.Parameters.Add("$material", SqliteType.Text);
|
||||
command.Parameters.Add("$name", SqliteType.Text);
|
||||
command.Parameters.Add("$productGroup", SqliteType.Text);
|
||||
command.Parameters.Add("$quantity", SqliteType.Real);
|
||||
command.Parameters.Add("$supplierNumber", SqliteType.Text);
|
||||
command.Parameters.Add("$supplierName", SqliteType.Text);
|
||||
command.Parameters.Add("$supplierCountry", SqliteType.Text);
|
||||
command.Parameters.Add("$customerNumber", SqliteType.Text);
|
||||
command.Parameters.Add("$customerName", SqliteType.Text);
|
||||
command.Parameters.Add("$customerCountry", SqliteType.Text);
|
||||
command.Parameters.Add("$customerIndustry", SqliteType.Text);
|
||||
command.Parameters.Add("$standardCost", SqliteType.Real);
|
||||
command.Parameters.Add("$standardCostCurrency", SqliteType.Text);
|
||||
command.Parameters.Add("$purchaseOrderNumber", SqliteType.Text);
|
||||
command.Parameters.Add("$salesPriceValue", SqliteType.Real);
|
||||
command.Parameters.Add("$salesCurrency", SqliteType.Text);
|
||||
command.Parameters.Add("$incoterms2020", SqliteType.Text);
|
||||
command.Parameters.Add("$salesResponsibleEmployee", SqliteType.Text);
|
||||
command.Parameters.Add("$invoiceDate", SqliteType.Text);
|
||||
command.Parameters.Add("$orderDate", SqliteType.Text);
|
||||
command.Parameters.Add("$land", SqliteType.Text);
|
||||
command.Parameters.Add("$documentType", SqliteType.Text);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private static void SetInsertParameters(SqliteCommand command, Site site, string sourceSystem, SalesRecord record)
|
||||
{
|
||||
command.Parameters["$storedAtUtc"].Value = DateTime.UtcNow.ToString("O");
|
||||
command.Parameters["$siteId"].Value = site.Id;
|
||||
command.Parameters["$sourceSystem"].Value = sourceSystem;
|
||||
command.Parameters["$extractionDate"].Value = record.ExtractionDate.ToString("O");
|
||||
command.Parameters["$tsc"].Value = record.Tsc ?? string.Empty;
|
||||
command.Parameters["$invoiceNumber"].Value = record.InvoiceNumber ?? string.Empty;
|
||||
command.Parameters["$positionOnInvoice"].Value = record.PositionOnInvoice;
|
||||
command.Parameters["$material"].Value = record.Material ?? string.Empty;
|
||||
command.Parameters["$name"].Value = record.Name ?? string.Empty;
|
||||
command.Parameters["$productGroup"].Value = record.ProductGroup ?? string.Empty;
|
||||
command.Parameters["$quantity"].Value = record.Quantity;
|
||||
command.Parameters["$supplierNumber"].Value = record.SupplierNumber ?? string.Empty;
|
||||
command.Parameters["$supplierName"].Value = record.SupplierName ?? string.Empty;
|
||||
command.Parameters["$supplierCountry"].Value = record.SupplierCountry ?? string.Empty;
|
||||
command.Parameters["$customerNumber"].Value = record.CustomerNumber ?? string.Empty;
|
||||
command.Parameters["$customerName"].Value = record.CustomerName ?? string.Empty;
|
||||
command.Parameters["$customerCountry"].Value = record.CustomerCountry ?? string.Empty;
|
||||
command.Parameters["$customerIndustry"].Value = record.CustomerIndustry ?? string.Empty;
|
||||
command.Parameters["$standardCost"].Value = record.StandardCost;
|
||||
command.Parameters["$standardCostCurrency"].Value = record.StandardCostCurrency ?? string.Empty;
|
||||
command.Parameters["$purchaseOrderNumber"].Value = record.PurchaseOrderNumber ?? string.Empty;
|
||||
command.Parameters["$salesPriceValue"].Value = record.SalesPriceValue;
|
||||
command.Parameters["$salesCurrency"].Value = record.SalesCurrency ?? string.Empty;
|
||||
command.Parameters["$incoterms2020"].Value = record.Incoterms2020 ?? string.Empty;
|
||||
command.Parameters["$salesResponsibleEmployee"].Value = record.SalesResponsibleEmployee ?? string.Empty;
|
||||
command.Parameters["$invoiceDate"].Value = record.InvoiceDate?.ToString("O") ?? (object)DBNull.Value;
|
||||
command.Parameters["$orderDate"].Value = record.OrderDate?.ToString("O") ?? (object)DBNull.Value;
|
||||
command.Parameters["$land"].Value = record.Land ?? string.Empty;
|
||||
command.Parameters["$documentType"].Value = record.DocumentType ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user