1538 lines
44 KiB
Plaintext
1538 lines
44 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ ProcessPrint }
|
|
{ }
|
|
{ Copyright (C) 2025 kku }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit ProcessPrint;
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows, System.SysUtils, System.Classes, IdHTTP, Tocsg.Obj, System.Generics.Collections, System.JSON.Types;
|
|
|
|
type
|
|
TxPrtData = (xpdEmp, xpdPrts, xpdBill, xpdMkcd, xpdLump);
|
|
TxPrtDatas = set of TxPrtData;
|
|
|
|
// PxBillEnt = ^TxBillEnt;
|
|
// TxBillEnt = packed record
|
|
// accessUser,
|
|
// billCodeName: UTF8String;
|
|
// end;
|
|
TxBillData = class(TTgObject)
|
|
private
|
|
DcData_: TDictionary<UTF8String,UTF8String>;
|
|
// DataList_: TList<PxBillEnt>;
|
|
// StrList_: TStringList;
|
|
// procedure OnEntNoti(Sender: TObject; const Item: PxBillEnt; Action: TCollectionNotification);
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
function LoadFromFile(const sPath: String): Boolean;
|
|
procedure UpdateData(const sJsonData: String);
|
|
procedure SaveToFile(const sPath: String);
|
|
end;
|
|
|
|
TxEmpData = class(TTgObject)
|
|
private
|
|
DcData_: TDictionary<UTF8String,UTF8String>;
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
function LoadFromFile(const sPath: String): Boolean;
|
|
procedure UpdateData(const sJsonData: String);
|
|
procedure SaveToFile(const sPath: String);
|
|
end;
|
|
|
|
TxPrtInfoData = class(TTgObject)
|
|
private
|
|
DcData_: TDictionary<UTF8String,UTF8String>;
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
function LoadFromFile(const sPath: String): Boolean;
|
|
procedure UpdateData(const sJsonData: String);
|
|
procedure SaveToFile(const sPath: String);
|
|
end;
|
|
|
|
// mk-codes, lumpsum-fixed-codes 처리
|
|
TxStrData = class(TTgObject)
|
|
private
|
|
sName_: String;
|
|
DataList_: TStringList;
|
|
public
|
|
Constructor Create(sName: String);
|
|
Destructor Destroy; override;
|
|
|
|
function LoadFromFile(const sPath: String): Boolean;
|
|
procedure UpdateData(const sJsonData: String);
|
|
procedure SaveToFile(const sPath: String);
|
|
end;
|
|
|
|
procedure ProcessCheck_xPrintData(aHTTP: TIdHTTP);
|
|
function ProcessRcv_xPrintData(aHTTP: TIdHTTP; aPrtDatas: TxPrtDatas; bForceDl: Boolean = false): Boolean;
|
|
|
|
procedure CheckAndUpdate_xPrint;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Tocsg.Safe, ManagerService, Tocsg.Exception, Tocsg.Process,
|
|
System.Zip, Tocsg.Shell, GlobalDefine, ProcessUninstall, Tocsg.Files,
|
|
Tocsg.Trace, Tocsg.Path, Tocsg.Strings, superobject, ManagerModel, Condition,
|
|
System.IniFiles, Tocsg.Json, System.JSON, System.JSON.Readers, Tocsg.DateTime,
|
|
Tocsg.DRM.Encrypt;
|
|
|
|
const
|
|
PASS_xDRM_HEAD: AnsiString = '#df12mf8(zfq@';
|
|
PASS_xDRM_DATA: AnsiString = 'Z!8r]Xc3$g>+Tp5L%u';
|
|
SIG_xDRM: AnsiString = 'X-PRINT';
|
|
|
|
function Is_xEncrypt(const plainPath: string): Boolean;
|
|
var
|
|
dec: TTgDrmDec;
|
|
begin
|
|
try
|
|
Result := CheckSign(plainPath, SIG_xDRM);
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
Result := false;
|
|
ETgException.TraceException(E, 'Fail .. Is_xEncrypt()');
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function Do_xDecrypt(const encPath, decPath: string): Boolean;
|
|
var
|
|
dec: TTgDrmDec;
|
|
begin
|
|
Result := false;
|
|
try
|
|
if not FileExists(encPath) then
|
|
exit;
|
|
|
|
if not DirectoryExists(ExtractFilePath(decPath)) then
|
|
exit;
|
|
|
|
Guard(dec, TTgDrmDec.Create(encPath));
|
|
if not dec.CheckSig(SIG_xDRM) then
|
|
exit;
|
|
|
|
if not dec.ExtrHead(PASS_xDRM_HEAD) then
|
|
exit;
|
|
|
|
Result := dec.DecryptToFile(PASS_xDRM_DATA, decPath);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. Do_xDecrypt()');
|
|
// WriteLn(encPath + '오류 발생: ', E.Message);
|
|
end;
|
|
end;
|
|
|
|
function Do_xEncrypt(const plainPath, encPath: string): Boolean;
|
|
var
|
|
enc: TTgDrmEnc;
|
|
begin
|
|
Result := false;
|
|
if Is_xEncrypt(plainPath) then
|
|
exit;
|
|
|
|
try
|
|
Guard(enc, TTgDrmEnc.Create(encPath));
|
|
enc.SetHaed(PASS_xDRM_HEAD, SIG_xDRM, '', '', '', '', 0);
|
|
Result := enc.EncryptFromFile(PASS_xDRM_DATA, plainPath);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. Do_xEncrypt()');
|
|
end;
|
|
end;
|
|
|
|
{ TxBillData }
|
|
|
|
Constructor TxBillData.Create;
|
|
begin
|
|
Inherited Create;
|
|
DcData_ := TDictionary<UTF8String,UTF8String>.Create;
|
|
// DcData_.OnValueNotify := OnEntNoti;
|
|
// DataList_ := TList<PxBillEnt>.Create;
|
|
// DataList_.OnNotify := OnEntNoti;
|
|
// StrList_ := TStringList.Create;
|
|
end;
|
|
|
|
Destructor TxBillData.Destroy;
|
|
begin
|
|
FreeAndNil(DcData_);
|
|
// FreeAndNil(StrList_);
|
|
// FreeAndNil(DataList_);
|
|
Inherited;
|
|
end;
|
|
|
|
//procedure TxBillData.OnEntNoti(Sender: TObject; const Item: PxBillEnt; Action: TCollectionNotification);
|
|
//begin
|
|
// if Action = cnRemoved then
|
|
// Dispose(Item);
|
|
//end;
|
|
|
|
function TxBillData.LoadFromFile(const sPath: String): Boolean;
|
|
var
|
|
// O: ISuperObject;
|
|
i: Integer;
|
|
sData, sDecPath: String;
|
|
// pEnt: PxBillEnt;
|
|
// Ent: TxBillEnt;
|
|
|
|
// JSONObj: TJSONObject;
|
|
// JSONArray: TJSONArray;
|
|
// item: TJSONValue;
|
|
|
|
ms: TMemoryStream;
|
|
sr: TStreamReader;
|
|
jr: TJsonTextReader;
|
|
bArray, bObject: Boolean;
|
|
sProp, s1, s2: String;
|
|
begin
|
|
Result := false;
|
|
try
|
|
sDecPath := '';
|
|
DcData_.Clear;
|
|
// StrList_.Clear;
|
|
// DataList_.Clear;
|
|
|
|
// 속도 및 메모리 최적화를 위해 아래처럼 처리 25_1023 16:10:36 kku
|
|
Guard(ms, TMemoryStream.Create);
|
|
|
|
if Is_xEncrypt(sPath) then
|
|
begin
|
|
sDecPath := GetRunExePathDir + 'Task\';
|
|
if ForceDirectories(sDecPath) then
|
|
begin
|
|
sDecPath := sDecPath + IntToStr(GetTickCount) + '_Bil.dat';
|
|
if not Do_xDecrypt(sPath, sDecPath) then
|
|
begin
|
|
_Trace('Fail .. Do_xDecrypt() .. Path=%s', [sDecPath]);
|
|
exit;
|
|
end;
|
|
ms.LoadFromFile(sDecPath);
|
|
end else begin
|
|
_Trace('Fail .. CreateDir() .. Path=%s', [sDecPath]);
|
|
exit;
|
|
end;
|
|
end else
|
|
ms.LoadFromFile(sPath);
|
|
|
|
try
|
|
Guard(sr, TStreamReader.Create(ms, TEncoding.UTF8, true, 1 shl 16));
|
|
Guard(jr, TJsonTextReader.Create(sr));
|
|
|
|
bArray := false;
|
|
bObject := false;
|
|
// pEnt := nil;
|
|
|
|
while jr.Read do
|
|
begin
|
|
case jr.TokenType of
|
|
TJsonToken.StartArray: bArray := true;
|
|
TJsonToken.EndArray: bArray := false;
|
|
|
|
TJsonToken.StartObject:
|
|
begin
|
|
// 객체 시작: 필요한 필드 초기화
|
|
bObject := true;
|
|
|
|
// New(pEnt);
|
|
// ZeroMemory(pEnt, SizeOf(TxBillEnt));
|
|
// ZeroMemory(@Ent, SizeOf(TxBillEnt));
|
|
end;
|
|
|
|
TJsonToken.PropertyName:
|
|
sProp := jr.Value.AsString; // Delphi 11+에서 사용 가능(버전에 따라 ToString 사용)
|
|
|
|
TJsonToken.String:
|
|
if bObject then
|
|
begin
|
|
// if pEnt <> nil then
|
|
begin
|
|
if SameText(sProp, 'accessUser') then
|
|
s1 := jr.Value.AsString// ToString
|
|
else if SameText(sProp, 'billCodeName') then
|
|
s2 := jr.Value.AsString; //ToString;
|
|
end;
|
|
end;
|
|
|
|
TJsonToken.Integer:
|
|
if bObject then
|
|
begin
|
|
// if SameText(sProp, 'age') then
|
|
// nVal := StrToIntDef(jr.Value.ToString, -1);
|
|
end;
|
|
|
|
TJsonToken.EndObject:
|
|
begin
|
|
// ★ 여기서 한 레코드 처리(저장/집계/필터링 등) 후 버린다
|
|
// 예: DB Insert, 파일 Append, 통계 누적 등
|
|
// DoProcess(sVal, nVal);
|
|
bObject := false;
|
|
|
|
if s2 <> '' then
|
|
DcData_.Add(UpperCase(s2), s1 + '|' + s2);
|
|
|
|
// if pEnt <> nil then
|
|
// begin
|
|
// try
|
|
// if pEnt.accessUser <> '' then
|
|
//// DataList_.Add(pEnt)
|
|
// DcData_.Add(UpperCase(pEnt.billCodeName), pEnt)
|
|
// else
|
|
// Dispose(pEnt);
|
|
// except
|
|
// _Trace('Fail .. TxBillData.LoadFromFile() .. 중복 데이터? billCodeName=%s', [pEnt.billCodeName], 9);
|
|
// Dispose(pEnt);
|
|
// end;
|
|
// pEnt := nil;
|
|
// end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
Result := true;
|
|
finally
|
|
if sDecPath <> '' then
|
|
DeleteFile(sDecPath);
|
|
end;
|
|
|
|
// sData := LoadStrFromFile(sPath, TEncoding.UTF8);
|
|
// JSONArray := TJSONObject.ParseJSONValue(sData) as TJSONArray;
|
|
// if JSONArray = nil then
|
|
// exit;
|
|
//
|
|
// try
|
|
// for i := 0 to JSONArray.Count - 1 do
|
|
// begin
|
|
// item := JSONArray.Items[i];
|
|
//
|
|
// New(pEnt);
|
|
// pEnt.accessUser := item.GetValue<String>('accessUser');
|
|
// pEnt.billCodeName := item.GetValue<String>('billCodeName');
|
|
// try
|
|
// if pEnt.accessUser <> '' then
|
|
// DcData_.Add(pEnt.billCodeName.ToUpper, pEnt)
|
|
// else
|
|
// Dispose(pEnt);
|
|
// except
|
|
// _Trace('Fail .. TxBillData.LoadFromFile() .. 중복 데이터? billCodeName=%s', [pEnt.billCodeName], 9);
|
|
// Dispose(pEnt);
|
|
// end;
|
|
// end;
|
|
// finally
|
|
// JSONArray.Free;
|
|
// end;
|
|
|
|
// if not LoadJsonObjFromFile(O, sPath) then
|
|
// exit;
|
|
//
|
|
// if (O.DataType <> stArray) or (O.AsArray.Length = 0) then
|
|
// exit;
|
|
//
|
|
// for i := 0 to O.AsArray.Length - 1 do
|
|
// begin
|
|
// New(pEnt);
|
|
// pEnt.accessUser := O.AsArray.O[i].S['accessUser'];
|
|
// pEnt.billCodeName := O.AsArray.O[i].S['billCodeName'];
|
|
// try
|
|
// if pEnt.accessUser <> '' then
|
|
// DcData_.Add(pEnt.billCodeName.ToUpper, pEnt)
|
|
// else
|
|
// Dispose(pEnt);
|
|
// except
|
|
// _Trace('Fail .. TxBillData.LoadFromFile() .. 중복 데이터? billCodeName=%s', [pEnt.billCodeName], 9);
|
|
// Dispose(pEnt);
|
|
// end;
|
|
// end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. LoadFromFile()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxBillData.UpdateData(const sJsonData: String);
|
|
var
|
|
O: ISuperObject;
|
|
i: Integer;
|
|
sKey: String;
|
|
// pEnt: PxBillEnt;
|
|
begin
|
|
try
|
|
O := SO(sJsonData);
|
|
if O = nil then
|
|
exit;
|
|
|
|
if (O.O['created'] <> nil) and (O.O['created'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['created'].Length - 1 do
|
|
begin
|
|
sKey := O.A['created'].O[i].S['billCodeName'].ToUpper;
|
|
if not DcData_.ContainsKey(sKey) then
|
|
begin
|
|
// New(pEnt);
|
|
// pEnt.billCodeName := O.A['created'].O[i].S['billCodeName'];
|
|
// pEnt.accessUser := O.A['created'].O[i].S['accessUser'];
|
|
// DcData_.Add(sKey, pEnt);
|
|
|
|
DcData_.Add(sKey, O.A['created'].O[i].S['accessUser'] + '|' + O.A['created'].O[i].S['billCodeName']);
|
|
_Trace('billcodes.UpdateData() .. created, billCodeName=%s, accessUser=%s', [O.A['created'].O[i].S['billCodeName'], O.A['created'].O[i].S['accessUser']], 5);
|
|
end else begin
|
|
// pEnt := DcData_[sKey];
|
|
// pEnt.accessUser := O.A['created'].O[i].S['accessUser'];
|
|
|
|
DcData_[sKey] := O.A['created'].O[i].S['accessUser'] + '|' + O.A['created'].O[i].S['billCodeName'];
|
|
_Trace('billcodes.UpdateData() .. created(mod), billCodeName=%s, accessUser=%s', [O.A['created'].O[i].S['billCodeName'], O.A['created'].O[i].S['accessUser']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['updated'] <> nil) and (O.O['updated'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['updated'].Length - 1 do
|
|
begin
|
|
sKey := O.A['updated'].O[i].S['billCodeName'].ToUpper;
|
|
if not DcData_.ContainsKey(sKey) then
|
|
begin
|
|
// New(pEnt);
|
|
// pEnt.billCodeName := O.A['updated'].O[i].S['billCodeName'];
|
|
// pEnt.accessUser := O.A['updated'].O[i].S['accessUser'];
|
|
// DcData_.Add(sKey, pEnt);
|
|
|
|
DcData_.Add(sKey, O.A['updated'].O[i].S['accessUser'] + '|' + O.A['updated'].O[i].S['billCodeName']);
|
|
_Trace('billcodes.UpdateData() .. updated(new), billCodeName=%s, accessUser=%s', [O.A['updated'].O[i].S['billCodeName'], O.A['updated'].O[i].S['accessUser']], 5);
|
|
end else begin
|
|
// pEnt := DcData_[sKey];
|
|
// pEnt.accessUser := O.A['updated'].O[i].S['accessUser'];
|
|
DcData_[sKey] := O.A['updated'].O[i].S['accessUser'] + '|' + O.A['updated'].O[i].S['billCodeName'];
|
|
_Trace('billcodes.UpdateData() .. updated, billCodeName=%s, accessUser=%s', [O.A['updated'].O[i].S['billCodeName'], O.A['updated'].O[i].S['accessUser']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['deleted'] <> nil) and (O.O['deleted'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['deleted'].Length - 1 do
|
|
begin
|
|
sKey := O.A['deleted'].O[i].S['billCodeName'].ToUpper;
|
|
if DcData_.ContainsKey(sKey) then
|
|
begin
|
|
DcData_.Remove(O.A['deleted'].O[i].S['billCodeName'].ToUpper);
|
|
_Trace('billcodes.UpdateData() .. deleted, billCodeName=%s, accessUser=%s', [O.A['deleted'].O[i].S['billCodeName'], O.A['deleted'].O[i].S['accessUser']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. UpdateData()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxBillData.SaveToFile(const sPath: String);
|
|
var
|
|
// OA, O: ISuperObject;
|
|
enum: TEnumerator<UTF8String>;
|
|
sData, sEnt, sU, sB: String;
|
|
n: Integer;
|
|
begin
|
|
try
|
|
sData := '';
|
|
// OA := TSuperObject.Create(stArray);
|
|
// Guard(enum, StrList_.GetEnumerator);
|
|
Guard(enum, DcData_.Values.GetEnumerator);
|
|
// Guard(enum, DataList_.GetEnumerator);
|
|
while enum.MoveNext do
|
|
begin
|
|
// SumString(sData, TTgJson.ValueToJsonAsString<TxBillEnt>(enum.Current^), ',');
|
|
|
|
// sEnt := JsonEscapeString(enum.Current);
|
|
sEnt := enum.Current;
|
|
|
|
n := Pos('|', sEnt);
|
|
if n > 0 then
|
|
begin
|
|
sU := Copy(sEnt, 1, n - 1);
|
|
Delete(sEnt, 1, n);
|
|
sB := sEnt;
|
|
SumString(sData, Format('{"accessUser":"%s","billCodeName":"%s"}', [sU, sB]), ',');
|
|
end;
|
|
|
|
// O := TTgJson.ValueToJsonObject<TxBillEnt>(enum.Current^);
|
|
// OA.AsArray.Add(O);
|
|
end;
|
|
SaveStrToFile(sPath, '[' + sData + ']', TEncoding.UTF8);
|
|
|
|
// SaveJsonObjToFile(OA, sPath);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. SaveToFile()');
|
|
end;
|
|
end;
|
|
|
|
{ TxEmpData }
|
|
|
|
Constructor TxEmpData.Create;
|
|
begin
|
|
Inherited Create;
|
|
DcData_ := TDictionary<UTF8String,UTF8String>.Create;
|
|
end;
|
|
Destructor TxEmpData.Destroy;
|
|
begin
|
|
FreeAndNil(DcData_);
|
|
Inherited;
|
|
end;
|
|
|
|
function TxEmpData.LoadFromFile(const sPath: String): Boolean;
|
|
var
|
|
O: ISuperObject;
|
|
i: Integer;
|
|
sKey: String;
|
|
begin
|
|
Result := false;
|
|
try
|
|
if Is_xEncrypt(sPath) then
|
|
begin
|
|
var sDecPath: String := GetRunExePathDir + 'Task\';
|
|
if ForceDirectories(sDecPath) then
|
|
begin
|
|
sDecPath := sDecPath + IntToStr(GetTickCount) + '_Emp.dat';
|
|
try
|
|
if not Do_xDecrypt(sPath, sDecPath) then
|
|
begin
|
|
_Trace('Fail .. Do_xDecrypt() .. Path=%s', [sDecPath]);
|
|
exit;
|
|
end;
|
|
|
|
if not LoadJsonObjFromFile(O, sDecPath) then
|
|
begin
|
|
_Trace('Fail .. TxEmpData.LoadJsonObjFromFile()');
|
|
exit;
|
|
end;
|
|
finally
|
|
if FileExists(sDecPath) then
|
|
DeleteFile(sDecPath);
|
|
end;
|
|
end else begin
|
|
_Trace('Fail .. CreateDir() .. Path=%s', [sDecPath]);
|
|
exit;
|
|
end;
|
|
end else
|
|
if not LoadJsonObjFromFile(O, sPath) then
|
|
begin
|
|
_Trace('Fail .. TxEmpData.LoadJsonObjFromFile()');
|
|
exit;
|
|
end;
|
|
|
|
if (O.DataType <> stArray) or (O.AsArray.Length = 0) then
|
|
begin
|
|
_Trace('Fail .. TxEmpData.InvalidData()');
|
|
exit;
|
|
end;
|
|
|
|
for i := 0 to O.AsArray.Length - 1 do
|
|
begin
|
|
sKey := O.AsArray.O[i].S['empId'].ToUpper;
|
|
try
|
|
if sKey <> '' then
|
|
DcData_.Add(sKey, O.AsArray.O[i].AsJSon);
|
|
except
|
|
_Trace('Fail .. TxEmpData.LoadFromFile() .. 중복 데이터? Key=%s', [sKey], 9);
|
|
end;
|
|
end;
|
|
|
|
Result := true;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. LoadFromFile()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxEmpData.UpdateData(const sJsonData: String);
|
|
var
|
|
O: ISuperObject;
|
|
i: Integer;
|
|
sKey: String;
|
|
begin
|
|
try
|
|
O := SO(sJsonData);
|
|
if O = nil then
|
|
exit;
|
|
|
|
if (O.O['created'] <> nil) and (O.O['created'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['created'].Length - 1 do
|
|
begin
|
|
sKey := O.A['created'].O[i].S['empId'].ToUpper;
|
|
if not DcData_.ContainsKey(sKey) then
|
|
begin
|
|
DcData_.Add(sKey, O.A['created'].O[i].AsJSon);
|
|
_Trace('emps.UpdateData() .. created, empId=%s', [O.A['created'].O[i].S['empId']], 5);
|
|
end else begin
|
|
DcData_[sKey] := O.A['created'].O[i].AsJSon;
|
|
_Trace('emps.UpdateData() .. created(mod), empId=%s', [O.A['created'].O[i].S['empId']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['updated'] <> nil) and (O.O['updated'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['updated'].Length - 1 do
|
|
begin
|
|
sKey := O.A['updated'].O[i].S['empId'].ToUpper;
|
|
if not DcData_.ContainsKey(sKey) then
|
|
begin
|
|
DcData_.Add(sKey, O.A['updated'].O[i].AsJSon);
|
|
_Trace('emps.UpdateData() .. updated(new), empId=%s', [O.A['updated'].O[i].S['empId']], 5);
|
|
end else begin
|
|
DcData_[sKey] := O.A['updated'].O[i].AsJSon;
|
|
_Trace('emps.UpdateData() .. updated, empId=%s', [O.A['updated'].O[i].S['empId']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['deleted'] <> nil) and (O.O['deleted'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['deleted'].Length - 1 do
|
|
begin
|
|
sKey := O.A['deleted'].O[i].S['empId'].ToUpper;
|
|
if DcData_.ContainsKey(sKey) then
|
|
begin
|
|
DcData_.Remove(O.A['deleted'].O[i].S['empId'].ToUpper);
|
|
_Trace('emps.UpdateData() .. deleted, empId=%s', [O.A['deleted'].O[i].S['empId']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. UpdateData()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxEmpData.SaveToFile(const sPath: String);
|
|
var
|
|
enum: TEnumerator<UTF8String>;
|
|
sData, sEnt: String;
|
|
begin
|
|
try
|
|
sData := '';
|
|
Guard(enum, DcData_.Values.GetEnumerator);
|
|
while enum.MoveNext do
|
|
begin
|
|
sEnt := enum.Current;
|
|
|
|
if sEnt <> '' then
|
|
SumString(sData, sEnt, ',');
|
|
end;
|
|
SaveStrToFile(sPath, '[' + sData + ']', TEncoding.UTF8);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. SaveToFile()');
|
|
end;
|
|
end;
|
|
|
|
{ TxPrtInfoData }
|
|
|
|
Constructor TxPrtInfoData.Create;
|
|
begin
|
|
Inherited Create;
|
|
DcData_ := TDictionary<UTF8String,UTF8String>.Create;
|
|
end;
|
|
Destructor TxPrtInfoData.Destroy;
|
|
begin
|
|
FreeAndNil(DcData_);
|
|
Inherited;
|
|
end;
|
|
|
|
function TxPrtInfoData.LoadFromFile(const sPath: String): Boolean;
|
|
var
|
|
O: ISuperObject;
|
|
i: Integer;
|
|
sKey: String;
|
|
begin
|
|
Result := false;
|
|
try
|
|
if Is_xEncrypt(sPath) then
|
|
begin
|
|
var sDecPath: String := GetRunExePathDir + 'Task\';
|
|
if ForceDirectories(sDecPath) then
|
|
begin
|
|
sDecPath := sDecPath + IntToStr(GetTickCount) + '_Prt.dat';
|
|
try
|
|
if not Do_xDecrypt(sPath, sDecPath) then
|
|
begin
|
|
_Trace('Fail .. Do_xDecrypt() .. Path=%s', [sDecPath]);
|
|
exit;
|
|
end;
|
|
|
|
if not LoadJsonObjFromFile(O, sDecPath) then
|
|
begin
|
|
_Trace('Fail .. TxPrtInfoData.LoadJsonObjFromFile()');
|
|
exit;
|
|
end;
|
|
finally
|
|
if FileExists(sDecPath) then
|
|
DeleteFile(sDecPath);
|
|
end;
|
|
end else begin
|
|
_Trace('Fail .. CreateDir() .. Path=%s', [sDecPath]);
|
|
exit;
|
|
end;
|
|
end else
|
|
if not LoadJsonObjFromFile(O, sPath) then
|
|
begin
|
|
_Trace('Fail .. TxPrtInfoData.LoadJsonObjFromFile()');
|
|
exit;
|
|
end;
|
|
|
|
if (O.DataType <> stArray) or (O.AsArray.Length = 0) then
|
|
begin
|
|
_Trace('Fail .. TxPrtInfoData.InvalidData()');
|
|
exit;
|
|
end;
|
|
|
|
for i := 0 to O.AsArray.Length - 1 do
|
|
begin
|
|
sKey := O.AsArray.O[i].S['p_code'].ToUpper;
|
|
try
|
|
if sKey <> '' then
|
|
DcData_.Add(sKey, O.AsArray.O[i].AsJSon);
|
|
except
|
|
_Trace('Fail .. xPrtInfoData.LoadFromFile() .. 중복 데이터? Key=%s', [sKey], 9);
|
|
end;
|
|
end;
|
|
Result := true;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. LoadFromFile()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxPrtInfoData.UpdateData(const sJsonData: String);
|
|
var
|
|
O: ISuperObject;
|
|
i: Integer;
|
|
sKey: String;
|
|
begin
|
|
try
|
|
O := SO(sJsonData);
|
|
if O = nil then
|
|
exit;
|
|
|
|
if (O.O['created'] <> nil) and (O.O['created'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['created'].Length - 1 do
|
|
begin
|
|
sKey := O.A['created'].O[i].S['p_code'].ToUpper;
|
|
if not DcData_.ContainsKey(sKey) then
|
|
begin
|
|
DcData_.Add(sKey, O.A['created'].O[i].AsJSon);
|
|
_Trace('xprint-printers.UpdateData() .. created, p_code=%s', [O.A['created'].O[i].S['p_code']], 5);
|
|
end else begin
|
|
DcData_[sKey] := O.A['created'].O[i].AsJSon;
|
|
_Trace('xprint-printers.UpdateData() .. created(mod), p_code=%s', [O.A['created'].O[i].S['p_code']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['updated'] <> nil) and (O.O['updated'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['updated'].Length - 1 do
|
|
begin
|
|
sKey := O.A['updated'].O[i].S['p_code'].ToUpper;
|
|
if not DcData_.ContainsKey(sKey) then
|
|
begin
|
|
DcData_.Add(sKey, O.A['updated'].O[i].AsJSon);
|
|
_Trace('xprint-printers.UpdateData() .. updated(new), p_code=%s', [O.A['updated'].O[i].S['p_code']], 5);
|
|
end else begin
|
|
DcData_[sKey] := O.A['updated'].O[i].AsJSon;
|
|
_Trace('xprint-printers.UpdateData() .. updated, p_code=%s', [O.A['updated'].O[i].S['p_code']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['deleted'] <> nil) and (O.O['deleted'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['deleted'].Length - 1 do
|
|
begin
|
|
sKey := O.A['deleted'].O[i].S['p_code'].ToUpper;
|
|
if DcData_.ContainsKey(sKey) then
|
|
begin
|
|
DcData_.Remove(O.A['deleted'].O[i].S['p_code'].ToUpper);
|
|
_Trace('xprint-printers.UpdateData() .. deleted, p_code=%s', [O.A['deleted'].O[i].S['p_code']], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. UpdateData()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxPrtInfoData.SaveToFile(const sPath: String);
|
|
var
|
|
enum: TEnumerator<UTF8String>;
|
|
sData, sEnt: String;
|
|
begin
|
|
try
|
|
sData := '';
|
|
Guard(enum, DcData_.Values.GetEnumerator);
|
|
while enum.MoveNext do
|
|
begin
|
|
sEnt := enum.Current;
|
|
|
|
if sEnt <> '' then
|
|
SumString(sData, sEnt, ',');
|
|
end;
|
|
SaveStrToFile(sPath, '[' + sData + ']', TEncoding.UTF8);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. SaveToFile()');
|
|
end;
|
|
end;
|
|
|
|
{ TxStrData }
|
|
|
|
Constructor TxStrData.Create(sName: String);
|
|
begin
|
|
Inherited Create;
|
|
sName_ := sName;
|
|
DataList_ := TStringList.Create;
|
|
DataList_.CaseSensitive := false;
|
|
end;
|
|
Destructor TxStrData.Destroy;
|
|
begin
|
|
FreeAndNil(DataList_);
|
|
Inherited;
|
|
end;
|
|
|
|
function TxStrData.LoadFromFile(const sPath: String): Boolean;
|
|
var
|
|
O: ISuperObject;
|
|
i: Integer;
|
|
sKey: String;
|
|
begin
|
|
try
|
|
if Is_xEncrypt(sPath) then
|
|
begin
|
|
var sDecPath: String := GetRunExePathDir + 'Task\';
|
|
if ForceDirectories(sDecPath) then
|
|
begin
|
|
sDecPath := sDecPath + IntToStr(GetTickCount) + Format('_%s.dat', [sName_]);
|
|
try
|
|
if not Do_xDecrypt(sPath, sDecPath) then
|
|
begin
|
|
_Trace('Fail .. Do_xDecrypt() .. %s, Path=%s', [sName_, sDecPath]);
|
|
exit;
|
|
end;
|
|
|
|
if not LoadJsonObjFromFile(O, sDecPath) then
|
|
begin
|
|
_Trace('Fail .. TxStrData.LoadJsonObjFromFile()-' + sName_);
|
|
exit;
|
|
end;
|
|
finally
|
|
if FileExists(sDecPath) then
|
|
DeleteFile(sDecPath);
|
|
end;
|
|
end else begin
|
|
_Trace('Fail .. CreateDir() .. %s, Path=%s', [sName_, sDecPath]);
|
|
exit;
|
|
end;
|
|
end else
|
|
if not LoadJsonObjFromFile(O, sPath) then
|
|
begin
|
|
_Trace('Fail .. TxStrData.LoadJsonObjFromFile()-' + sName_);
|
|
exit;
|
|
end;
|
|
|
|
if (O.DataType <> stArray) or (O.AsArray.Length = 0) then
|
|
exit;
|
|
|
|
for i := 0 to O.AsArray.Length - 1 do
|
|
DataList_.Add(O.AsArray.S[i]);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. LoadFromFile()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxStrData.UpdateData(const sJsonData: String);
|
|
var
|
|
O: ISuperObject;
|
|
i, n: Integer;
|
|
sEnt: String;
|
|
begin
|
|
try
|
|
O := SO(sJsonData);
|
|
if O = nil then
|
|
exit;
|
|
|
|
if (O.O['created'] <> nil) and (O.O['created'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['created'].Length - 1 do
|
|
begin
|
|
sEnt := O.A['created'].S[i];
|
|
if DataList_.IndexOf(sEnt) = -1 then
|
|
begin
|
|
DataList_.Add(sEnt);
|
|
_Trace('%s.UpdateData() .. created, Ent=%s', [sName_, sEnt], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['updated'] <> nil) and (O.O['updated'].DataType = stArray) then
|
|
begin
|
|
// 수정은 없을거 같지만... created와 똑같이 처리하는걸로 해준다
|
|
for i := 0 to O.A['updated'].Length - 1 do
|
|
begin
|
|
sEnt := O.A['updated'].S[i];
|
|
if DataList_.IndexOf(sEnt) = -1 then
|
|
begin
|
|
DataList_.Add(sEnt);
|
|
_Trace('%s.UpdateData() .. updated, Ent=%s', [sName_, sEnt], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (O.O['deleted'] <> nil) and (O.O['deleted'].DataType = stArray) then
|
|
begin
|
|
for i := 0 to O.A['deleted'].Length - 1 do
|
|
begin
|
|
sEnt := O.A['deleted'].S[i];
|
|
n := DataList_.IndexOf(sEnt);
|
|
if n <> -1 then
|
|
begin
|
|
DataList_.Delete(n);
|
|
_Trace('%s.UpdateData() .. deleted, Ent=%s', [sName_, sEnt], 5);
|
|
end;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. UpdateData()');
|
|
end;
|
|
end;
|
|
|
|
procedure TxStrData.SaveToFile(const sPath: String);
|
|
var
|
|
OA: ISuperObject;
|
|
i: Integer;
|
|
begin
|
|
try
|
|
OA := TSuperObject.Create(stArray);
|
|
for i := 0 to DataList_.Count - 1 do
|
|
OA.AsArray.Add(DataList_[i]);
|
|
|
|
SaveJsonObjToFile(OA, sPath);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. SaveToFile()');
|
|
end;
|
|
end;
|
|
|
|
|
|
function GetTimestampFromJsonStr(sJsonStr: String): String;
|
|
var
|
|
O: ISuperObject;
|
|
begin
|
|
Result := '';
|
|
try
|
|
O := SO(sJsonStr);
|
|
Result := O.S['timestamp'];
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetTimestampFromJsonStr(), Data=' + sJsonStr);
|
|
end;
|
|
end;
|
|
|
|
procedure ProcessCheck_xPrintData(aHTTP: TIdHTTP);
|
|
var
|
|
ss: TStringStream;
|
|
ReqPrtDatas: TxPrtDatas;
|
|
sUpDt: String;
|
|
begin
|
|
try
|
|
if CUSTOMER_TYPE <> CUSTOMER_KIMCHANG then
|
|
exit;
|
|
|
|
// 24시간에 한번만 업데이트 되도록 임시 보완 25_0924 14:55:13 kku
|
|
// if (gMgSvc.dtOneDay_ <> 0) and (HoursBetween(gMgSvc.dtOneDay_, Now) < 24) then
|
|
// exit;
|
|
|
|
ReqPrtDatas := [];
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/emps/latest-timestamp'));
|
|
if (sUpDt <> '') and (gMgSvc.EmpsUpDt <> sUpDt) then
|
|
Include(ReqPrtDatas, xpdEmp);
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/billcodes/latest-timestamp'));
|
|
if (sUpDt <> '') and (gMgSvc.BillUpDt <> sUpDt) then
|
|
Include(ReqPrtDatas, xpdBill);
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/xprint-printers/latest-timestamp'));
|
|
if (sUpDt <> '') and (gMgSvc.PrtsUpDt <> sUpDt) then
|
|
Include(ReqPrtDatas, xpdPrts);
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/mk-codes/latest-timestamp'));
|
|
if (sUpDt <> '') and (gMgSvc.MkcdUpDt <> sUpDt) then
|
|
Include(ReqPrtDatas, xpdMkcd);
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/lumpsum-fixed-codes/latest-timestamp'));
|
|
if (sUpDt <> '') and (gMgSvc.LumpUpDt <> sUpDt) then
|
|
Include(ReqPrtDatas, xpdLump);
|
|
|
|
if ReqPrtDatas <> [] then
|
|
ProcessRcv_xPrintData(aHTTP, ReqPrtDatas);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. ProcessCheck_xPrintData()');
|
|
end;
|
|
end;
|
|
|
|
function ProcessRcv_xPrintData(aHTTP: TIdHTTP; aPrtDatas: TxPrtDatas; bForceDl: Boolean = false): Boolean;
|
|
var
|
|
sXPrtDir, sUpDt, sToDt, sPath: String;
|
|
ss: TStringStream;
|
|
bUpdate, bEncData: Boolean;
|
|
|
|
procedure EncFile(const sPath: String);
|
|
var
|
|
sEncPath: String;
|
|
begin
|
|
if not bEncData then
|
|
exit;
|
|
|
|
if not FileExists(sPath) then
|
|
exit;
|
|
|
|
sEncPath := GetRunExePathDir + 'Task\';
|
|
if ForceDirectories(sEncPath) then
|
|
begin
|
|
sEncPath := sEncPath + '$xEnTmp.dat';
|
|
DeleteFile(sEncPath);
|
|
|
|
if Do_xEncrypt(sPath, sEncPath) then
|
|
begin
|
|
DeleteFile(sPath);
|
|
MoveFile_wait(sEncPath, sPath, 3);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result := false;
|
|
try
|
|
TTgTrace.T('ProcessRcv_xPrintData() ..', 1);
|
|
|
|
sXPrtDir := GetCommonDataDir + 'bsoneprint\';
|
|
if not FileExists(sXPrtDir + EXE_xPrintSvc) then
|
|
begin
|
|
TTgTrace.T('Fail .. ProcessRcv_xPrintData() .. xPrint Client를 찾을 수 없음.', 1);
|
|
exit;
|
|
end;
|
|
|
|
sXPrtDir := sXPrtDir + 'data\';
|
|
if not ForceDirectories(sXPrtDir) then
|
|
begin
|
|
TTgTrace.T('Fail .. ProcessRcv_xPrintData() .. data 폴더 생성 실패, Path=%s', [sXPrtDir], 1);
|
|
exit;
|
|
end;
|
|
|
|
bEncData := true;
|
|
try
|
|
sPath := GetProgramFilesDir + DIR_TG + INI_FORCEHE;
|
|
if FileExists(sPath) then
|
|
begin
|
|
var ini: TIniFile;
|
|
Guard(ini, TIniFile.Create(sPath));
|
|
bEncData := not ini.ReadBool('Force', 'xPrintDataNoEnc', false);
|
|
end;
|
|
except
|
|
//
|
|
end;
|
|
|
|
bUpdate := false;
|
|
Guard(ss, TStringStream.Create('', TEncoding.UTF8));
|
|
|
|
if xpdEmp in aPrtDatas then
|
|
begin
|
|
sPath := sXPrtDir + 'xEmp.dat';
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/emps/latest-timestamp'));
|
|
if not bForceDl and FileExists(sPath) and (sUpDt <> '') and (gMgSvc.EmpsUpDt <> '') then
|
|
begin
|
|
sToDt := '2099-12-31T23:59:59Z';
|
|
aHTTP.Get(gMgSvc.DestIPort + Format('aapi/emps?include=attribute&from=%s&to=%s&include=changeType&groupBy=changeType', [gMgSvc.EmpsUpDt, sToDt]), ss);
|
|
end else
|
|
aHTTP.Get(gMgSvc.DestIPort + 'aapi/emps?include=attribute&isRetired=false&isDeleted=false', ss);
|
|
|
|
// aHTTP.Get(gMgSvc.DestIPort + 'aapi/emps?include=attribute', ss);
|
|
|
|
if ss.Size > 0 then
|
|
begin
|
|
if not bForceDl and FileExists(sPath) then
|
|
begin
|
|
var xEmpData: TxEmpData;
|
|
Guard(xEmpData, TxEmpData.Create);
|
|
xEmpData.LoadFromFile(sPath);
|
|
xEmpData.UpdateData(ss.DataString);
|
|
xEmpData.SaveToFile(sPath);
|
|
TTgTrace.T('emps 데이터 업데이트 완료', 1);
|
|
end else begin
|
|
if bForceDl and FileExists(sPath) then
|
|
DeleteFile(sPath);
|
|
|
|
ss.SaveToFile(sPath);
|
|
TTgTrace.T('emps 데이터 전체 다운로드 완료', 1);
|
|
end;
|
|
EncFile(sPath);
|
|
end;
|
|
|
|
if sUpDt <> '' then
|
|
begin
|
|
gMgSvc.EmpsUpDt := sUpDt;
|
|
bUpdate := true;
|
|
end;
|
|
end;
|
|
|
|
if xpdBill in aPrtDatas then
|
|
begin
|
|
sPath := sXPrtDir + 'xBil.dat';
|
|
ss.Clear;
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/billcodes/latest-timestamp'));
|
|
if not bForceDl and FileExists(sPath) and (sUpDt <> '') and (gMgSvc.BillUpDt <> '') then
|
|
begin
|
|
sToDt := '2099-12-31T23:59:59Z';
|
|
aHTTP.Get(gMgSvc.DestIPort + Format('aapi/billcodes?from=%s&to=%s&include=changeType&groupBy=changeType', [gMgSvc.BillUpDt, sToDt]), ss);
|
|
end else
|
|
aHTTP.Get(gMgSvc.DestIPort + 'aapi/billcodes?isDeleted=false', ss);
|
|
|
|
// aHTTP.Get(gMgSvc.DestIPort + 'aapi/billcodes', ss);
|
|
|
|
if ss.Size > 0 then
|
|
begin
|
|
if not bForceDl and FileExists(sPath) then
|
|
begin
|
|
var xBillData: TxBillData;
|
|
Guard(xBillData, TxBillData.Create);
|
|
xBillData.LoadFromFile(sPath);
|
|
xBillData.UpdateData(ss.DataString);
|
|
xBillData.SaveToFile(sPath);
|
|
TTgTrace.T('billcodes 데이터 업데이트 완료', 1);
|
|
end else begin
|
|
if bForceDl and FileExists(sPath) then
|
|
DeleteFile(sPath);
|
|
|
|
ss.SaveToFile(sPath);
|
|
TTgTrace.T('billcodes 데이터 전체 다운로드 완료', 1);
|
|
end;
|
|
EncFile(sPath);
|
|
end;
|
|
|
|
if sUpDt <> '' then
|
|
begin
|
|
gMgSvc.BillUpDt := sUpDt;
|
|
bUpdate := true;
|
|
end;
|
|
end;
|
|
|
|
if xpdPrts in aPrtDatas then
|
|
begin
|
|
sPath := sXPrtDir + 'xPti.dat';
|
|
ss.Clear;
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/xprint-printers/latest-timestamp'));
|
|
if not bForceDl and FileExists(sPath) and (sUpDt <> '') and (gMgSvc.PrtsUpDt <> '') then
|
|
begin
|
|
sToDt := '2099-12-31T23:59:59Z';
|
|
aHTTP.Get(gMgSvc.DestIPort + Format('aapi/xprint-printers?from=%s&to=%s&include=changeType&groupBy=changeType', [gMgSvc.PrtsUpDt, sToDt]), ss);
|
|
end else
|
|
aHTTP.Get(gMgSvc.DestIPort + 'aapi/xprint-printers?isDeleted=false', ss);
|
|
|
|
// aHTTP.Get(gMgSvc.DestIPort + 'aapi/xprint-printers', ss);
|
|
|
|
if ss.Size > 0 then
|
|
begin
|
|
if not bForceDl and FileExists(sPath) then
|
|
begin
|
|
var xPrtInfoData: TxPrtInfoData;
|
|
Guard(xPrtInfoData, TxPrtInfoData.Create);
|
|
xPrtInfoData.LoadFromFile(sPath);
|
|
xPrtInfoData.UpdateData(ss.DataString);
|
|
xPrtInfoData.SaveToFile(sPath);
|
|
TTgTrace.T('xprint-printers 데이터 업데이트 완료', 1);
|
|
end else begin
|
|
if bForceDl and FileExists(sPath) then
|
|
DeleteFile(sPath);
|
|
|
|
ss.SaveToFile(sPath);
|
|
TTgTrace.T('xprint-printers 데이터 전체 다운로드 완료', 1);
|
|
end;
|
|
EncFile(sPath);
|
|
end;
|
|
|
|
if sUpDt <> '' then
|
|
begin
|
|
gMgSvc.PrtsUpDt := sUpDt;
|
|
bUpdate := true;
|
|
end;
|
|
end;
|
|
|
|
if xpdMkcd in aPrtDatas then
|
|
begin
|
|
sPath := sXPrtDir + 'xMkc.dat';
|
|
ss.Clear;
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/mk-codes/latest-timestamp'));
|
|
if not bForceDl and FileExists(sPath) and (sUpDt <> '') and (gMgSvc.MkcdUpDt <> '') then
|
|
begin
|
|
sToDt := '2099-12-31T23:59:59Z';
|
|
aHTTP.Get(gMgSvc.DestIPort + Format('aapi/mk-codes?from=%s&to=%s&include=changeType&groupBy=changeType', [gMgSvc.MkcdUpDt, sToDt]), ss);
|
|
end else
|
|
aHTTP.Get(gMgSvc.DestIPort + 'aapi/mk-codes?isDeleted=false', ss);
|
|
|
|
// aHTTP.Get(gMgSvc.DestIPort + 'aapi/mk-codes', ss);
|
|
|
|
if ss.Size > 0 then
|
|
begin
|
|
if not bForceDl and FileExists(sPath) then
|
|
begin
|
|
var xStrData: TxStrData;
|
|
Guard(xStrData, TxStrData.Create('mk-codes'));
|
|
xStrData.LoadFromFile(sPath);
|
|
xStrData.UpdateData(ss.DataString);
|
|
xStrData.SaveToFile(sPath);
|
|
TTgTrace.T('mk-codes 데이터 업데이트 완료', 1);
|
|
end else begin
|
|
if bForceDl and FileExists(sPath) then
|
|
DeleteFile(sPath);
|
|
|
|
ss.SaveToFile(sXPrtDir + 'xMkc.dat');
|
|
TTgTrace.T('mk-codes 데이터 전체 다운로드 완료', 1);
|
|
end;
|
|
EncFile(sPath);
|
|
end;
|
|
|
|
if sUpDt <> '' then
|
|
begin
|
|
gMgSvc.MkcdUpDt := sUpDt;
|
|
bUpdate := true;
|
|
end;
|
|
end;
|
|
|
|
if xpdLump in aPrtDatas then
|
|
begin
|
|
sPath := sXPrtDir + 'xLum.dat';
|
|
ss.Clear;
|
|
|
|
sUpDt := GetTimestampFromJsonStr(aHTTP.Get(gMgSvc.DestIPort + 'aapi/lumpsum-fixed-codes/latest-timestamp'));
|
|
if not bForceDl and FileExists(sPath) and (sUpDt <> '') and (gMgSvc.LumpUpDt <> '') then
|
|
begin
|
|
sToDt := '2099-12-31T23:59:59Z';
|
|
aHTTP.Get(gMgSvc.DestIPort + Format('aapi/lumpsum-fixed-codes?from=%s&to=%s&include=changeType&groupBy=changeType', [gMgSvc.LumpUpDt, sToDt]), ss);
|
|
end else
|
|
aHTTP.Get(gMgSvc.DestIPort + 'aapi/lumpsum-fixed-codes?isDeleted=false', ss);
|
|
|
|
// aHTTP.Get(gMgSvc.DestIPort + 'aapi/lumpsum-fixed-codes', ss);
|
|
|
|
if ss.Size > 0 then
|
|
begin
|
|
if not bForceDl and FileExists(sPath) then
|
|
begin
|
|
var xStrData: TxStrData;
|
|
Guard(xStrData, TxStrData.Create('lumpsum-fixed-codes'));
|
|
xStrData.LoadFromFile(sPath);
|
|
xStrData.UpdateData(ss.DataString);
|
|
xStrData.SaveToFile(sPath);
|
|
TTgTrace.T('lumpsum-fixed-codes 데이터 업데이트 완료', 1);
|
|
end else begin
|
|
if bForceDl and FileExists(sPath) then
|
|
DeleteFile(sPath);
|
|
|
|
ss.SaveToFile(sPath);
|
|
TTgTrace.T('lumpsum-fixed-codes 데이터 전체 다운로드 완료', 1);
|
|
end;
|
|
EncFile(sPath);
|
|
end;
|
|
|
|
if sUpDt <> '' then
|
|
begin
|
|
gMgSvc.LumpUpDt := sUpDt;
|
|
bUpdate := true;
|
|
end;
|
|
end;
|
|
|
|
if bUpdate then
|
|
begin
|
|
var ini: TIniFile;
|
|
Guard(ini, TIniFile.Create(GetRunExePathDir + 'xPrint.ini'));
|
|
ini.WriteString('DateTime', 'EmpsUpDt', gMgSvc.EmpsUpDt);
|
|
ini.WriteString('DateTime', 'PrtsUpDt', gMgSvc.PrtsUpDt);
|
|
ini.WriteString('DateTime', 'BillUpDt', gMgSvc.BillUpDt);
|
|
ini.WriteString('DateTime', 'MkcdUpDt', gMgSvc.MkcdUpDt);
|
|
ini.WriteString('DateTime', 'LumpUpDt', gMgSvc.LumpUpDt);
|
|
gMgSvc.dtOneDay_ := Now;
|
|
ini.WriteDateTime('DateTime', 'xOneDayDT', gMgSvc.dtOneDay_);
|
|
end;
|
|
|
|
Result := true;
|
|
TTgTrace.T('ProcessRcv_xPrintData() .. OK', 1);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. ProcessRcv_xPrintData()');
|
|
end;
|
|
end;
|
|
|
|
procedure CheckAndUpdate_xPrint;
|
|
var
|
|
sRes,
|
|
sNewVer,
|
|
sCurVer: String;
|
|
NewVers,
|
|
CurVers: TStringList;
|
|
i: Integer;
|
|
OVer: ISuperObject;
|
|
bDoUpdate: Boolean;
|
|
PO: TPrefModel;
|
|
begin
|
|
try
|
|
if gMgSvc.ThdxPrintLog = nil then
|
|
exit;
|
|
|
|
PO := gMgSvc.PrefModel;
|
|
if not PO.xPrintUpEnable then
|
|
exit;
|
|
|
|
sNewVer := PO.xPrintUpVer;
|
|
if sNewVer = '' then
|
|
exit;
|
|
|
|
sCurVer := gMgSvc.xPrintVer;
|
|
if sCurVer = '' then
|
|
sCurVer := '1.0.0';
|
|
|
|
if sNewVer = sCurVer then
|
|
exit;
|
|
|
|
bDoUpdate := false;
|
|
if not PO.xPrintUpFixedVer then
|
|
begin
|
|
Guard(NewVers, TStringList.Create);
|
|
Guard(CurVers, TStringList.Create);
|
|
if SplitString(sNewVer, '.', NewVers) = 0 then
|
|
exit;
|
|
|
|
if SplitString(sCurVer, '.', CurVers) = 0 then
|
|
begin
|
|
bDoUpdate := StrToIntDef(NewVers[0], 0) > StrToIntDef(sCurVer, 0);
|
|
exit;
|
|
end;
|
|
|
|
for i := 0 to NewVers.Count - 1 do
|
|
begin
|
|
if i >= CurVers.Count then
|
|
begin
|
|
bDoUpdate := true;
|
|
break;
|
|
end;
|
|
|
|
if StrToIntDef(NewVers[i], 0) < StrToIntDef(CurVers[i], 0) then
|
|
break;
|
|
|
|
if StrToIntDef(NewVers[i], 0) > StrToIntDef(CurVers[i], 0) then
|
|
begin
|
|
bDoUpdate := true;
|
|
break;
|
|
end;
|
|
end;
|
|
end else
|
|
bDoUpdate := sNewVer <> sCurVer;
|
|
|
|
if bDoUpdate then
|
|
begin
|
|
// 다운로드, 업데이트 실패해도 재시도 하지 않게 버전 정보 업데이트 25_0730 15:32:07 kku
|
|
gMgSvc.xPrintVer := sNewVer;
|
|
TTgTrace.T('xPrint 업데이트 시작 .. Ver=%s, NewVer=%s', [sCurVer, sNewVer]);
|
|
|
|
var sUrl: String := gMgSvc.DestIPort + 'aapi/comps/xprint?ver=' + sNewVer;
|
|
var nOldTO: Integer := gMgSvc.HTTP.ReadTimeout;
|
|
var sPtPath: String := GetProgramFilesDir + DIR_TG;
|
|
var sZName: String := 'x_patch.zip';
|
|
var fs: TFileStream := TFileStream.Create(sPtPath + sZName, fmCreate);
|
|
gMgSvc.HTTP.ReadTimeout := 120000;
|
|
try
|
|
gMgSvc.HTTP.Get(sUrl, fs);
|
|
Sleep(500);
|
|
if FileExists(sPtPath + sZName) then
|
|
begin
|
|
FreeAndNil(fs);
|
|
if GetFileSize_path(sPtPath + sZName) = 0 then
|
|
begin
|
|
TTgTrace.T('Fail .. CheckAndUpdate_xPrint() .. 다운로드 실패, 크기 0');
|
|
DeleteFile(PChar(sPtPath + sZName));
|
|
exit;
|
|
end;
|
|
|
|
if not UninstallXPrt(true) then
|
|
begin
|
|
gMgSvc.xPrintVer := sCurVer;
|
|
TTgTrace.T('Fail .. CheckAndUpdate_xPrint() .. 제거 실패.');
|
|
exit;
|
|
end;
|
|
|
|
var sXPrtPath: String := 'C:\ProgramData\bsoneprint\';
|
|
if ForceDirectories(sXPrtPath) then
|
|
begin
|
|
TZipFile.ExtractZipFile(sPtPath + sZName, sXPrtPath);
|
|
DeleteFile(PChar(sPtPath + sZName));
|
|
|
|
ExecutePath_hide(sXprtPath + EXE_xPrintSvc, '-install');
|
|
end;
|
|
end;
|
|
finally
|
|
if fs <> nil then
|
|
FreeAndNil(fs);
|
|
gMgSvc.HTTP.ReadTimeout := nOldTO;
|
|
end;
|
|
|
|
TTgTrace.T('xPrint 업데이트 완료 .. Ver=%s, NewVer=%s', [sCurVer, sNewVer]);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. CheckAndUpdate_xPrint()');
|
|
end;
|
|
end;
|
|
|
|
//procedure CheckAndUpdate_xPrint;
|
|
//var
|
|
// sRes,
|
|
// sNewVer,
|
|
// sCurVer: String;
|
|
// NewVers,
|
|
// CurVers: TStringList;
|
|
// i: Integer;
|
|
// OVer: ISuperObject;
|
|
// bDoUpdate: Boolean;
|
|
//begin
|
|
// try
|
|
// if gMgSvc.ThdxPrintLog = nil then
|
|
// exit;
|
|
//
|
|
// sRes := gMgSvc.HTTP.Get(gMgSvc.DestIPort + 'aapi/comps/xprint/info');
|
|
// if sRes = '' then
|
|
// exit;
|
|
// try
|
|
// OVer := SO(sRes);
|
|
// except
|
|
// exit;
|
|
// end;
|
|
//
|
|
// sNewVer := OVer.S['ver'];
|
|
// if sNewVer = '' then
|
|
// exit;
|
|
//
|
|
// sCurVer := gMgSvc.xPrintVer;
|
|
// if sCurVer = '' then
|
|
// sCurVer := '1.0.0';
|
|
//
|
|
// if sNewVer = sCurVer then
|
|
// exit;
|
|
//
|
|
// Guard(NewVers, TStringList.Create);
|
|
// Guard(CurVers, TStringList.Create);
|
|
// if SplitString(sNewVer, '.', NewVers) = 0 then
|
|
// exit;
|
|
//
|
|
// bDoUpdate := false;
|
|
// if SplitString(sCurVer, '.', CurVers) = 0 then
|
|
// begin
|
|
// bDoUpdate := StrToIntDef(NewVers[0], 0) > StrToIntDef(sCurVer, 0);
|
|
// exit;
|
|
// end;
|
|
//
|
|
// for i := 0 to NewVers.Count - 1 do
|
|
// begin
|
|
// if i >= CurVers.Count then
|
|
// begin
|
|
// bDoUpdate := true;
|
|
// break;
|
|
// end;
|
|
//
|
|
// if StrToIntDef(NewVers[i], 0) < StrToIntDef(CurVers[i], 0) then
|
|
// break;
|
|
//
|
|
// if StrToIntDef(NewVers[i], 0) > StrToIntDef(CurVers[i], 0) then
|
|
// begin
|
|
// bDoUpdate := true;
|
|
// break;
|
|
// end;
|
|
// end;
|
|
//
|
|
// if bDoUpdate then
|
|
// begin
|
|
// // 다운로드, 업데이트 실패해도 재시도 하지 않게 버전 정보 업데이트 25_0730 15:32:07 kku
|
|
// gMgSvc.xPrintVer := sNewVer;
|
|
// TTgTrace.T('xPrint 업데이트 시작 .. Ver=%s, NewVer=%s', [sCurVer, sNewVer]);
|
|
//
|
|
// var sUrl: String := gMgSvc.DestIPort + 'aapi/comps/xprint';
|
|
// var nOldTO: Integer := gMgSvc.HTTP.ReadTimeout;
|
|
// var sPtPath: String := GetProgramFilesDir + DIR_TG;
|
|
// var sZName: String := 'x_patch.zip';
|
|
// var fs: TFileStream := TFileStream.Create(sPtPath + sZName, fmCreate);
|
|
// gMgSvc.HTTP.ReadTimeout := 120000;
|
|
// try
|
|
// gMgSvc.HTTP.Get(sUrl, fs);
|
|
// Sleep(500);
|
|
// if FileExists(sPtPath + sZName) then
|
|
// begin
|
|
// FreeAndNil(fs);
|
|
// if GetFileSize_path(sPtPath + sZName) = 0 then
|
|
// begin
|
|
// TTgTrace.T('Fail .. CheckAndUpdate_xPrint() .. 다운로드 실패, 크기 0');
|
|
// DeleteFile(PChar(sPtPath + sZName));
|
|
// exit;
|
|
// end;
|
|
//
|
|
// if not UninstallXPrt(true) then
|
|
// begin
|
|
// gMgSvc.xPrintVer := sCurVer;
|
|
// TTgTrace.T('Fail .. CheckAndUpdate_xPrint() .. 제거 실패.');
|
|
// exit;
|
|
// end;
|
|
//
|
|
// var sXPrtPath: String := 'C:\ProgramData\bsoneprint\';
|
|
// if ForceDirectories(sXPrtPath) then
|
|
// begin
|
|
// TZipFile.ExtractZipFile(sPtPath + sZName, sXPrtPath);
|
|
// DeleteFile(PChar(sPtPath + sZName));
|
|
//
|
|
// ExecutePath_hide(sXprtPath + EXE_xPrintSvc, '-install');
|
|
// end;
|
|
// end;
|
|
// finally
|
|
// if fs <> nil then
|
|
// FreeAndNil(fs);
|
|
// gMgSvc.HTTP.ReadTimeout := nOldTO;
|
|
// end;
|
|
//
|
|
// TTgTrace.T('xPrint 업데이트 완료 .. Ver=%s, NewVer=%s', [sCurVer, sNewVer]);
|
|
// end;
|
|
// except
|
|
// on E: Exception do
|
|
// ETgException.TraceException(E, 'Fail .. CheckAndUpdate_xPrint()');
|
|
// end;
|
|
//end;
|
|
|
|
end.
|