manometer
This commit is contained in:
@@ -158,19 +158,21 @@ public class ConfigTransferService : IConfigTransferService
|
||||
{
|
||||
var package = JsonSerializer.Deserialize<ConfigTransferPackage>(json, JsonOptions)
|
||||
?? throw new InvalidOperationException("Konfigurationsdatei konnte nicht gelesen werden.");
|
||||
var importedSourceSystems = ResolveImportedSourceSystems(json, package);
|
||||
|
||||
using var db = await _dbFactory.CreateDbContextAsync();
|
||||
await using var transaction = await db.Database.BeginTransactionAsync();
|
||||
var existingSharePoint = await db.SharePointConfigs.FirstOrDefaultAsync();
|
||||
var existingSettings = await db.ExportSettings.FirstOrDefaultAsync();
|
||||
var existingSourceSystems = await db.SourceSystemDefinitions.ToListAsync();
|
||||
var existingServers = await db.HanaServers.ToListAsync();
|
||||
var existingExchangeRates = await db.CurrencyExchangeRates.ToListAsync();
|
||||
var existingSites = await db.Sites.ToListAsync();
|
||||
var existingCentralRecords = await db.CentralSalesRecords.AsNoTracking().ToListAsync();
|
||||
var existingRules = await db.FieldTransformationRules.ToListAsync();
|
||||
var existingSapSources = await db.SapSourceDefinitions.ToListAsync();
|
||||
var existingSapJoins = await db.SapJoinDefinitions.ToListAsync();
|
||||
var existingSapMappings = await db.SapFieldMappings.ToListAsync();
|
||||
var existingCentralRecords = await db.CentralSalesRecords.ToListAsync();
|
||||
|
||||
var preservedSharePointSecret = existingSharePoint?.ClientSecret ?? string.Empty;
|
||||
var preservedSourceSystemSecrets = existingSourceSystems.ToDictionary(
|
||||
@@ -180,13 +182,15 @@ public class ConfigTransferService : IConfigTransferService
|
||||
var preservedSiteSecrets = existingSites.ToDictionary(
|
||||
x => BuildSiteSignature(x.Land, x.TSC, x.Schema, x.SourceSystem),
|
||||
x => (x.UsernameOverride, x.PasswordOverride));
|
||||
var existingSiteSignaturesById = existingSites.ToDictionary(
|
||||
x => x.Id,
|
||||
x => BuildSiteSignature(x.Land, x.TSC, x.Schema, x.SourceSystem));
|
||||
|
||||
if (existingSapMappings.Count > 0) db.SapFieldMappings.RemoveRange(existingSapMappings);
|
||||
if (existingSapJoins.Count > 0) db.SapJoinDefinitions.RemoveRange(existingSapJoins);
|
||||
if (existingSapSources.Count > 0) db.SapSourceDefinitions.RemoveRange(existingSapSources);
|
||||
if (existingRules.Count > 0) db.FieldTransformationRules.RemoveRange(existingRules);
|
||||
if (existingExchangeRates.Count > 0) db.CurrencyExchangeRates.RemoveRange(existingExchangeRates);
|
||||
if (existingCentralRecords.Count > 0) db.CentralSalesRecords.RemoveRange(existingCentralRecords);
|
||||
if (existingSites.Count > 0) db.Sites.RemoveRange(existingSites);
|
||||
if (existingServers.Count > 0) db.HanaServers.RemoveRange(existingServers);
|
||||
if (existingSourceSystems.Count > 0) db.SourceSystemDefinitions.RemoveRange(existingSourceSystems);
|
||||
@@ -217,10 +221,6 @@ public class ConfigTransferService : IConfigTransferService
|
||||
LocalConsolidatedExportFolder = importedSettings.LocalConsolidatedExportFolder
|
||||
});
|
||||
|
||||
var importedSourceSystems = package.SourceSystemDefinitions.Count > 0
|
||||
? package.SourceSystemDefinitions
|
||||
: BuildDefaultSourceSystems();
|
||||
|
||||
foreach (var sourceSystem in importedSourceSystems)
|
||||
{
|
||||
preservedSourceSystemSecrets.TryGetValue(sourceSystem.Code, out var preserved);
|
||||
@@ -272,6 +272,7 @@ public class ConfigTransferService : IConfigTransferService
|
||||
}
|
||||
|
||||
var siteIdMap = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||
var importedSiteIdBySignature = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var site in package.Sites)
|
||||
{
|
||||
preservedSiteSecrets.TryGetValue(BuildSiteSignature(site.Land, site.TSC, site.Schema, site.SourceSystem), out var preserved);
|
||||
@@ -298,8 +299,52 @@ public class ConfigTransferService : IConfigTransferService
|
||||
db.Sites.Add(entity);
|
||||
await db.SaveChangesAsync();
|
||||
siteIdMap[site.Key] = entity.Id;
|
||||
importedSiteIdBySignature[BuildSiteSignature(site.Land, site.TSC, site.Schema, site.SourceSystem)] = entity.Id;
|
||||
}
|
||||
|
||||
var centralRecordsToPreserve = existingCentralRecords
|
||||
.Where(record => existingSiteSignaturesById.TryGetValue(record.SiteId, out var signature) && importedSiteIdBySignature.ContainsKey(signature))
|
||||
.Select(record =>
|
||||
{
|
||||
var signature = existingSiteSignaturesById[record.SiteId];
|
||||
return new CentralSalesRecord
|
||||
{
|
||||
StoredAtUtc = record.StoredAtUtc,
|
||||
SiteId = importedSiteIdBySignature[signature],
|
||||
SourceSystem = record.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
|
||||
};
|
||||
})
|
||||
.ToList();
|
||||
|
||||
if (centralRecordsToPreserve.Count > 0)
|
||||
db.CentralSalesRecords.AddRange(centralRecordsToPreserve);
|
||||
|
||||
if (package.FieldTransformationRules.Count > 0)
|
||||
{
|
||||
db.FieldTransformationRules.AddRange(package.FieldTransformationRules.Select(r => new FieldTransformationRule
|
||||
@@ -363,10 +408,53 @@ public class ConfigTransferService : IConfigTransferService
|
||||
}
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
|
||||
private static string BuildSiteSignature(string land, string tsc, string schema, string sourceSystem)
|
||||
=> $"{land}|{tsc}|{schema}|{sourceSystem}".ToUpperInvariant();
|
||||
|
||||
private static List<ConfigTransferSourceSystemDefinition> ResolveImportedSourceSystems(string json, ConfigTransferPackage package)
|
||||
{
|
||||
if (package.SourceSystemDefinitions.Count == 0)
|
||||
return BuildDefaultSourceSystems();
|
||||
|
||||
using var document = JsonDocument.Parse(json);
|
||||
if (!document.RootElement.TryGetProperty(nameof(ConfigTransferPackage.SourceSystemDefinitions), out var sourceSystemsElement) ||
|
||||
sourceSystemsElement.ValueKind != JsonValueKind.Array)
|
||||
{
|
||||
return package.SourceSystemDefinitions;
|
||||
}
|
||||
|
||||
var imported = package.SourceSystemDefinitions
|
||||
.Select((sourceSystem, index) =>
|
||||
{
|
||||
var hasExplicitConnectionKind =
|
||||
index < sourceSystemsElement.GetArrayLength() &&
|
||||
sourceSystemsElement[index].TryGetProperty(nameof(ConfigTransferSourceSystemDefinition.ConnectionKind), out _);
|
||||
|
||||
if (hasExplicitConnectionKind)
|
||||
return sourceSystem;
|
||||
|
||||
sourceSystem.ConnectionKind = InferLegacyConnectionKind(sourceSystem.Code);
|
||||
return sourceSystem;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return imported;
|
||||
}
|
||||
|
||||
private static string InferLegacyConnectionKind(string code)
|
||||
{
|
||||
if (string.Equals(code, "SAP", StringComparison.OrdinalIgnoreCase))
|
||||
return SourceSystemConnectionKinds.SapGateway;
|
||||
|
||||
if (string.Equals(code, "MANUAL_EXCEL", StringComparison.OrdinalIgnoreCase))
|
||||
return SourceSystemConnectionKinds.ManualExcel;
|
||||
|
||||
return SourceSystemConnectionKinds.Hana;
|
||||
}
|
||||
|
||||
private static List<ConfigTransferSourceSystemDefinition> BuildDefaultSourceSystems()
|
||||
{
|
||||
return
|
||||
|
||||
@@ -48,7 +48,7 @@ public class DatabaseInitializationService : IDatabaseInitializationService
|
||||
EnsureSitesTableSupportsOptionalHanaServer(db);
|
||||
EnsureExportSettingsTableSupportsCurrentSchema(db);
|
||||
EnsureHanaServersTableSupportsCurrentSchema(db);
|
||||
RepairBrokenSiteForeignKeys(db);
|
||||
RepairBrokenForeignKeys(db);
|
||||
AddColumnIfMissing(db, "HanaServers", "SourceSystem", "TEXT NOT NULL DEFAULT ''");
|
||||
AddColumnIfMissing(db, "HanaServers", "DatabaseName", "TEXT NOT NULL DEFAULT ''");
|
||||
AddColumnIfMissing(db, "HanaServers", "UseSsl", "INTEGER NOT NULL DEFAULT 0");
|
||||
@@ -166,26 +166,7 @@ public class DatabaseInitializationService : IDatabaseInitializationService
|
||||
using (var create = conn.CreateCommand())
|
||||
{
|
||||
create.Transaction = transaction;
|
||||
create.CommandText = @"
|
||||
CREATE TABLE Sites (
|
||||
Id INTEGER NOT NULL CONSTRAINT PK_Sites PRIMARY KEY AUTOINCREMENT,
|
||||
HanaServerId INTEGER NULL,
|
||||
Schema TEXT NOT NULL,
|
||||
TSC TEXT NOT NULL,
|
||||
Land TEXT NOT NULL,
|
||||
SourceSystem TEXT NOT NULL DEFAULT 'SAP',
|
||||
UsernameOverride TEXT NOT NULL DEFAULT '',
|
||||
PasswordOverride TEXT NOT NULL DEFAULT '',
|
||||
LocalExportFolderOverride TEXT NOT NULL DEFAULT '',
|
||||
ManualImportFilePath TEXT NOT NULL DEFAULT '',
|
||||
ManualImportLastUploadedAtUtc TEXT NULL,
|
||||
SapServiceUrl TEXT NOT NULL DEFAULT '',
|
||||
SapEntitySet TEXT NOT NULL DEFAULT '',
|
||||
SapEntitySetsCache TEXT NOT NULL DEFAULT '',
|
||||
SapEntitySetsRefreshedAtUtc TEXT NULL,
|
||||
IsActive INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Sites_HanaServers_HanaServerId FOREIGN KEY (HanaServerId) REFERENCES HanaServers (Id)
|
||||
);";
|
||||
create.CommandText = GetSitesCreateSql();
|
||||
create.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
@@ -195,8 +176,9 @@ CREATE TABLE Sites (
|
||||
copy.CommandText = @"
|
||||
INSERT INTO Sites (
|
||||
Id, HanaServerId, Schema, TSC, Land, SourceSystem,
|
||||
UsernameOverride, PasswordOverride, LocalExportFolderOverride, SapServiceUrl, SapEntitySet,
|
||||
ManualImportFilePath, ManualImportLastUploadedAtUtc, SapEntitySetsCache, SapEntitySetsRefreshedAtUtc, IsActive
|
||||
UsernameOverride, PasswordOverride, LocalExportFolderOverride, ManualImportFilePath,
|
||||
ManualImportLastUploadedAtUtc, SapServiceUrl, SapEntitySet, SapEntitySetsCache,
|
||||
SapEntitySetsRefreshedAtUtc, IsActive
|
||||
)
|
||||
SELECT
|
||||
Id, HanaServerId, Schema, TSC, Land,
|
||||
@@ -229,13 +211,13 @@ FROM Sites_old;";
|
||||
enableFk.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
private static void RepairBrokenSiteForeignKeys(AppDbContext db)
|
||||
private static void RepairBrokenForeignKeys(AppDbContext db)
|
||||
{
|
||||
var conn = db.Database.GetDbConnection();
|
||||
if (conn.State != ConnectionState.Open)
|
||||
conn.Open();
|
||||
|
||||
var tablesToRepair = new[]
|
||||
var siteDependentTables = new[]
|
||||
{
|
||||
("ExportLogs", GetExportLogsCreateSql()),
|
||||
("AppEventLogs", GetAppEventLogsCreateSql()),
|
||||
@@ -245,14 +227,17 @@ FROM Sites_old;";
|
||||
("SapFieldMappings", GetSapFieldMappingsCreateSql())
|
||||
};
|
||||
|
||||
foreach (var (tableName, createSql) in tablesToRepair)
|
||||
foreach (var (tableName, createSql) in siteDependentTables)
|
||||
{
|
||||
if (TableReferencesSitesOld(conn, tableName))
|
||||
if (TableReferences(conn, tableName, "Sites_old"))
|
||||
RebuildTable(conn, tableName, createSql);
|
||||
}
|
||||
|
||||
if (TableReferences(conn, "Sites", "HanaServers_repair_old"))
|
||||
RebuildTable(conn, "Sites", GetSitesCreateSql());
|
||||
}
|
||||
|
||||
private static bool TableReferencesSitesOld(System.Data.Common.DbConnection connection, string tableName)
|
||||
private static bool TableReferences(System.Data.Common.DbConnection connection, string tableName, string referencedTableName)
|
||||
{
|
||||
using var command = connection.CreateCommand();
|
||||
command.CommandText = "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = $tableName;";
|
||||
@@ -263,7 +248,7 @@ FROM Sites_old;";
|
||||
command.Parameters.Add(parameter);
|
||||
|
||||
var sql = command.ExecuteScalar()?.ToString() ?? string.Empty;
|
||||
return sql.Contains("Sites_old", StringComparison.OrdinalIgnoreCase);
|
||||
return sql.Contains(referencedTableName, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static void RebuildTable(System.Data.Common.DbConnection connection, string tableName, string createSql)
|
||||
@@ -383,6 +368,27 @@ CREATE TABLE HanaServers (
|
||||
AdditionalParams TEXT NOT NULL DEFAULT ''
|
||||
);";
|
||||
|
||||
private static string GetSitesCreateSql() => @"
|
||||
CREATE TABLE Sites (
|
||||
Id INTEGER NOT NULL CONSTRAINT PK_Sites PRIMARY KEY AUTOINCREMENT,
|
||||
HanaServerId INTEGER NULL,
|
||||
Schema TEXT NOT NULL,
|
||||
TSC TEXT NOT NULL,
|
||||
Land TEXT NOT NULL,
|
||||
SourceSystem TEXT NOT NULL DEFAULT 'SAP',
|
||||
UsernameOverride TEXT NOT NULL DEFAULT '',
|
||||
PasswordOverride TEXT NOT NULL DEFAULT '',
|
||||
LocalExportFolderOverride TEXT NOT NULL DEFAULT '',
|
||||
ManualImportFilePath TEXT NOT NULL DEFAULT '',
|
||||
ManualImportLastUploadedAtUtc TEXT NULL,
|
||||
SapServiceUrl TEXT NOT NULL DEFAULT '',
|
||||
SapEntitySet TEXT NOT NULL DEFAULT '',
|
||||
SapEntitySetsCache TEXT NOT NULL DEFAULT '',
|
||||
SapEntitySetsRefreshedAtUtc TEXT NULL,
|
||||
IsActive INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Sites_HanaServers_HanaServerId FOREIGN KEY (HanaServerId) REFERENCES HanaServers (Id)
|
||||
);";
|
||||
|
||||
private static string GetAppEventLogsCreateSql() => @"
|
||||
CREATE TABLE AppEventLogs (
|
||||
Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
@@ -3,5 +3,6 @@ namespace TrafagSalesExporter.Services;
|
||||
public interface ISharePointUploadService
|
||||
{
|
||||
Task UploadAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string exportFolder, string land, string localFilePath);
|
||||
Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference);
|
||||
Task TestConnectionAsync(string tenantId, string clientId, string clientSecret, string siteUrl);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,45 @@ public class SharePointUploadService : ISharePointUploadService
|
||||
await graphClient.Drives[drive.Id].Root.ItemWithPath(remotePath).Content.PutAsync(stream);
|
||||
}
|
||||
|
||||
public async Task<string> DownloadToTempFileAsync(string tenantId, string clientId, string clientSecret, string siteUrl, string fileReference)
|
||||
{
|
||||
var normalizedTenantId = Normalize(tenantId);
|
||||
var normalizedClientId = Normalize(clientId);
|
||||
var normalizedClientSecret = Normalize(clientSecret);
|
||||
var normalizedSiteUrl = Normalize(siteUrl);
|
||||
var normalizedReference = Normalize(fileReference);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(normalizedReference))
|
||||
throw new InvalidOperationException("SharePoint-Dateireferenz fehlt.");
|
||||
|
||||
var credential = new ClientSecretCredential(normalizedTenantId, normalizedClientId, normalizedClientSecret);
|
||||
var graphClient = new GraphServiceClient(credential, ["https://graph.microsoft.com/.default"]);
|
||||
|
||||
var siteUri = new Uri(normalizedSiteUrl);
|
||||
var sitePath = siteUri.AbsolutePath.TrimEnd('/');
|
||||
var site = await graphClient.Sites[$"{siteUri.Host}:{sitePath}"].GetAsync();
|
||||
|
||||
if (site?.Id is null)
|
||||
throw new InvalidOperationException("SharePoint Site konnte nicht gefunden werden.");
|
||||
|
||||
var drive = await graphClient.Sites[site.Id].Drive.GetAsync();
|
||||
if (drive?.Id is null)
|
||||
throw new InvalidOperationException("SharePoint Dokumentenbibliothek konnte nicht gefunden werden.");
|
||||
|
||||
var remotePath = ResolveRemotePath(normalizedReference, siteUri);
|
||||
var fileName = Path.GetFileName(remotePath);
|
||||
if (string.IsNullOrWhiteSpace(fileName))
|
||||
throw new InvalidOperationException("Aus der SharePoint-Dateireferenz konnte kein Dateiname gelesen werden.");
|
||||
|
||||
await using var contentStream = await graphClient.Drives[drive.Id].Root.ItemWithPath(remotePath).Content.GetAsync()
|
||||
?? throw new InvalidOperationException("SharePoint-Datei konnte nicht gelesen werden.");
|
||||
|
||||
var tempPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}_{fileName}");
|
||||
await using var targetStream = File.Create(tempPath);
|
||||
await contentStream.CopyToAsync(targetStream);
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
public async Task TestConnectionAsync(string tenantId, string clientId, string clientSecret, string siteUrl)
|
||||
{
|
||||
var normalizedTenantId = Normalize(tenantId);
|
||||
@@ -86,6 +125,24 @@ public class SharePointUploadService : ISharePointUploadService
|
||||
|
||||
private static string Normalize(string value) => value?.Trim() ?? string.Empty;
|
||||
|
||||
private static string ResolveRemotePath(string fileReference, Uri siteUri)
|
||||
{
|
||||
if (Uri.TryCreate(fileReference, UriKind.Absolute, out var fileUri))
|
||||
{
|
||||
if (!string.Equals(fileUri.Host, siteUri.Host, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException("Die SharePoint-Datei muss auf derselben SharePoint-Site liegen wie die zentrale Konfiguration.");
|
||||
|
||||
var sitePath = siteUri.AbsolutePath.TrimEnd('/');
|
||||
var absolutePath = Uri.UnescapeDataString(fileUri.AbsolutePath);
|
||||
if (absolutePath.StartsWith(sitePath, StringComparison.OrdinalIgnoreCase))
|
||||
absolutePath = absolutePath[sitePath.Length..];
|
||||
|
||||
return absolutePath.Trim('/').Trim();
|
||||
}
|
||||
|
||||
return fileReference.Trim('/').Trim();
|
||||
}
|
||||
|
||||
private static string BuildInputPreview(string tenantId, string clientId, string clientSecret, string siteUrl)
|
||||
{
|
||||
var maskedSecret = string.IsNullOrEmpty(clientSecret)
|
||||
|
||||
@@ -110,13 +110,48 @@ public class SiteExportService : ISiteExportService
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(site.ManualImportFilePath))
|
||||
throw new InvalidOperationException($"Standort '{site.Land}' hat keine manuelle Excel-Datei.");
|
||||
if (!File.Exists(site.ManualImportFilePath))
|
||||
throw new InvalidOperationException($"Die manuelle Excel-Datei wurde nicht gefunden: {site.ManualImportFilePath}");
|
||||
string? tempManualImportPath = null;
|
||||
try
|
||||
{
|
||||
var manualImportPath = site.ManualImportFilePath.Trim();
|
||||
if (File.Exists(manualImportPath))
|
||||
{
|
||||
filePath = manualImportPath;
|
||||
}
|
||||
else if (LooksLikeSharePointReference(manualImportPath))
|
||||
{
|
||||
if (spConfig is null ||
|
||||
string.IsNullOrWhiteSpace(spConfig.TenantId) ||
|
||||
string.IsNullOrWhiteSpace(spConfig.ClientId) ||
|
||||
string.IsNullOrWhiteSpace(spConfig.ClientSecret) ||
|
||||
string.IsNullOrWhiteSpace(spConfig.SiteUrl))
|
||||
{
|
||||
throw new InvalidOperationException("Fuer SharePoint-Manuellimport fehlt eine vollstaendige SharePoint-Konfiguration in Settings.");
|
||||
}
|
||||
|
||||
updateStatus?.Invoke("Manuelle Excel lesen...");
|
||||
await _appEventLogService.WriteAsync("Export", "Manuelle Excel lesen", siteId: site.Id, land: site.Land,
|
||||
details: site.ManualImportFilePath);
|
||||
records = await _manualExcelImportService.ReadSalesRecordsAsync(site.ManualImportFilePath, site);
|
||||
updateStatus?.Invoke("Manuelle Excel von SharePoint laden...");
|
||||
await _appEventLogService.WriteAsync("Export", "Manuelle Excel von SharePoint laden", siteId: site.Id, land: site.Land,
|
||||
details: manualImportPath);
|
||||
tempManualImportPath = await _sharePointService.DownloadToTempFileAsync(
|
||||
spConfig.TenantId, spConfig.ClientId, spConfig.ClientSecret, spConfig.SiteUrl, manualImportPath);
|
||||
filePath = manualImportPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"Die manuelle Excel-Datei wurde nicht gefunden: {manualImportPath}");
|
||||
}
|
||||
|
||||
var readPath = tempManualImportPath ?? filePath;
|
||||
updateStatus?.Invoke("Manuelle Excel lesen...");
|
||||
await _appEventLogService.WriteAsync("Export", "Manuelle Excel lesen", siteId: site.Id, land: site.Land,
|
||||
details: filePath);
|
||||
records = await _manualExcelImportService.ReadSalesRecordsAsync(readPath, site);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(tempManualImportPath) && File.Exists(tempManualImportPath))
|
||||
File.Delete(tempManualImportPath);
|
||||
}
|
||||
|
||||
updateStatus?.Invoke("Transformationen anwenden...");
|
||||
await _appEventLogService.WriteAsync("Export", "Transformationen anwenden", siteId: site.Id, land: site.Land,
|
||||
@@ -127,7 +162,6 @@ public class SiteExportService : ISiteExportService
|
||||
.ToListAsync();
|
||||
_transformationService.Apply(records, rules);
|
||||
|
||||
filePath = site.ManualImportFilePath;
|
||||
log.RowCount = records.Count;
|
||||
}
|
||||
else
|
||||
@@ -272,6 +306,12 @@ public class SiteExportService : ISiteExportService
|
||||
: configured;
|
||||
}
|
||||
|
||||
private static bool LooksLikeSharePointReference(string path)
|
||||
=> path.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
|
||||
path.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ||
|
||||
path.StartsWith("/Shared Documents/", StringComparison.OrdinalIgnoreCase) ||
|
||||
path.StartsWith("Shared Documents/", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private static Site CloneSiteWithSapServiceUrl(Site site, string sapServiceUrl)
|
||||
{
|
||||
return new Site
|
||||
|
||||
Reference in New Issue
Block a user