2026-07-06 14:48:54 +02:00
using BeWo.ServerUtils.Core ;
using BS.Shared ;
2024-10-30 11:43:23 +01:00
using BS.Shared.AppSender ;
2024-11-22 10:59:57 +01:00
using BS.Shared.Core ;
2024-10-30 11:43:23 +01:00
using BS.Shared.DataContracts ;
2024-10-29 15:23:30 +01:00
using BS.Shared.DataContracts.GkvAbrechnung ;
2024-10-30 11:43:23 +01:00
using BS.Shared.Exceptions ;
2024-10-29 15:23:30 +01:00
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
{
2024-10-29 15:23:30 +01:00
class Program
{
static bool time_in_line = false ;
static bool is_dakota_running = false ;
2024-10-30 11:43:23 +01:00
static Dictionary < string , Dictionary < long , GkvClientResultRequestDC > > ten2user2req ;
2024-10-29 15:23:30 +01:00
static void Main ( string [ ] args )
{
2024-12-18 12:36:51 +01:00
if ( Config . QueueFolder . GetFiles ( "*.auf" , SearchOption . TopDirectoryOnly ) . Length = = 0 )
{
return ;
}
var logfolderpath = Config . LogPath ;
var logfilename = Config . LogSingleFile ? Config . LogFileName : $"log_{DateTime.Today:yyyyMMdd}.txt" ;
var log4day = Path . Combine ( logfolderpath , logfilename ) ;
2024-12-02 14:00:28 +01:00
FileStream filestream = new FileStream ( log4day , FileMode . Append ) ;
2024-10-29 15:23:30 +01:00
var streamwriter = new StreamWriter ( filestream ) ;
streamwriter . AutoFlush = true ;
Console . SetOut ( streamwriter ) ;
Console . SetError ( streamwriter ) ;
try
2024-10-23 17:05:20 +02:00
{
2025-01-13 15:36:33 +01:00
PrintSeperator ( ) ;
2024-10-29 15:23:30 +01:00
HandleQueueFiles ( ) ;
2024-10-30 11:43:23 +01:00
2025-01-13 15:36:33 +01:00
PrintSeperator ( ) ;
2024-10-31 09:20:01 +01:00
HandleResults ( ) ;
2024-10-29 15:23:30 +01:00
}
catch ( Exception e )
{
2024-11-22 10:59:57 +01:00
HandleException ( e , null ) ;
2024-10-29 15:23:30 +01:00
if ( is_dakota_running )
{
2024-11-05 09:52:36 +01:00
PrintSeperator ( ) ;
2024-10-29 15:23:30 +01:00
PrintLine ( $"Verarbeitung im Silent Modus fehlgeschlagen. dakota30.exe läuft (bereits)." ) ;
PrintLine ( "Ignoriere Verarbeitung aktuell. Versuche im nächsten Programm Aufruf erneut." ) ;
}
2024-10-31 15:38:24 +01:00
PrintSeperator ( ) ;
2024-10-23 17:05:20 +02:00
}
2025-01-31 10:45:42 +01:00
PrintLine ( ) ;
2024-10-29 15:23:30 +01:00
}
2024-10-30 11:43:23 +01:00
internal static void PrintTitle ( )
2024-10-29 15:23:30 +01:00
{
2024-10-31 15:38:24 +01:00
PrintLine ( ) ;
2024-10-31 09:20:01 +01:00
PrintSeperator ( ) ;
2024-10-29 15:23:30 +01:00
PrintLine ( "Dakota Sender Modul" ) ;
2024-10-31 09:20:01 +01:00
PrintSeperator ( ) ;
2024-10-29 15:23:30 +01:00
}
2024-10-31 09:20:01 +01:00
internal static void PrintSeperator ( ) = > PrintLine ( "-------------------" ) ;
2024-10-30 11:43:23 +01:00
internal static void PrintEnd ( )
2024-10-29 15:23:30 +01:00
{
PrintLine ( "Ende" ) ;
2024-10-31 09:20:01 +01:00
PrintSeperator ( ) ;
2024-10-29 15:23:30 +01:00
}
2024-10-31 15:38:24 +01:00
internal static void PrintLine ( ) = > PrintWithTime ( "\n" , false ) ;
2024-10-30 11:43:23 +01:00
internal static void PrintLine ( string line )
2024-10-29 15:23:30 +01:00
{
PrintWithTime ( line + "\n" , ! time_in_line ) ;
2024-07-03 16:44:58 +02:00
2024-10-29 15:23:30 +01:00
time_in_line = false ;
}
2024-10-30 11:43:23 +01:00
internal static void Print ( string line )
2024-10-29 15:23:30 +01:00
{
PrintWithTime ( line , ! time_in_line ) ;
time_in_line = true ;
}
2024-10-30 11:43:23 +01:00
internal static void PrintWithTime ( string line , bool showTime )
2024-10-29 15:23:30 +01:00
{
if ( showTime )
Console . Write ( $"[{DateTime.Now:dd.MM.yy HH:mm:ss.fff}] {line}" ) ;
2024-10-23 17:05:20 +02:00
else
2024-10-29 15:23:30 +01:00
Console . Write ( line ) ;
}
2024-10-30 11:43:23 +01:00
internal static void PrintFileInfo ( DakotaSystemFile file )
2024-10-29 15:23:30 +01:00
{
2025-11-12 10:41:33 +01:00
Print ( $"Verarbeite Datei: {file.SourceNutzdatendatei.Name}" ) ;
2024-10-31 15:38:24 +01:00
PrintLine ( $"(T:{file.Tenant}, U:{file.ApplicationUserOid}, P:{file.ProtokollOid}, D:{file.Datenannahmestelle})" ) ;
2024-10-29 15:23:30 +01:00
}
2025-11-12 10:41:33 +01:00
internal static void HandleException ( Exception e , string tenant )
2024-11-22 10:59:57 +01:00
{
MailUtils . SendGkvModuleErrorMail ( "GkvSender Exception" , e , tenant ) ;
2025-11-12 10:41:33 +01:00
PrintLine ( e . ToString ( ) ) ;
2024-11-22 10:59:57 +01:00
}
2024-10-29 15:23:30 +01:00
2025-01-13 15:36:33 +01:00
static void CheckDakotaStatus ( bool sub = false )
2024-10-29 15:23:30 +01:00
{
2025-01-13 15:36:33 +01:00
if ( sub )
Print ( "- " ) ;
Print ( "Überprüfe Dakota Status: " ) ;
2024-10-29 15:23:30 +01:00
var code = ExecuteDakota ( "-s" ) ;
Returncodes . EvaluateStatusCode ( code , out is_dakota_running , out bool accept , out string message ) ;
if ( accept )
{
2025-01-13 15:36:33 +01:00
PrintLine ( "Ok." ) ;
2024-10-29 15:23:30 +01:00
}
else
{
throw new Exception ( $"Statuscode {code} wird nicht akzeptiert. {message}" ) ;
}
}
2024-11-05 09:52:36 +01:00
2024-10-29 15:23:30 +01:00
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 )
2024-11-05 09:52:36 +01:00
{
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 )
{
2024-11-22 10:59:57 +01:00
string tenant = null ;
2024-11-05 09:52:36 +01:00
try
2024-10-29 15:23:30 +01:00
{
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" ) ;
2024-11-05 09:52:36 +01:00
return null ;
2024-10-29 15:23:30 +01:00
}
2024-10-31 15:38:24 +01:00
PrintLine ( $"- {auft.FullName}" ) ;
2024-10-29 15:23:30 +01:00
var split = nutz . Name . Split ( '_' ) ;
2024-11-22 10:59:57 +01:00
tenant = split [ 0 ] ;
2024-10-31 15:49:41 +01:00
var app_oid = long . Parse ( split [ 1 ] ) ;
var p_oid = long . Parse ( split [ 2 ] ) ;
2024-10-29 15:23:30 +01:00
var datenannahmestelle = split [ 3 ] ;
var transfername = split [ 4 ] ;
2025-01-13 16:06:56 +01:00
var test = DakotaSenderUtils . IsTenantTest ( tenant ) ;
var allow = DakotaSenderUtils . IsTenantAllowed ( tenant ) ;
2025-11-12 10:41:33 +01:00
if ( ! test & & ! allow )
2024-10-29 15:23:30 +01:00
{
2025-01-13 16:06:56 +01:00
PrintLine ( $"{auft.FullName} wird ignoriert. Tenant \'{tenant}\' ungültig." ) ;
2024-11-05 09:52:36 +01:00
return null ;
2024-10-29 15:23:30 +01:00
}
var file = new DakotaSystemFile ( )
{
2025-01-13 16:06:56 +01:00
TestCase = test ,
2024-10-29 15:23:30 +01:00
SourceAuftragsdatei = auft ,
SourceNutzdatendatei = nutz ,
Tenant = tenant ,
ProtokollOid = p_oid ,
ApplicationUserOid = app_oid ,
Datenannahmestelle = datenannahmestelle ,
Transfername = transfername ,
} ;
2024-11-05 09:52:36 +01:00
return file ;
}
2025-11-12 10:41:33 +01:00
catch ( Exception e )
2024-11-05 09:52:36 +01:00
{
2024-11-22 10:59:57 +01:00
HandleException ( e , tenant ) ;
2024-10-29 15:23:30 +01:00
}
return null ;
}
static void HandleQueueFiles ( )
{
2025-01-13 15:36:33 +01:00
CheckDakotaStatus ( ) ;
PrintSeperator ( ) ;
2024-10-31 15:38:24 +01:00
PrintLine ( "Scanne Dakota Dateien:" ) ;
2024-10-29 15:23:30 +01:00
var ten2dat2files = ScanQueueFolder ( ) ;
2024-10-31 15:38:24 +01:00
PrintSeperator ( ) ;
2024-10-29 15:23:30 +01:00
if ( ten2dat2files is null )
2024-10-31 15:38:24 +01:00
{
2024-10-29 15:23:30 +01:00
return ;
2024-10-31 15:38:24 +01:00
}
2024-10-29 15:23:30 +01:00
2024-10-30 11:43:23 +01:00
ten2user2req = new Dictionary < string , Dictionary < long , GkvClientResultRequestDC > > ( ) ;
2024-10-29 15:23:30 +01:00
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 ;
2025-01-13 15:36:33 +01:00
//PrintLine($"Bearbeite Datenannahmestelle \'{dat}\' für Tenant \'{ten}\':");
2024-10-29 15:23:30 +01:00
2024-10-30 11:43:23 +01:00
HandleQueueFiles ( files ) ;
2024-10-31 09:20:01 +01:00
2025-01-13 15:36:33 +01:00
CheckDakotaStatus ( true ) ;
2024-10-29 15:23:30 +01:00
}
}
}
2024-10-30 11:43:23 +01:00
static void HandleQueueFiles ( List < DakotaSystemFile > files )
2024-10-29 15:23:30 +01:00
{
foreach ( var file in files )
2024-10-23 17:05:20 +02:00
{
2025-11-12 10:41:33 +01:00
var msg = HandleQueueFile ( file , out bool success ) ;
2024-11-14 17:24:18 +01:00
2025-11-12 10:41:33 +01:00
if ( success )
{
PrintLine ( msg ) ;
2024-10-29 15:23:30 +01:00
2025-11-12 10:41:33 +01:00
Add2Results ( file , GkvTransferResultType . Success ) ;
2024-10-30 11:43:23 +01:00
2025-11-12 10:41:33 +01:00
FileController . CopyFileToCopy ( file ) ;
2024-11-14 17:24:18 +01:00
2025-11-12 10:41:33 +01:00
FileController . CopyFileToSuccesss ( file ) ;
2024-10-29 15:23:30 +01:00
}
else
{
2025-11-12 10:41:33 +01:00
PrintLine ( "Fehler gefunden. " + msg ) ;
2024-10-29 15:23:30 +01:00
2025-11-12 10:41:33 +01:00
Add2Results ( file , GkvTransferResultType . FailSoft , msg , "DS:Fehler" ) ;
2024-10-29 15:23:30 +01:00
2025-11-12 10:41:33 +01:00
FileController . CopyFileToCopy ( file ) ;
2025-01-13 15:36:33 +01:00
2025-11-12 10:41:33 +01:00
FileController . CopyFileToFailed ( file ) ;
}
2025-01-13 15:36:33 +01:00
2025-11-12 10:41:33 +01:00
FileController . DeleteQueueFile ( file ) ;
2024-10-23 17:05:20 +02:00
}
2024-10-29 15:23:30 +01: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
2025-01-13 16:06:56 +01:00
if ( file . TestCase )
{
success = true ;
return "- TestCase. " ;
}
2024-10-29 15:23:30 +01:00
if ( ! Config . IsDatenannahmestelleValid ( file . Datenannahmestelle ) )
2025-01-13 16:06:56 +01:00
return $"- Datenannahmestelle {file.Datenannahmestelle} unbekannt." ;
2024-07-03 16:44:58 +02:00
2024-10-30 11:43:23 +01:00
FileController . CopyFileToDestination ( file ) ;
2024-07-03 16:44:58 +02:00
2025-01-13 15:36:33 +01:00
Print ( "- Sende via Dakota. " ) ;
2024-07-03 16:44:58 +02:00
2024-10-29 15:23:30 +01:00
var rc = ExecuteDakota ( "-x" ) ;
2024-07-03 16:44:58 +02:00
2024-10-29 15:23:30 +01:00
Returncodes . EvaluateSendCode ( rc , out is_dakota_running , out success , out string message ) ;
2024-07-03 16:44:58 +02:00
2024-10-31 16:18:51 +01:00
if ( ! success )
2024-10-29 15:23:30 +01:00
{
2024-10-30 11:43:23 +01:00
FileController . DeleteDakotaFile ( file ) ;
2024-10-31 16:18:51 +01:00
}
2024-07-03 16:44:58 +02:00
2024-10-31 16:18:51 +01:00
if ( is_dakota_running )
{
2024-10-29 15:23:30 +01:00
throw new Exception ( ) ;
}
2025-01-13 16:06:56 +01:00
if ( success )
return "Ok." ;
else
return message ;
2024-10-29 15:23:30 +01:00
}
2024-10-30 11:43:23 +01:00
static void Add2Results ( DakotaSystemFile file , GkvTransferResultType type , string nachricht = null , string title = null )
2024-10-29 15:23:30 +01:00
{
2024-10-30 11:43:23 +01:00
var tenant = file . Tenant ;
var user = file . ApplicationUserOid ;
2024-07-03 16:44:58 +02:00
2024-10-30 11:43:23 +01:00
if ( ! ten2user2req . ContainsKey ( tenant ) )
ten2user2req . Add ( tenant , new Dictionary < long , GkvClientResultRequestDC > ( ) ) ;
2024-07-03 16:44:58 +02:00
2024-10-30 11:43:23 +01:00
var user2req = ten2user2req [ tenant ] ;
2024-07-02 15:30:39 +02:00
2024-10-30 11:43:23 +01:00
if ( ! user2req . ContainsKey ( user ) )
2024-10-31 15:38:24 +01:00
user2req . Add ( user , new GkvClientResultRequestDC ( )
{
UserOid = file . ApplicationUserOid ,
Tenant = file . Tenant ,
GkvSecretKey = Config . GkvSecretKey
} ) ;
2024-07-03 16:44:58 +02:00
2024-10-30 11:43:23 +01:00
var req = user2req [ user ] ;
2024-10-29 15:23:30 +01:00
2024-10-30 11:43:23 +01:00
if ( req . ResultDCs is null )
req . ResultDCs = new List < GkvServerResultDC > ( ) ;
2024-10-29 15:23:30 +01:00
2024-10-30 11:43:23 +01:00
var item = new GkvServerResultDC ( ) ;
2024-10-29 15:23:30 +01:00
2024-10-30 11:43:23 +01:00
item . Datum = DateTime . Now ;
item . Nachricht = nachricht ;
item . ProtokollOid = file . ProtokollOid ;
item . ResultType = type ;
item . Titel = title ;
2024-10-29 15:23:30 +01:00
2024-10-30 11:43:23 +01:00
req . ResultDCs . Add ( item ) ;
2024-10-29 15:23:30 +01:00
}
2024-10-31 09:20:01 +01:00
static void HandleResults ( )
{
2024-10-31 15:38:24 +01:00
if ( ten2user2req is null | | ! ten2user2req . Any ( ) )
2024-10-31 09:20:01 +01:00
return ;
2024-12-02 14:00:28 +01:00
PrintLine ( "Sende Ergebnisse:" ) ;
PrintSeperator ( ) ;
2024-10-31 09:20:01 +01:00
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-29 15:23:30 +01:00
{
2024-10-30 12:04:38 +01:00
var tasks = new List < Task > ( ) ;
2024-10-30 11:43:23 +01:00
foreach ( var tenant in ten2user2req . Keys )
{
foreach ( var user in ten2user2req [ tenant ] . Keys )
{
var req = ten2user2req [ tenant ] [ user ] ;
2024-10-29 15:23:30 +01:00
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 11:43:23 +01:00
}
}
2024-10-30 12:02:42 +01:00
2024-10-30 12:04:38 +01:00
await Task . WhenAll ( tasks ) ;
2024-10-29 15:23:30 +01:00
}
2024-10-30 12:02:42 +01:00
static async Task HandleResult ( GkvClientResultRequestDC req , string tenant , long user )
2024-10-29 15:23:30 +01:00
{
2024-10-31 15:38:24 +01:00
var res = new GkvResponseDC ( false , "empty" ) ;
2024-10-30 11:43:23 +01:00
try
{
2024-10-31 15:38:24 +01:00
PrintLine ( $"Sende Ergebnis an: Tenant: {req.Tenant}, User; {req.UserOid}" ) ;
res = await GkvSender . SendKundenAppClientRequestAsync < GkvClientResultRequestDC , GkvResponseDC > ( req , tenant , user ) ;
2024-10-29 15:23:30 +01:00
2024-10-30 11:43:23 +01:00
if ( res . Success )
2024-10-31 15:38:24 +01:00
PrintLine ( "Erfolgreich!" ) ;
else
PrintLine ( "Fehler: " + res . Message ) ;
2024-10-30 11:43:23 +01:00
}
2024-11-05 09:52:36 +01:00
catch ( GkvException e )
2024-10-30 11:43:23 +01:00
{
2024-11-22 10:59:57 +01:00
HandleException ( e , tenant ) ;
2024-10-30 11:43:23 +01:00
}
2024-11-05 09:52:36 +01:00
catch ( Exception e )
2024-10-30 11:43:23 +01:00
{
2024-11-22 10:59:57 +01:00
HandleException ( e , tenant ) ;
2024-10-30 11:43:23 +01:00
}
2024-10-29 15:23:30 +01:00
2024-10-31 15:38:24 +01:00
PrintSeperator ( ) ;
if ( res . Success )
return ;
2024-10-30 11:43:23 +01:00
foreach ( var result in req . ResultDCs )
{
FileController . SaveAsXmlFileInResultFolder ( result , tenant , user ) ;
}
2024-10-31 15:38:24 +01:00
PrintSeperator ( ) ;
2024-10-29 15:23:30 +01:00
}
static int ExecuteDakota ( string arg )
{
var fileinfo = Config . DakotaExe ;
var process = Process . Start ( Config . DakotaExe . FullName , arg ) ;
var success = process . WaitForExit ( Config . ProcessWaitForExitMs ) ;
if ( success )
{
return process . ExitCode ;
}
else
{
2025-01-13 15:36:33 +01:00
PrintLine ( $"{fileinfo.Name} {arg} wird ausgeführt" ) ;
2024-10-29 15:23:30 +01:00
throw new Exception ( $"dakota30.exe - Timeout exceeded ({Config.ProcessWaitForExitMs} ms). " ) ;
}
}
}
2024-07-02 11:44:48 +02:00
}