Dalsi zmeny

This commit is contained in:
2026-03-03 16:18:27 +01:00
parent 03ff9ebc84
commit a62b608cfd
97 changed files with 4635 additions and 240 deletions

View File

@ -0,0 +1 @@
// arrDefs.Add('ep_HDCDZApi_ZpracujPrijataData');

View File

@ -76,6 +76,22 @@ type
end;
[MVCPath('/emp/vytezeni')]
TEMPVytezeniDoklController = class(TBaseController)
private
FSelfSvc: TEMPVytezeniDoklService;
public
constructor Create; override;
destructor Destroy; override;
[MVCPath('/fprij/post/($id)')]
[MVCHTTPMethod([httpGET])]
[MVCSwagSummary('EMP - vyt<79><74>en<65> dokument<6E> dokladu FaktPrij', 'Po<50>le dokument dokladu Faktury p<>ijat<61> na AiDOCU API', 'EMPVytezDokFPrijPostByID')]
[MVCSwagParam(plPath, 'id', 'ID dokladu Faktury p<>ijat<61>', ptString, true)]
[MVCProduces('application/json')]
procedure FPrij_PostByID (id: string);
end;
implementation
uses
@ -195,22 +211,22 @@ uses
procedure TEMPDokumentAtestController.GetMeta;
begin
try
Render(ObjectDict().Add('data', GetDokumentService.GetMeta));
except
begin
try
Render(ObjectDict().Add('data', GetDokumentService.GetMeta));
except
{$IFDEF NORENDER400}
RenderStatusMessage (200);
RenderStatusMessage (200);
{$ELSE}
on E: EServiceException do
begin
raise EMVCException.Create(E.Message, '', 0, 404);
end
else
raise;
on E: EServiceException do
begin
raise EMVCException.Create(E.Message, '', 0, 404);
end
else
raise;
{$ENDIF}
end;
end;
end;
@ -243,4 +259,48 @@ uses
end;
{ TEMPVytezeniDoklService }
constructor TEMPVytezeniDoklController.Create;
begin
inherited;
end;
destructor TEMPVytezeniDoklController.Destroy;
begin
inherited;
end;
procedure TEMPVytezeniDoklController.FPrij_PostByID (id: string);
var iId: integer;
begin
id:= sanitizeSQLString (id);
if not(TryStrToInt(id, iId)) then
iId:= 0;
try
Render(ObjectDict().Add('data', GetEMPVytezeniDoklService.FPrij_PostByID (iId))); // viz uSvcCustom.pas
except
{$IFDEF NORENDER400}
RenderStatusMessage (200);
{$ELSE}
on E: EServiceException do
begin
raise EMVCException.Create(E.Message, '', 0, 404);
end
else
raise;
{$ENDIF}
end;
end;
end.

View File

@ -42,6 +42,11 @@ type
function GetByParams (params: TDictionary<string, string>): TObjectList<TEMPNadoba>;
end;
TEMPVytezeniDoklService = class(TServiceBase)
public
function FPrij_PostByID (const AID: integer): TJSONObject; // vrati se identifikace od providera
end;
implementation
@ -50,6 +55,9 @@ uses
FireDAC.Stan.Option,
FireDAC.Comp.Client,
FireDAC.Stan.Param,
System.JSON.Builders,
System.JSON.Writers,
System.JSON.Types,
MVCFramework.FireDAC.Utils,
MVCFramework.DataSet.Utils,
MVCFramework.Serializer.Commons,
@ -195,7 +203,7 @@ uses
try
if not(lQry.EOF) then
begin
result:= FDM.sqlQry1.AsObject<TEMPNadoba>
result:= FDM.sqlQry1.AsObject<TEMPNadoba>;
end
else
raise EServiceException.Create('N<>doba s <20><>slem ' + ACislo + ' nebyla nalezena.');
@ -239,4 +247,31 @@ uses
end;
{ TEMPVytezeniDoklService }
function TEMPVytezeniDoklService.FPrij_PostByID (const AID: integer): TJSONObject; // vrati se identifikace od providera
var lSQL, statusOut: string;
resVal: TJSONObject;
sB: TStringBuilder;
sW: TStringWriter;
w: TJsonTextWriter;
b: TJSONObjectBuilder;
p: TJSONCollectionBuilder.TPairs;
begin
result:= TJSONObject.Create;
statusOut:= 'Not OK';
sB:= TStringBuilder.Create;
sW:= TStringWriter.Create (sB);
w:= TJsonTextWriter (sW);
w.Formatting:= TJsonFormatting.Indented;
b:= TJsonObjectBuilder.Create (w);
p:= b.BeginObject.Add('status', statusOut);
p.EndObject;
result.FromJSON (sB.ToString);
end;
end.

View File

@ -1,3 +1,4 @@
FEngine.AddController (TEMPNadobaController);
FEngine.AddController (TEMPDokumentAtestController);
FEngine.AddController (TEMPDokumentAtestController);
FEngine.AddController (TEMPVytezeniDoklController);

View File

@ -0,0 +1 @@
// tblAPIDigiSoubory = '[dbo].[Tabx_HDC_API_DigitalizaceSoubory]';

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<config_aidocu vytezovaniDokumentuSek="10" url="https://aidocu-test.amitia-ai.com/api/v1" auth="24A0F17F9ACD9E20821EEA7870BAB2754C19972CB12CF6DD62508800644C9F64121C218D8DBE627C6F01E467B00C80CC428CB28575475F9048A61C7C64DA08907F1F5316C81E429E184DCCAED7801D7D7A830181216F911DF4C33A899DA0E153C09246E17598055BBE227684724EB851FD5AE2AFDF889A09E20DCBDA8DDC91FC174BA3ABE36A8DF02C1B61CEABE9BFB1B6A97D384E506BB5ED3C5A45F2ED786F33F636D3F8900F7D2ED64BE6323E2AF7224049EA2061D72C837F7013226E7ACB8969E98372A1F0F5B7BF0C727088DF8A72D64A616B83B4A026F567CBE3B1209C0A1561AA327C8630DCC745D45B48F34A5646938093526F9C5AD3539753BE4F5AA40162A5D8091DACA425320ACC8CCB77E327B3786BC860AAF505CA0FB76755BB49D6179666ACA28DFBDF4E910B3A1AA38DDFC7EEDDE3EEBE23692ECA21D97CE85A075AD2F9E6A1432C8592088608E0C11A7A66117A95AE">
<config auth="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJlbXBvbGFyIiwicmVsZWFzZV9pZCI6IjY4NGE4NDU4ZGUzNTcxNGFiNDdiZTUwMCIsImxpY2VuY2VfaWQiOiI2ODUxMmRmMzI2NjgwM2FjOGFhOWUwMDQiLCJzZWNyZXRfdG9rZW4iOiJjN0pUZ242V05TNlBiZ0hmWlo1Zk1uRjNXdjlrSk1IZm9zdnVwTkZrbERxaGJjdFBXYTllaTliVm5SMjVtd1VwIiwiZXhwIjoxNzU5MjY5NjAwfQ.rYWVHenSwmoM_5bpSsannmxFln5oZBAd-2jb_CP-WQ8"/>
</config_aidocu>

View File

@ -0,0 +1,337 @@
constructor THeoEMPVytezovaniDokThread.Create (AOnTerminate: TNotifyEvent; AService: TService);
begin
inherited Create (false); // Create thread in NOT suspended mode
FMainService:= AService;
FLock:= TCriticalSection.Create;
FRunning:= false;
FTermEvent:= TEvent.Create (nil, False, False, '');
// OnTerminate:= AOnTerminate;
// FreeOnTerminate:= true;
FreeOnTerminate:= false; // Ensure manual freeing of thread resources
end;
destructor THeoEMPVytezovaniDokThread.Destroy;
begin
{$IFDEF DEBUG}
Write('Ukoncuji thread EMP vytezovani dokumentu...');
{$ENDIF}
if (FTimer<>0) then
CloseHandle (FTimer);
FTermEvent.Free;
FRunning:= false;
FMainService:= nil;
Terminate;
FLock.Free;
inherited;
{$IFDEF DEBUG}
WriteLn('OK');
{$ENDIF}
end;
procedure THeoEMPVytezovaniDokThread.TerminatedSet;
begin
FTermEvent.SetEvent;
end;
procedure THeoEMPVytezovaniDokThread.ThreadTerminate;
begin
Terminate;
WaitFor;
end;
procedure THeoEMPVytezovaniDokThread.Execute;
const _Second = 10_000_000;
var lSQL, errMsg, url, authHash, outData, fName, loopCasTyp: string;
lLoop, idDZ, cnt, idx: Integer;
lLoopMax, koefProCas: integer;
logRunCnt: integer;
Msg: TMsg;
firstRun, inProg, inDL: boolean;
lQry, lQry2: TFDQuery;
sqlConnX, sqlConnX2: TFDConnection;
sqlTrans: IFDPhysTransaction;
f, lOpenSSLLib: string;
lBusy: LongInt;
liDueTime: LARGE_INTEGER;
mamSSLLibs: boolean;
sslLibPath, dataSouboru: string;
http1: System.Net.HTTPClient.THTTPClient;
iResp: System.Net.HTTPClient.IHTTPResponse;
aResp: TMemoryStream;
http2: TIdHttp;
sslHndlr: TIdSSLIOHandlerSocketOpenSSL;
respHttp2: TStream;
i: integer;
sTemp, outData2: string;
cfgFile: string;
specCfgXML: XML.XmlIntf.IXMLDocument;
n1: XML.XmlIntf.IXMLNode;
attribs: IXMLNodeList;
attrIdx: integer;
function StringToHex (const inStr: string): string;
var i: integer;
begin
result:= '';
for i:=1 to Length(inStr) do
result:= result + IntToHex(Ord(inStr[i]), 2); // 2 means two hex digits per character
end;
function MemStreamToHex (aStream: TMemoryStream): string;
var i: integer;
b: byte;
begin
result:= '';
for i:=0 to aStream.Size-1 do
begin
b:= PByte(TMemoryStream(aStream).Memory)[i];
result:= result + IntToHex(b,2);
end;
end;
begin
lLoop:= 0;
idDZ:= 0;
logRunCnt:= 1;
url:= '';
authHash:= '';
lLoopMax:= 20; // v sekundach !!!!
try
try
CoInitialize(nil); // kvuli pouziti TXMLDocument
cfgFile:= ExtractFilePath(ParamStr(0)) + 'empolar.xml';
if (FileExists(cfgFile)) then
begin
specCfgXML:= Xml.XMLDoc.TXMLDocument.Create(nil);
specCfgXML.LoadFromFile (cfgFile);
specCfgXML.Active:= true;
if not(specCfgXML.IsEmptyDoc) then
begin
if (specCfgXML.DocumentElement<>nil) then
begin
n1:= specCfgXML.DocumentElement;
if (n1.NodeName='config_aidocu') then
begin
attribs:= n1.AttributeNodes;
attrIdx:= attribs.IndexOf('vytezovaniDokumentuSek');
if (attrIdx>-1) then
if (attribs.Get(attrIdx).NodeValue<>null) then
lLoopMax:= attribs.Get(attrIdx).NodeValue;
attrIdx:= attribs.IndexOf('url');
if (attrIdx>-1) then
if (attribs.Get(attrIdx).NodeValue<>null) then
url:= attribs.Get(attrIdx).NodeValue;
attrIdx:= attribs.IndexOf('auth');
if (attrIdx>-1) then
if (attribs.Get(attrIdx).NodeValue<>null) then
authHash:= attribs.Get(attrIdx).NodeValue;
{$IFDEF DEBUG}
if (Length(authHash)<350) then
begin
authHash:= (FMainService as THDCDZApiService).ReturnEncrypted (authHash);
WriteLn('API HASH: ' + authHash);
end;
{$ENDIF}
if (authHash<>'') and (FMainService<>nil) then
authHash:= (FMainService as THDCDZApiService).ReturnDecrypted (authHash);
end; // n1 = config
end; // specCfgXML.DocumentElement<>nil
end; // not specCfgXML.IsEmptyDoc
end; // FileExists(cfgFile)
except
end; // try
finally
begin
if (specCfgXML<>nil) then
specCfgXML:= nil;
CoUninitialize;
end;
end;
datMod.LogInfo (Quick.Logger.etInfo, 'Interval vytezovani dokumentu: ' + lLoopMax.ToString + ' sek');
firstRun:= true;
inProg:= false;
sslLibPath:= '';
f:= ExtractFilePath (ParamStr(0));
mamSSLLibs:= false;
for lOpenSSLLib in OPENSSL_LIBS do
begin
if (FileExists(TPath.Combine(f, lOpenSSLLib))) then
begin
mamSSLLibs:= true;
sslLibPath:= ExcludeTrailingPathDelimiter (f);
end;
end;
FRunning:= true;
if (1=1) then // pro rychle vypnuti
begin
FTimer:= CreateWaitableTimer (nil, true, 'EMPVytezDokumWaitableTimer');
liDueTime.QuadPart:= -1*_Second;
sqlConnX:= TFDConnection.Create (nil);
sqlConnX2:= TFDConnection.Create (nil);
lQry:= TFDQuery.Create(nil);
lQry2:= TFDQuery.Create(nil);
try
try
sqlConnX.Params.SetStrings (datMod.sqlConnParams);
sqlConnX2.Params.SetStrings (datMod.sqlConnParams);
// sqlConnX.TxOptions.AutoCommit:= false;
sqlConnX.Open;
sqlConnX2.Open;
lQry.Connection:= sqlConnX;
lQry2.Connection:= sqlConnX2;
while not(Terminated) or not(FRunning) do
begin
if (HDCDZApiService<>nil) then
if (HDCDZApiService.Terminated) then
begin
Terminate;
FRunning:= false;
end;
PeekMessage (&Msg, 0, 0, 0, PM_NOREMOVE); { Create message queue }
if (lLoop=lLoopMax) or (firstRun) then // pri startu a pak podle lLoopMax sek (prednastaveno 10 sek)
begin
idDZ:= 0;
firstRun:= false;
if (logRunCnt<4) then
datMod.LogInfo (Quick.Logger.etInfo, 'Spoustim vytezovani ' + logRunCnt.toString + '...');
if (logRunCnt=4) then
datMod.LogInfo (Quick.Logger.etInfo, 'Spoustim vytezovani - bezi ale dal neloguju');
try
if not(inProg) then // nebezi uz ?
begin
if (1=1) then // pro rychle vypnuti
begin
if (sqlConnX.Connected) then
begin
lSQL:= '/* hdcDZApiSvc-emp */ SELECT ID FROM ' + tblDZ
+ ' WHERE BlokovaniEditoru IS NULL AND DruhPohybuZbo=18 AND CisloOrg IS NULL ORDER BY ID';
try
lQry.Open(lSQL);
if (lQry.RecordCount>0) then
begin
lQry.First;
inProg:= true;
while not(lQry.EOF) do
begin
idDZ:= lQry.FieldByName('ID').asInteger;
if (idDZ>0) then
begin
dataSouboru:= '';
lSQL:= 'SELECT 1 FROM ' + tblDokumVaz + ' v JOIN ' + tblDokum + ' d ON (d.ID=v.IDDok) WHERE v.IDTab=' + idDZ.ToString
+ ' AND v.IdentVazby=9 AND UPPER(d.JmenoACesta) LIKE N''%PDF'' AND d.VelikostSouboru>0';
lQry2.Open (lSQL);
if (lQry2.RecordCount=1) then // mam dokument PDF
begin
lQry2.Close;
lSQL:= lSQL.Replace(' 1 ', ' TOP(1) /*CONVERT(varchar(max), Dokument, 2)*/ BASE64_ENCODE(Dokument) AS DataSouboru ');
lQry2.Open (lSQL);
if (lQry2.Recordcount=1) then
begin
dataSouboru:= lQry2.FieldByName('DataSouboru').AsString;
lQry2.Close;
end;
end; // mam dokument PDF
if (dataSouboru<>'') then
begin
end; // dataSouboru<>''
end; // idDZ>0
lQry.Next;
end;
end;
finally
lQry.Close;
FreeAndNil (lQry);
// lQry.Free;
// lQry:= nil;
end;
inProg:= false;
sqlConnX.Close;
end; // sqlConnX Connected
end; // 1=1 -- pro rychle vypnuti
end; // not(inProg)
except on E:Exception do
begin
inProg:= false;
if (lQry<>nil) then
begin
lQry.Close;
FreeAndNil (lQry);
end;
if (sqlConnX<>nil) then
sqlConnX.Close;
errMsg:= E.Message; // datMod.sqlQry11.FieldByName('ErrMsg').AsString;
if (mamTabPrijataData) then
datMod.LogInfo (Quick.Logger.etError, 'Chyba zpracovani API souboru FaktPrij ID ' + idDZ.ToString + ' : ' + errMsg);
end;
end; // try
lLoop:= 0;
if (logRunCnt<5) then
Inc (logRunCnt);
end;
Inc (lLoop);
// sleep na vterinu
if (FTimer<>0) then
SetWaitableTimer (FTimer, TLargeInteger(liDueTime), 0, nil, nil, false);
repeat
lBusy:= MsgWaitForMultipleObjects (1, FTimer, false, INFINITE, QS_ALLINPUT);
until lBusy = WAIT_OBJECT_0;
end;
except
end;
finally
sqlConnX.Close;
FreeAndNil (sqlConnX);
end;
end; // 1=1 -- pro rychle vypnuti
if (sqlConnX2<>nil) then
begin
if (sqlConnX2.Connected) then
sqlConnX2.Close;
FreeAndNil (sqlConnX2);
end;
end;

View File

@ -0,0 +1 @@
empVytezovaniDokThr: THeoEMPVytezovaniDokThread;

View File

@ -0,0 +1,3 @@
if (empVytezovaniDokThr<>nil) then
if (empVytezovaniDokThr.Suspended) then
empVytezovaniDokThr.Resume;

View File

@ -0,0 +1,7 @@
if (empVytezovaniDokThr<>nil) then
if not(empVytezovaniDokThr.Started) then
begin
empVytezovaniDokThr.Start;
datMod.LogInfo (Quick.Logger.etInfo, 'Start sluzby EMP vytezovani dokladu - pocet FaktPrij: ' + datMod.SQLGetString('SELECT COUNT(ID) FROM '
+ tblDZ + ' WHERE BlokovaniEditoru IS NULL AND DruhPohybuZbo=18 AND CislOrg IS NULL'));
end;

View File

@ -0,0 +1,3 @@
if (empVytezovaniDokThr<>nil) then
if not(empVytezovaniDokThr.Suspended) then
empVytezovaniDokThr.Suspend;

View File

@ -0,0 +1,22 @@
datMod.LogInfo (Quick.Logger.etInfo, 'Start sluzby EMP vytezovani dokumentu - inverval 10 sekund...');
{$IFDEF DEBUG}
WriteLn ('Start sluzby EMP vytezovani dokumentu - inverval 10 sekund...');
{$ENDIF}
empVytezovaniDokThr:= THeoEMPVytezovaniDokThread.Create (ThreadTerminated, self);
if (empVytezovaniDokThr<>nil) then
begin
if (empVytezovaniDokThr.Started) then
begin
datMod.LogInfo (Quick.Logger.etInfo, ' OK');
{$IFDEF DEBUG}
WriteLn (' OK');
{$ENDIF}
end;
end
else
begin
datMod.LogInfo (Quick.Logger.etInfo, ' thread empVytezovaniDokThr neni vytvoren');
{$IFDEF DEBUG}
WriteLn (' thread empVytezovaniDokThr neni vytvoren');
{$ENDIF}
end;

View File

@ -0,0 +1,18 @@
if Assigned(empVytezovaniDokThr) then
begin
{$IFDEF DEBUG}
WriteLn ('Ukoncuji vlakno EMP vytezovani dokumentu...');
{$ENDIF}
datMod.LogInfo (Quick.Logger.etInfo, 'Ukoncuji vlakno EMP vytezovani dokumentu...');
try
empVytezovaniDokThr.ThreadTerminate;
FreeAndNil(empVytezovaniDokThr);
except on E:Exception do
// add event in eventlog with reason why the service couldn't stop
LogMessage('Cannot stop thread EMPVytezaniDok: ' + E.Message, EVENTLOG_ERROR_TYPE, 0, 1);
end;
datMod.LogInfo (Quick.Logger.etInfo, ' OK');
{$IFDEF DEBUG}
WriteLn (' OK');
{$ENDIF}
end;

View File

@ -0,0 +1,3 @@
intervalSecVytezovani

View File

@ -0,0 +1,15 @@
THeoEMPVytezovaniDokThread = class(TThread)
private
FMainService: TService;
FLock: TCriticalSection;
FTermEvent: TEvent;
FRunning: boolean;
FTimer: THandle;
protected
procedure Execute; override;
procedure TerminatedSet; override; // XE2+ only *
public
constructor Create (AOnTerminate: TNotifyEvent; AService: TService);
destructor Destroy; override;
procedure ThreadTerminate;
end;

View File

@ -0,0 +1 @@
System.JSON.Builders, System.JSON.Writers, System.JSON.Types,

View File

@ -0,0 +1 @@
System.Net.HttpClient, System.Threading,

View File

@ -0,0 +1 @@
intervalSecVytezovani: integer;