Files
BeWoPlaner/DakotaSender/Program.cs

447 lines
10 KiB
C#
Raw Normal View History

using BS.Shared;
using BS.Shared.AppSender;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.GkvAbrechnung;
using BS.Shared.Exceptions;
using System;
2024-07-02 11:44:48 +02:00
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace DakotaSender
{
class Program
{
static readonly string TEST_TENANT = "5000000000";
static readonly string TEST_TENANT_2 = "7375324044";
static bool time_in_line = false;
static bool is_dakota_running = false;
static Dictionary<string, Dictionary<long, GkvClientResultRequestDC>> ten2user2req;
static void Main(string[] args)
{
FileStream filestream = new FileStream(Config.LogPath, FileMode.Append);
var streamwriter = new StreamWriter(filestream);
streamwriter.AutoFlush = true;
Console.SetOut(streamwriter);
Console.SetError(streamwriter);
try
2024-10-23 17:05:20 +02:00
{
PrintTitle();
CheckDakotaStatus();
HandleQueueFiles();
2024-10-31 09:20:01 +01:00
HandleResults();
}
catch (Exception e)
{
PrintException(e);
if (is_dakota_running)
{
PrintSeperator();
PrintLine($"Verarbeitung im Silent Modus fehlgeschlagen. dakota30.exe läuft (bereits).");
PrintLine("Ignoriere Verarbeitung aktuell. Versuche im nächsten Programm Aufruf erneut.");
}
PrintSeperator();
2024-10-23 17:05:20 +02:00
}
2024-07-03 16:44:58 +02:00
PrintEnd();
}
internal static void PrintTitle()
{
PrintLine();
2024-10-31 09:20:01 +01:00
PrintSeperator();
PrintLine("Dakota Sender Modul");
2024-10-31 09:20:01 +01:00
PrintSeperator();
}
2024-10-31 09:20:01 +01:00
internal static void PrintSeperator() => PrintLine("-------------------");
internal static void PrintEnd()
{
PrintLine("Ende");
2024-10-31 09:20:01 +01:00
PrintSeperator();
}
internal static void PrintLine() => PrintWithTime("\n", false);
internal static void PrintLine(string line)
{
PrintWithTime(line + "\n", !time_in_line);
2024-07-03 16:44:58 +02:00
time_in_line = false;
}
internal static void Print(string line)
{
PrintWithTime(line, !time_in_line);
time_in_line = true;
}
internal static void PrintWithTime(string line, bool showTime)
{
if (showTime)
Console.Write($"[{DateTime.Now:dd.MM.yy HH:mm:ss.fff}] {line}");
2024-10-23 17:05:20 +02:00
else
Console.Write(line);
}
internal static void PrintFileInfo(DakotaSystemFile file)
{
Print($"Verarbeite Datei: {file.SourceNutzdatendatei.Name}");
PrintLine($"(T:{file.Tenant}, U:{file.ApplicationUserOid}, P:{file.ProtokollOid}, D:{file.Datenannahmestelle})");
}
internal static void PrintException(Exception e) => PrintLine(e.ToString());
static void CheckDakotaStatus()
{
PrintLine("Überprüfe Dakota Status:");
var code = ExecuteDakota("-s");
Returncodes.EvaluateStatusCode(code, out is_dakota_running, out bool accept, out string message);
if (accept)
{
PrintLine(message);
}
else
{
throw new Exception($"Statuscode {code} wird nicht akzeptiert. {message}");
}
2024-10-31 09:20:01 +01:00
PrintSeperator();
}
static Dictionary<string, Dictionary<string, List<DakotaSystemFile>>> ScanQueueFolder()
{
var queue = Config.QueueFolder;
var files = queue.GetFiles("*.auf", SearchOption.TopDirectoryOnly)
.OrderBy(x => x.FullName);
var ten2dat2files = new Dictionary<string, Dictionary<string, List<DakotaSystemFile>>>();
foreach (var auft in files)
{
var file = ScanQueueFile(auft);
if (file is null)
continue;
var tenant = file.Tenant;
var datenannahmestelle = file.Datenannahmestelle;
if (!ten2dat2files.ContainsKey(tenant))
ten2dat2files.Add(tenant, new Dictionary<string, List<DakotaSystemFile>>());
var dat2files = ten2dat2files[tenant];
if (!dat2files.ContainsKey(datenannahmestelle))
dat2files.Add(datenannahmestelle, new List<DakotaSystemFile>());
ten2dat2files[tenant][datenannahmestelle].Add(file);
}
if (ten2dat2files.Any())
return ten2dat2files;
PrintLine("Keine gültigen Dakota Dateien in Queue gefunden.");
return null;
}
static DakotaSystemFile ScanQueueFile(FileInfo auft)
{
try
{
var nutz_fullname = auft.FullName.Substring(0, auft.FullName.Length - 4);
var nutz = new FileInfo(nutz_fullname);
if (!nutz.Exists)
{
PrintLine($"{auft.FullName} wird ignoriert. {nutz.FullName} nicht vorhanden");
return null;
}
PrintLine($"- {auft.FullName}");
var split = nutz.Name.Split('_');
var tenant = split[0];
var app_oid = long.Parse(split[1]);
var p_oid = long.Parse(split[2]);
var datenannahmestelle = split[3];
var transfername = split[4];
// Muss nachher nur entfernt werden, um andere zu testen
// Ggf Tool einbauen?
if (tenant != TEST_TENANT && tenant != TEST_TENANT_2)
{
PrintLine($"{auft.FullName} wird ignoriert. Tenant {tenant} nicht gültig.");
return null;
}
var file = new DakotaSystemFile()
{
SourceAuftragsdatei = auft,
SourceNutzdatendatei = nutz,
Tenant = tenant,
ProtokollOid = p_oid,
ApplicationUserOid = app_oid,
Datenannahmestelle = datenannahmestelle,
Transfername = transfername,
};
return file;
}
catch(Exception e)
{
PrintException(e);
}
return null;
}
static void HandleQueueFiles()
{
PrintLine("Scanne Dakota Dateien:");
var ten2dat2files = ScanQueueFolder();
PrintSeperator();
if (ten2dat2files is null)
{
return;
}
ten2user2req = new Dictionary<string, Dictionary<long, GkvClientResultRequestDC>>();
PrintLine("Bearbeite Queue");
2024-10-31 09:20:01 +01:00
PrintSeperator();
foreach (var kv in ten2dat2files)
{
var ten = kv.Key;
var dat2files = kv.Value;
foreach (var kv2 in dat2files)
{
var dat = kv2.Key;
var files = kv2.Value;
PrintLine($"Bearbeite Datenannahmestelle \'{dat}\' für Tenant \'{ten}\':");
HandleQueueFiles(files);
2024-10-31 09:20:01 +01:00
PrintSeperator();
CheckDakotaStatus();
}
}
PrintLine("Bearbeitung Queue beendet");
PrintSeperator();
}
static void HandleQueueFiles(List<DakotaSystemFile> files)
{
bool error = false;
foreach (var file in files)
2024-10-23 17:05:20 +02:00
{
if (!error)
{
var msg = HandleQueueFile(file, out bool success);
if (success)
{
PrintLine(msg);
Add2Results(file, GkvTransferResultType.Success);
}
else
{
error = true;
PrintLine("Fehler gefunden. " + msg);
Add2Results(file, GkvTransferResultType.FailSoft, msg, "DS:Fehler");
FileController.CopyFileToFailed(file);
}
}
else
{
PrintLine($"Folgefehler: {file.SourceNutzdatendatei.Name}");
Add2Results(file, GkvTransferResultType.FailFollowUp, "Wird neu erstellt und übertragen.", "DS:Folgefehler");
}
FileController.DeleteQueueFile(file);
2024-10-23 17:05:20 +02:00
}
}
/// <summary>
/// Bearbeitet eine File. Wenn dakota.exe während der Bearbeitung gestartet wird, wird das Dakota Verzeichnis gesäubert und die weitere Bearbeitung durch throw Exception unterbrochen.
/// </summary>
/// <param name="file"></param>
/// <param name="success"></param>
/// <returns></returns>
static string HandleQueueFile(DakotaSystemFile file, out bool success)
{
success = false;
PrintFileInfo(file);
2024-07-03 16:44:58 +02:00
if (!Config.IsDatenannahmestelleValid(file.Datenannahmestelle))
return $"Datenannahmestelle {file.Datenannahmestelle} unbekannt.";
2024-07-03 16:44:58 +02:00
FileController.CopyFileToDestination(file);
2024-07-03 16:44:58 +02:00
Print("Sende via Dakota. ");
2024-07-03 16:44:58 +02:00
var rc = ExecuteDakota("-x");
2024-07-03 16:44:58 +02:00
Returncodes.EvaluateSendCode(rc, out is_dakota_running, out success, out string message);
2024-07-03 16:44:58 +02:00
if (!success)
{
FileController.DeleteDakotaFile(file);
}
2024-07-03 16:44:58 +02:00
if (is_dakota_running)
{
throw new Exception();
}
return message;
}
static void Add2Results(DakotaSystemFile file, GkvTransferResultType type, string nachricht = null, string title = null)
{
var tenant = file.Tenant;
var user = file.ApplicationUserOid;
2024-07-03 16:44:58 +02:00
if (!ten2user2req.ContainsKey(tenant))
ten2user2req.Add(tenant, new Dictionary<long, GkvClientResultRequestDC>());
2024-07-03 16:44:58 +02:00
var user2req = ten2user2req[tenant];
2024-07-02 15:30:39 +02:00
if (!user2req.ContainsKey(user))
user2req.Add(user, new GkvClientResultRequestDC()
{
UserOid = file.ApplicationUserOid,
Tenant = file.Tenant,
GkvSecretKey = Config.GkvSecretKey
});
2024-07-03 16:44:58 +02:00
var req = user2req[user];
if (req.ResultDCs is null)
req.ResultDCs = new List<GkvServerResultDC>();
var item = new GkvServerResultDC();
item.Datum = DateTime.Now;
item.Nachricht = nachricht;
item.ProtokollOid = file.ProtokollOid;
item.ResultType = type;
item.Titel = title;
req.ResultDCs.Add(item);
}
2024-10-31 09:20:01 +01:00
static void HandleResults()
{
PrintLine("Sende Ergebnisse:");
PrintSeperator();
if (ten2user2req is null || !ten2user2req.Any())
2024-10-31 09:20:01 +01:00
return;
var task = HandleResultsAsync();
task.Wait();
if (task.IsFaulted)
throw task.Exception;
}
2024-10-30 12:04:38 +01:00
static async Task HandleResultsAsync()
{
2024-10-30 12:04:38 +01:00
var tasks = new List<Task>();
foreach (var tenant in ten2user2req.Keys)
{
foreach (var user in ten2user2req[tenant].Keys)
{
var req = ten2user2req[tenant][user];
2024-10-30 12:02:42 +01:00
var task = HandleResult(req, tenant, user);
2024-10-30 12:04:38 +01:00
tasks.Add(task);
}
}
2024-10-30 12:02:42 +01:00
2024-10-30 12:04:38 +01:00
await Task.WhenAll(tasks);
}
2024-10-30 12:02:42 +01:00
static async Task HandleResult(GkvClientResultRequestDC req, string tenant, long user)
{
var res = new GkvResponseDC(false, "empty");
try
{
PrintLine($"Sende Ergebnis an: Tenant: {req.Tenant}, User; {req.UserOid}");
res = await GkvSender.SendKundenAppClientRequestAsync<GkvClientResultRequestDC, GkvResponseDC>(req, tenant, user);
if (res.Success)
PrintLine("Erfolgreich!");
else
PrintLine("Fehler: " + res.Message);
}
catch (GkvException e)
{
PrintException(e);
}
catch (Exception e)
{
PrintException(e);
}
PrintSeperator();
if (res.Success)
return;
foreach (var result in req.ResultDCs)
{
FileController.SaveAsXmlFileInResultFolder(result, tenant, user);
}
PrintSeperator();
}
static int ExecuteDakota(string arg)
{
var fileinfo = Config.DakotaExe;
PrintLine($"{fileinfo.Name} {arg} wird ausgeführt");
var process = Process.Start(Config.DakotaExe.FullName, arg);
var success = process.WaitForExit(Config.ProcessWaitForExitMs);
if (success)
{
return process.ExitCode;
}
else
{
throw new Exception($"dakota30.exe - Timeout exceeded ({Config.ProcessWaitForExitMs} ms). ");
}
}
}
2024-07-02 11:44:48 +02:00
}