chore(legacy): muta proiectul Visual FoxPro in legacy-vfp/

Codul VFP original (ROAAUTO) era doar de testare/proba si nu se mai dezvolta.
Mutat in legacy-vfp/ (sursa .prg, proiect .pjx/.PJT, date .DBF/.CDX/.FPT,
test-comenzi.xml). Actualizat caile DBF default in tools/import_dbf.py si
referinta din tests/test_import_dbf.py. Adaugat legacy-vfp/README.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-17 06:51:21 +00:00
parent 854db66abc
commit 5a8787bbc4
17 changed files with 35 additions and 4 deletions

31
legacy-vfp/README.md Normal file
View File

@@ -0,0 +1,31 @@
# legacy-vfp/ — arhiva Visual FoxPro (ROAAUTO)
Proiectul **Visual FoxPro** original (clasa `RarAutoPass`, ROAAUTO) care declara
prestatiile la RAR AUTOPASS. A fost folosit doar pentru testare si proba pe endpoint-ul
de test RAR; **nu se mai dezvolta** — gateway-ul Python din `../app/` il inlocuieste.
Pastrat ca **sursa de adevar de contract** pentru portarea web si ca sursa pentru migrarea
DBF.
## Continut
| Fisier | Rol | Portat in |
|--------|-----|-----------|
| `rar_autopass.prg` | clasa `RarAutoPass`: login+JWT, nomenclator, postPrezentare, cancel | `app/rar_client.py` |
| `rar-forms.prg` | UI + timer auto-process | logica -> worker |
| `export_comenzi.prg` | citeste comenzi/operatii, construieste payload | client subtire `POST /v1/prezentari` |
| `rar_advanced.prg` | export Excel (oglinda treapta 2) | referinta import xlsx/csv |
| `rar_automate.prg`, `nfjsonread.prg` | automatizare / parse JSON | referinta |
| `rar_autopass.pjx` / `.PJT` | fisierele de proiect VFP | — |
| `mapare_prestatii.DBF` (+ `.CDX`/`.FPT`) | cod_op_service -> codPrestatie | `operations_mapping` (via `tools/import_dbf.py`) |
| `prestatii_rar.DBF` (+ `.CDX`) | nomenclator {codPrestatie, numePrestatie} | `nomenclator_rar` (via `tools/import_dbf.py`) |
| `test-comenzi.xml` | comenzi de test (proba) | — |
## Migrare DBF -> SQLite
Datele din DBF se importa cu `tools/import_dbf.py` (caile default pointeaza deja aici):
```bash
python3 -m tools.import_dbf # dry-run + raport
python3 -m tools.import_dbf --commit # scrie in SQLite
```

View File

@@ -0,0 +1,83 @@
* export_comenzi.prg
PROCEDURE ExportComenziXML
PARAMETERS tcFileName, tdData
LOCAL loXML AS MSXML2.DOMDocument.6.0
LOCAL lcXML, llSuccess
llSuccess = .F.
Try
loXML = CREATEOBJECT("MSXML2.DOMDocument.6.0")
loXML.async = .F.
* Creare structura XML
TEXT TO lcXML NOSHOW
<?xml version="1.0" encoding="UTF-8"?>
<comenzi>
</comenzi>
ENDTEXT
loXML.loadXML(lcXML)
loRoot = loXML.documentElement
* Selectam comenzile pentru export
SELECT comenzi_service
SET FILTER TO data_comanda = tdData AND status = "FINALIZAT"
SCAN
* Adaugam nodul pentru comanda
loComanda = loXML.createElement("comanda")
* Adaugam detaliile comenzii
THIS.AddXMLNode(loXML, loComanda, "nr_comanda", nr_comanda)
THIS.AddXMLNode(loXML, loComanda, "data", TTOC(data_comanda, 1))
THIS.AddXMLNode(loXML, loComanda, "vin", vin)
THIS.AddXMLNode(loXML, loComanda, "nr_inmatriculare", nr_auto)
THIS.AddXMLNode(loXML, loComanda, "km_final", TRANSFORM(km))
THIS.AddXMLNode(loXML, loComanda, "km_initial", "0")
THIS.AddXMLNode(loXML, loComanda, "observatii", observatii)
* Adaugam operatiile
loOperatii = loXML.createElement("operatii")
SELECT operatii
SCAN FOR id_comanda = comenzi_service.id
loOperatie = loXML.createElement("operatie")
THIS.AddXMLNode(loXML, loOperatie, "cod_operatie", cod_operatie)
THIS.AddXMLNode(loXML, loOperatie, "denumire", denumire)
loOperatii.appendChild(loOperatie)
ENDSCAN
loComanda.appendChild(loOperatii)
loRoot.appendChild(loComanda)
ENDSCAN
* Salvam XML-ul
loXML.save(tcFileName)
llSuccess = .T.
Catch To loEx
MESSAGEBOX("Eroare export XML: " + loEx.Message, 16, "Eroare")
llSuccess = .F.
Endtry
Return llSuccess
* Helper pentru adaugare noduri
PROCEDURE AddXMLNode
PARAMETERS loXML, loParent, tcName, tcValue
LOCAL loNode, loText, llSuccess
llSuccess = .F.
Try
loNode = loXML.createElement(tcName)
loText = loXML.createTextNode(tcValue)
loNode.appendChild(loText)
loParent.appendChild(loNode)
llSuccess = .T.
Catch To loEx
MESSAGEBOX("Eroare adaugare nod XML: " + loEx.Message, 16, "Eroare")
llSuccess = .F.
Endtry
Return llSuccess

Binary file not shown.

Binary file not shown.

Binary file not shown.

775
legacy-vfp/nfjsonread.prg Normal file
View File

@@ -0,0 +1,775 @@
*-------------------------------------------------------------------
* Created by Marco Plaza vfp2nofox@gmail.com / @vfp2Nofox
* ver 2.000 - 26/03/2016
* ver 2.090 - 22/07/2016 :
* improved error management
* nfjsonread will return .null. for invalid json
*-------------------------------------------------------------------
Lparameters cjsonstr,isFileName,reviveCollection
#Define crlf Chr(13)+Chr(10)
Private All
stackLevels=Astackinfo(aerrs)
If m.stackLevels > 1
calledFrom = 'called From '+aerrs(m.stackLevels-1,4)+' line '+Transform(aerrs(m.stackLevels-1,5))
Else
calledFrom = ''
Endif
oJson = nfJsonCreate2(cjsonstr,isFileName,reviveCollection)
Return Iif(Vartype(m.oJson)='O',m.oJson,.Null.)
*-------------------------------------------------------------------------
Function nfJsonCreate2(cjsonstr,isFileName,reviveCollection)
*-------------------------------------------------------------------------
* validate parameters:
Do Case
Case ;
Vartype(m.cjsonstr) # 'C' Or;
Vartype(m.reviveCollection) # 'L' Or ;
Vartype(m.isFileName) # 'L'
jERROR('invalid parameter type')
Case m.isFileName And !File(m.cjsonstr)
jERROR('File "'+Rtrim(Left(m.cjsonstr,255))+'" does not exist')
Endcase
* process json:
If m.isFileName
cjsonstr = Filetostr(m.cjsonstr)
Endif
cJson = Rtrim(Chrtran(m.cjsonstr,Chr(13)+Chr(9)+Chr(10),''))
pChar = Left(Ltrim(m.cJson),1)
nl = Alines(aj,m.cJson,20,'{','}','"',',',':','[',']')
For xx = 1 To Alen(aj)
If Left(Ltrim(aj(m.xx)),1) $ '{}",:[]' Or Left(Ltrim(m.aj(m.xx)),4) $ 'true/false/null'
aj(m.xx) = Ltrim(aj(m.xx))
Endif
Endfor
Try
x = 1
cError = ''
oStack = Createobject('stack')
oJson = Createobject('empty')
Do Case
Case aj(1)='{'
x = 1
oStack.pushObject()
procstring(m.oJson)
Case aj(1) = '['
x = 0
procstring(m.oJson,.T.)
Otherwise
Error 'Invalid Json: expecting [{ received '+m.pChar
Endcase
If m.reviveCollection
oJson = reviveCollection(m.oJson)
Endif
Catch To oerr
strp = ''
For Y = 1 To m.x
strp = m.strp+aj(m.y)
Endfor
Do Case
Case oerr.ErrorNo = 1098
cError = ' Invalid Json: '+ m.oerr.Message+crlf+' Parsing: '+Right(m.strp,80)
*+' program line: '+Transform(oerr.Lineno)+' array item '+Transform(m.x)
Case oerr.ErrorNo = 2034
cError = ' INVALID DATE: '+crlf+' Parsing: '+Right(m.strp,80)
Otherwise
cError = 'program error # '+Transform(m.oerr.ErrorNo)+crlf+m.oerr.Message+' at: '+Transform(oerr.Lineno)+crlf+' Parsing ('+Transform(m.x)+') '
Endcase
Endtry
If !Empty(m.cError)
jERROR(m.cError)
Endif
Return m.oJson
*------------------------------------------------
Procedure jERROR( cMessage )
*------------------------------------------------
Error 'nfJson ('+m.calledFrom+'):'+crlf+m.cMessage
Return To nfJsonRead
*--------------------------------------------------------------------------------
Procedure procstring(obj,eValue)
*--------------------------------------------------------------------------------
#Define cvalid 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_'
#Define creem '_______________________________________________________________'
Private rowpos,colpos,bidim,ncols,arrayName,expecting,arrayLevel,vari
Private expectingPropertyName,expectingValue,objectOpen
expectingPropertyName = !m.eValue
expectingValue = m.eValue
expecting = Iif(expectingPropertyName,'"}','')
objectOpen = .T.
bidim = .F.
colpos = 0
rowpos = 0
arrayLevel = 0
arrayName = ''
vari = ''
ncols = 0
Do While m.objectOpen
x = m.x+1
Do Case
Case m.x > m.nl
m.x = m.nl
If oStack.Count > 0
Error 'expecting '+m.expecting
Endif
Return
Case aj(m.x) = '}' And '}' $ m.expecting
closeObject()
Case aj(x) = ']' And ']' $ m.expecting
closeArray()
Case m.expecting = ':'
If aj(m.x) = ':'
expecting = ''
Loop
Else
Error 'expecting : received '+aj(m.x)
Endif
Case ',' $ m.expecting
Do Case
Case aj(x) = ','
expecting = Iif( '[' $ m.expecting , '[' , '' )
Case Not aj(m.x) $ m.expecting
Error 'expecting '+m.expecting+' received '+aj(m.x)
Otherwise
expecting = Strtran(m.expecting,',','')
Endcase
Case m.expectingPropertyName
If aj(m.x) = '"'
propertyName(m.obj)
Else
Error 'expecting "'+m.expecting+' received '+aj(m.x)
Endif
Case m.expectingValue
If m.expecting == '[' And m.aj(m.x) # '['
Error 'expecting [ received '+aj(m.x)
Else
procValue(m.obj)
Endif
Endcase
Enddo
*----------------------------------------------------------
Function anuevoel(obj,arrayName,valasig,bidim,colpos,rowpos)
*----------------------------------------------------------
If m.bidim
colpos = m.colpos+1
If colpos > m.ncols
ncols = m.colpos
Endif
Dimension obj.&arrayName(m.rowpos,m.ncols)
obj.&arrayName(m.rowpos,m.colpos) = m.valasig
If Vartype(m.valasig) = 'O'
procstring(obj.&arrayName(m.rowpos,m.colpos))
Endif
Else
rowpos = m.rowpos+1
Dimension obj.&arrayName(m.rowpos)
obj.&arrayName(m.rowpos) = m.valasig
If Vartype(m.valasig) = 'O'
procstring(obj.&arrayName(m.rowpos))
Endif
Endif
*-----------------------------------------
Function unescunicode( Value )
*-----------------------------------------
noc=1
Do While .T.
posunicode = At('\u',m.value,m.noc)
If m.posunicode = 0
Return
Endif
If Substr(m.value,m.posunicode-1,1) = '\' And Substr(m.value,m.posunicode-2,1) # '\'
noc=m.noc+1
Loop
Endif
nunic = Evaluate('0x'+ Substr(m.value,m.posunicode+2,4) )
If Between(m.nunic,0,255)
unicodec = Chr(m.nunic)
Else
unicodec = '&#'+Transform(m.nunic)+';'
Endif
Value = Stuff(m.value,m.posunicode,6,m.unicodec)
Enddo
*-----------------------------------
Function unescapecontrolc( Value )
*-----------------------------------
If At('\', m.value) = 0
Return
Endif
* unescape special characters:
Private aa,elem,unesc
Declare aa(1)
=Alines(m.aa,m.value,18,'\\','\b','\f','\n','\r','\t','\"','\/')
unesc =''
#Define sustb 'bnrt/"'
#Define sustr Chr(127)+Chr(10)+Chr(13)+Chr(9)+Chr(47)+Chr(34)
For Each elem In m.aa
If ! m.elem == '\\' And Right(m.elem,2) = '\'
elem = Left(m.elem,Len(m.elem)-2)+Chrtran(Right(m.elem,1),sustb,sustr)
Endif
unesc = m.unesc+m.elem
Endfor
Value = m.unesc
*--------------------------------------------
Procedure propertyName(obj)
*--------------------------------------------
vari=''
Do While ( Right(m.vari,1) # '"' Or ( Right(m.vari,2) = '\"' And Right(m.vari,3) # '\\"' ) ) And Alen(aj) > m.x
x=m.x+1
vari = m.vari+aj(m.x)
Enddo
If Right(m.vari,1) # '"'
Error ' expecting " received '+ Right(Rtrim(m.vari),1)
Endif
vari = Left(m.vari,Len(m.vari)-1)
vari = Iif(Isalpha(m.vari),'','_')+m.vari
vari = Chrtran( vari, Chrtran( vari, cvalid,'' ) , creem )
If vari = 'tabindex'
vari = '_tabindex'
Endif
expecting = ':'
expectingValue = .T.
expectingPropertyName = .F.
*-------------------------------------------------------------
Procedure procValue(obj)
*-------------------------------------------------------------
Do Case
Case aj(m.x) = '{'
oStack.pushObject()
If m.arrayLevel = 0
AddProperty(obj,m.vari,Createobject('empty'))
procstring(obj.&vari)
expectingPropertyName = .T.
expecting = ',}'
expectingValue = .F.
Else
anuevoel(m.obj,m.arrayName,Createobject('empty'),m.bidim,@colpos,@rowpos)
expectingPropertyName = .F.
expecting = ',]'
expectingValue = .T.
Endif
Case aj(x) = '['
oStack.pushArray()
Do Case
Case m.arrayLevel = 0
arrayName = Evl(m.vari,'array')
rowpos = 0
colpos = 0
bidim = .F.
#DEFINE EMPTYARRAYFLAG '_EMPTY_ARRAY_FLAG_'
Try
AddProperty(obj,(m.arrayName+'(1)'),EMPTYARRAYFLAG)
Catch
m.arrayName = m.arrayName+'_vfpSafe_'
AddProperty(obj,(m.arrayName+'(1)'),EMPTYARRAYFLAG)
Endtry
Case m.arrayLevel = 1 And !m.bidim
rowpos = 1
colpos = 0
ncols = 1
Dime obj.&arrayName(1,2)
bidim = .T.
Endcase
arrayLevel = m.arrayLevel+1
vari=''
expecting = Iif(!m.bidim,'[]{',']')
expectingValue = .T.
expectingPropertyName = .F.
Otherwise
isstring = aj(m.x)='"'
x = m.x + Iif(m.isstring,1,0)
Value = ''
Do While .T.
Value = m.value+m.aj(m.x)
If m.isstring
If Right(m.value,1) = '"' And ( Right(m.value,2) # '\"' Or Right(m.value,3) = '\\' )
Exit
Endif
Else
If Right(m.value,1) $ '}],' And ( Left(Right(m.value,2),1) # '\' Or Left(Right(Value,3),2) = '\\')
Exit
Endif
Endif
If m.x < Alen(aj)
x = m.x+1
Else
Exit
Endif
Enddo
closeChar = Right(m.value,1)
Value = Rtrim(m.value,1,m.closeChar)
If Empty(Value) And Not ( m.isstring And m.closeChar = '"' )
Error 'Expecting value received '+m.closeChar
Endif
Do Case
Case m.isstring
If m.closeChar # '"'
Error 'expecting " received '+m.closeChar
Endif
Case oStack.isObject() And Not m.closeChar $ ',}'
Error 'expecting ,} received '+m.closeChar
Case oStack.isArray() And Not m.closeChar $ ',]'
Error 'expecting ,] received '+m.closeChar
Endcase
If m.isstring
* don't change this lines sequence!:
unescunicode(@Value) && 1
unescapecontrolc(@Value) && 2
Value = Strtran(m.value,'\\','\') && 3
** check for Json Date:
If isJsonDt( m.value )
Value = jsonDateToDT( m.value )
Endif
Else
Value = Alltrim(m.value)
Do Case
Case m.value == 'null'
Value = .Null.
Case m.value == 'true' Or m.value == 'false'
Value = Value='true'
Case Empty(Chrtran(m.value,'-1234567890.E','')) And Occurs('.',m.value) <= 1 And Occurs('-',m.value) <= 1 And Occurs('E',m.value)<=1
If Not 'E' $ m.value
Value = Cast( m.value As N( Len(m.value) , Iif(At('.',m.value)>0,Len(m.value)-At( '.',m.value) ,0) ))
Endif
Otherwise
Error 'expecting "|number|null|true|false| received '+aj(m.x)
Endcase
Endif
If m.arrayLevel = 0
AddProperty(obj,m.vari,m.value)
expecting = '}'
expectingValue = .F.
expectingPropertyName = .T.
Else
anuevoel(obj,m.arrayName,m.value,m.bidim,@colpos,@rowpos)
expecting = ']'
expectingValue = .T.
expectingPropertyName = .F.
Endif
expecting = Iif(m.isstring,',','')+m.expecting
Do Case
Case m.closeChar = ']'
closeArray()
Case m.closeChar = '}'
closeObject()
Endcase
Endcase
*------------------------------
Function closeArray()
*------------------------------
If oStack.Pop() # 'A'
Error 'unexpected ] '
Endif
If m.arrayLevel = 0
Error 'unexpected ] '
Endif
arrayLevel = m.arrayLevel-1
If m.arrayLevel = 0
arrayName = ''
rowpos = 0
colpos = 0
expecting = Iif(oStack.isObject(),',}','')
expectingPropertyName = .T.
expectingValue = .F.
Else
If m.bidim
rowpos = m.rowpos+1
colpos = 0
expecting = ',]['
Else
expecting = ',]'
Endif
expectingValue = .T.
expectingPropertyName = .F.
Endif
*-------------------------------------
Procedure closeObject
*-------------------------------------
If oStack.Pop() # 'O'
Error 'unexpected }'
Endif
If m.arrayLevel = 0
expecting = ',}'
expectingValue = .F.
expectingPropertyName = .T.
objectOpen = .F.
Else
expecting = ',]'
expectingValue = .T.
expectingPropertyName = .F.
Endif
*----------------------------------------------
Function reviveCollection( o )
*----------------------------------------------
Private All
oConv = Createobject('empty')
nProp = Amembers(elem,m.o,0,'U')
For x = 1 To m.nProp
estaVar = m.elem(x)
esArray = .F.
esColeccion = Type('m.o.'+m.estaVar) = 'O' And Right( m.estaVar , 14 ) $ '_KV_COLLECTION,_KL_COLLECTION' And Type( 'm.o.'+m.estaVar+'.collectionitems',1) = 'A'
Do Case
Case m.esColeccion
estaProp = Createobject('collection')
tv = m.o.&estaVar
m.keyValColl = Right( m.estaVar , 14 ) = '_KV_COLLECTION'
For T = 1 To Alen(m.tv.collectionItems)
If m.keyValColl
esteval = m.tv.collectionItems(m.T).Value
Else
esteval = m.tv.collectionItems(m.T)
ENDIF
IF VARTYPE(m.esteval) = 'C' AND m.esteval = emptyarrayflag
loop
ENDIF
If Vartype(m.esteval) = 'O' Or Type('esteVal',1) = 'A'
esteval = reviveCollection(m.esteval)
Endif
If m.keyValColl
estaProp.Add(esteval,m.tv.collectionItems(m.T).Key)
Else
estaProp.Add(m.esteval)
Endif
Endfor
Case Type('m.o.'+m.estaVar,1) = 'A'
esArray = .T.
For T = 1 To Alen(m.o.&estaVar)
Dimension &estaVar(m.T)
If Type('m.o.&estaVar(m.T)') = 'O'
&estaVar(m.T) = reviveCollection(m.o.&estaVar(m.T))
Else
&estaVar(m.T) = m.o.&estaVar(m.T)
Endif
Endfor
Case Type('m.o.'+estaVar) = 'O'
estaProp = reviveCollection(m.o.&estaVar)
Otherwise
estaProp = m.o.&estaVar
Endcase
estaVar = Strtran( m.estaVar,'_KV_COLLECTION', '' )
estaVar = Strtran( m.estaVar, '_KL_COLLECTION', '' )
Do Case
Case m.esColeccion
AddProperty(m.oConv,m.estaVar,m.estaProp)
Case m.esArray
AddProperty(m.oConv,m.estaVar+'(1)')
Acopy(&estaVar,m.oConv.&estaVar)
Otherwise
AddProperty(m.oConv,m.estaVar,m.estaProp)
Endcase
Endfor
Try
retCollection = m.oConv.Collection.BaseClass = 'Collection'
Catch
retCollection = .F.
Endtry
If m.retCollection
Return m.oConv.Collection
Else
Return m.oConv
Endif
*----------------------------------
Function isJsonDt( cstr )
*----------------------------------
Return Iif( Len(m.cstr) = 19 ;
AND Len(Chrtran(m.cstr,'01234567890:T-','')) = 0 ;
and Substr(m.cstr,5,1) = '-' ;
and Substr(m.cstr,8,1) = '-' ;
and Substr(m.cstr,11,1) = 'T' ;
and Substr(m.cstr,14,1) = ':' ;
and Substr(m.cstr,17,1) = ':' ;
and Occurs('T',m.cstr) = 1 ;
and Occurs('-',m.cstr) = 2 ;
and Occurs(':',m.cstr) = 2 ,.T.,.F. )
*-----------------------------------
Procedure jsonDateToDT( cJsonDate )
*-----------------------------------
Return Eval("{^"+m.cJsonDate+"}")
******************************************
Define Class Stack As Collection
******************************************
*---------------------------
Function pushObject()
*---------------------------
This.Add('O')
*---------------------------
Function pushArray()
*---------------------------
This.Add('A')
*--------------------------------------
Function isObject()
*--------------------------------------
If This.Count > 0
Return This.Item( This.Count ) = 'O'
Else
Return .F.
Endif
*--------------------------------------
Function isArray()
*--------------------------------------
If This.Count > 0
Return This.Item( This.Count ) = 'A'
Else
Return .F.
Endif
*----------------------------
Function Pop()
*----------------------------
cret = This.Item( This.Count )
This.Remove( This.Count )
Return m.cret
******************************************
Enddefine
******************************************

Binary file not shown.

Binary file not shown.

1296
legacy-vfp/rar-forms.prg Normal file

File diff suppressed because it is too large Load Diff

271
legacy-vfp/rar_advanced.prg Normal file
View File

@@ -0,0 +1,271 @@
* Adaugam controale noi in clasa RarAutoPassForm pentru tab-ul Log
* Form pentru cautare avansata
DEFINE CLASS SearchLogForm AS Form
Caption = "Cautare avansata in log"
Width = 600
Height = 400
AutoCenter = .T.
MaxButton = .F.
BorderStyle = 2
ADD OBJECT lblDateFrom AS Label WITH ;
Caption = "De la data:", ;
Left = 20, ;
Top = 20
ADD OBJECT txtDateFrom AS TextBox WITH ;
Left = 100, ;
Top = 20, ;
Width = 100, ;
Value = DATE() - 30
ADD OBJECT lblDateTo AS Label WITH ;
Caption = "Pana la:", ;
Left = 220, ;
Top = 20
ADD OBJECT txtDateTo AS TextBox WITH ;
Left = 280, ;
Top = 20, ;
Width = 100, ;
Value = DATE()
ADD OBJECT lblVin AS Label WITH ;
Caption = "VIN:", ;
Left = 20, ;
Top = 60
ADD OBJECT txtVin AS TextBox WITH ;
Left = 100, ;
Top = 60, ;
Width = 150
ADD OBJECT lblComanda AS Label WITH ;
Caption = "Nr. Comanda:", ;
Left = 270, ;
Top = 60
ADD OBJECT txtComanda AS TextBox WITH ;
Left = 350, ;
Top = 60, ;
Width = 100
ADD OBJECT lblStatus AS Label WITH ;
Caption = "Status:", ;
Left = 20, ;
Top = 100
ADD OBJECT cboStatus AS ComboBox WITH ;
Left = 100, ;
Top = 100, ;
Width = 150, ;
Style = 2
ADD OBJECT chkHasError AS Checkbox WITH ;
Caption = "Doar cu erori", ;
Left = 270, ;
Top = 100
ADD OBJECT btnSearch AS CommandButton WITH ;
Caption = "Caută", ;
Left = 20, ;
Top = 140, ;
Width = 100, ;
Height = 30
ADD OBJECT btnCancel AS CommandButton WITH ;
Caption = "Anulează", ;
Left = 130, ;
Top = 140, ;
Width = 100, ;
Height = 30
* Constructor
FUNCTION Init
THIS.cboStatus.AddItem("Toate")
THIS.cboStatus.AddItem("SUCCESS")
THIS.cboStatus.AddItem("ERROR")
THIS.cboStatus.ListIndex = 1
RETURN .T.
* Handler pentru butonul Cauta
FUNCTION btnSearch.Click
LOCAL lcFilter
lcFilter = THIS.BuildFilter()
THISFORM.Parent.ApplyLogFilter(lcFilter)
THISFORM.Release()
* Handler pentru butonul Anuleaza
FUNCTION btnCancel.Click
THISFORM.Release()
* Construieste filtrul SQL
FUNCTION BuildFilter
LOCAL lcFilter, lcAnd
lcFilter = ""
lcAnd = ""
* Filtru data
IF !EMPTY(THIS.txtDateFrom.Value)
lcFilter = lcFilter + "data_prezentare >= CTOD('" + ;
DTOC(THIS.txtDateFrom.Value) + "')"
lcAnd = " AND "
ENDIF
IF !EMPTY(THIS.txtDateTo.Value)
lcFilter = lcFilter + lcAnd + "data_prezentare <= CTOD('" + ;
DTOC(THIS.txtDateTo.Value) + "')"
lcAnd = " AND "
ENDIF
* Filtru VIN
IF !EMPTY(THIS.txtVin.Value)
lcFilter = lcFilter + lcAnd + "UPPER(vin) LIKE '" + ;
UPPER(ALLTRIM(THIS.txtVin.Value)) + "%'"
lcAnd = " AND "
ENDIF
* Filtru comanda
IF !EMPTY(THIS.txtComanda.Value)
lcFilter = lcFilter + lcAnd + "UPPER(nr_comanda) LIKE '" + ;
UPPER(ALLTRIM(THIS.txtComanda.Value)) + "%'"
lcAnd = " AND "
ENDIF
* Filtru status
IF THIS.cboStatus.ListIndex > 1
lcFilter = lcFilter + lcAnd + "status = '" + ;
THIS.cboStatus.Value + "'"
lcAnd = " AND "
ENDIF
* Filtru erori
IF THIS.chkHasError.Value
lcFilter = lcFilter + lcAnd + "!EMPTY(error_msg)"
ENDIF
RETURN lcFilter
ENDDEFINE
* Adaugam metodele noi in RarAutoPassForm
* In functia Init, adaugam butoanele noi:
ADD OBJECT btnAdvSearch AS CommandButton OF tabLog WITH ;
Caption = "Căutare avansată", ;
Left = 320, ;
Top = 20, ;
Width = 120, ;
Height = C_BTN_HEIGHT
ADD OBJECT btnExportExcel AS CommandButton OF tabLog WITH ;
Caption = "Export Excel", ;
Left = 450, ;
Top = 20, ;
Width = 120, ;
Height = C_BTN_HEIGHT
* Handler pentru cautare avansata
FUNCTION btnAdvSearch.Click
LOCAL loSearch
loSearch = CREATEOBJECT("SearchLogForm")
loSearch.Show(1)
ENDFUNC
* Aplicare filtru de cautare
FUNCTION ApplyLogFilter
PARAMETERS tcFilter
SELECT rar_log
IF !EMPTY(tcFilter)
SET FILTER TO &tcFilter
ELSE
SET FILTER TO
ENDIF
GO TOP
THIS.grdLog.Refresh()
ENDFUNC
* Handler pentru export Excel
FUNCTION btnExportExcel.Click
LOCAL lcFile, loExcel, loWorkbook, loWorksheet
LOCAL lnRow, lnCol, lcValue
* Alegem locatia fisierului
lcFile = PUTFILE("Excel files|*.xlsx", "RAR_Log_Export.xlsx", "", 0)
IF EMPTY(lcFile)
RETURN
ENDIF
THIS.AddStatus("Export Excel în " + lcFile + "...")
TRY
* Cream obiectul Excel
loExcel = CREATEOBJECT("Excel.Application")
loExcel.Visible = .F.
* Adaugam un workbook nou
loWorkbook = loExcel.Workbooks.Add()
loWorksheet = loWorkbook.Sheets(1)
* Setam headerele
WITH loWorksheet
.Cells(1,1).Value = "Data prezentare"
.Cells(1,2).Value = "Nr. comandă"
.Cells(1,3).Value = "VIN"
.Cells(1,4).Value = "Nr. înmatriculare"
.Cells(1,5).Value = "Km final"
.Cells(1,6).Value = "Km initial"
.Cells(1,7).Value = "Status"
.Cells(1,8).Value = "Eroare"
.Cells(1,9).Value = "Data trimitere"
* Formatare header
.Range(.Cells(1,1), .Cells(1,9)).Font.Bold = .T.
.Range(.Cells(1,1), .Cells(1,9)).Interior.Color = RGB(200,200,200)
ENDWITH
* Populam datele
SELECT rar_log
lnRow = 2
SCAN
loWorksheet.Cells(lnRow, 1).Value = data_prezentare
loWorksheet.Cells(lnRow, 2).Value = nr_comanda
loWorksheet.Cells(lnRow, 3).Value = vin
loWorksheet.Cells(lnRow, 4).Value = nr_inm
loWorksheet.Cells(lnRow, 5).Value = km_final
loWorksheet.Cells(lnRow, 6).Value = km_initial
loWorksheet.Cells(lnRow, 7).Value = status
loWorksheet.Cells(lnRow, 8).Value = error_msg
loWorksheet.Cells(lnRow, 9).Value = data_trimitere
* Coloram randurile cu erori in rosu deschis
IF status = "ERROR"
loWorksheet.Range(loWorksheet.Cells(lnRow,1), ;
loWorksheet.Cells(lnRow,9)).Interior.Color = RGB(255,200,200)
ENDIF
lnRow = lnRow + 1
ENDSCAN
* Auto-fit coloane
loWorksheet.Range("A:I").Columns.AutoFit()
* Salvam si inchidem
loWorkbook.SaveAs(lcFile)
loWorkbook.Close()
loExcel.Quit()
THIS.AddStatus("Export Excel finalizat cu succes")
* Deschidem fisierul
RUN /N "explorer.exe" &lcFile
CATCH TO loError
THIS.AddStatus("EROARE la export Excel: " + loError.Message)
TRY
loWorkbook.Close()
loExcel.Quit()
CATCH
ENDTRY
ENDTRY
ENDFUNC

View File

@@ -0,0 +1,55 @@
#DEFINE XML_PATH "C:\RAR\comenzi.xml"
#DEFINE LOG_PATH "C:\RAR\auto_log.txt"
PROCEDURE AutomateProcesare
LOCAL lcDate, llSuccess, llTestMode
llSuccess = .F.
llTestMode = .F. && Productie
lcDate = DTOC(DATE())
Try
* Export comenzi in XML
DO export_comenzi WITH XML_PATH, DATE()
* Procesare prin RAR AutoPass
loRar = CREATEOBJECT("RarAutoPass")
IF !loRar.SetCredentials(m.llTestMode) && .F. pentru productie
THIS.WriteLog("EROARE: " + loRar.ErrorMsg)
llSuccess = .F.
RETURN llSuccess
ENDIF
IF loRar.ProcessXMLComenzi(XML_PATH)
THIS.WriteLog("Procesare reu?ita pentru " + lcDate)
llSuccess = .T.
ELSE
THIS.WriteLog("EROARE: " + loRar.ErrorMsg)
llSuccess = .F.
ENDIF
Catch To loError
THIS.WriteLog("EROARE: " + loError.Message)
llSuccess = .F.
Endtry
Return llSuccess
PROCEDURE WriteLog
PARAMETERS tcMessage
LOCAL llSuccess
llSuccess = .F.
Try
STRTOFILE(;
TTOC(DATETIME()) + ": " + tcMessage + CHR(13) + CHR(10),;
LOG_PATH,;
1)
llSuccess = .T.
Catch To loError
? "Eroare scriere log: " + loError.Message
llSuccess = .F.
Endtry
Return llSuccess

BIN
legacy-vfp/rar_autopass.PJT Normal file

Binary file not shown.

BIN
legacy-vfp/rar_autopass.pjx Normal file

Binary file not shown.

611
legacy-vfp/rar_autopass.prg Normal file
View File

@@ -0,0 +1,611 @@
SET STEP ON
Test1()
Test2()
Procedure Test1
Local loRar As "RarAutoPass"
Local lcXMLComenzi, llTestMode
* Creare instanta
loRar = Createobject("RarAutoPass")
* Setare credentiale - pentru test
llTestMode = .T.
loRar.SetCredentials(m.llTestMode)
* Actualizare nomenclator
loRar.UpdateNomenclator()
TEXT TO lcXMLComenzi NOSHOW
<?xml version="1.0" encoding="UTF-8"?>
<comenzi>
<comanda>
<nr_comanda>COM001</nr_comanda>
<data>2024-02-04</data>
<vin>VF1234567890</vin>
<nr_inmatriculare>B01AAA</nr_inmatriculare>
<km_final>150000</km_final>
<km_initial>0</km_initial>
<observatii>Test prezentare</observatii>
<operatii>
<operatie>
<cod_operatie>SCHIMB_VITEZOMETRU</cod_operatie>
<denumire>Schimbare vitezometru</denumire>
</operatie>
<operatie>
<cod_operatie>REPARATIE_BORD</cod_operatie>
<denumire>Reparatie instrumente bord</denumire>
</operatie>
</operatii>
</comanda>
<comanda>
<!-- ... alte comenzi ... -->
</comanda>
</comenzi>
ENDTEXT
* Procesare fisier XML cu comenzi
If !loRar.ProcessXMLComenzi("comenzi.xml")
? "Eroare: " + loRar.ErrorMsg
Endif
Endproc && Test1
***********************************
Procedure Test2
Local loRar As "RarAutoPass"
Local llTestMode
* Creare instanta si setare mediu
loRar = Createobject("RarAutoPass")
* Pentru test
llTestMode = .T.
loRar.SetCredentials(m.llTestMode)
* SAU pentru productie
* loRar.SetCredentials("email@service.ro", "parola", .F.)
* Actualizare nomenclator (fortat)
If !loRar.UpdateNomenclator(.T.)
? "Eroare actualizare nomenclator: " + loRar.ErrorMsg
Return
Endif
* Adaugare mapari operatii
Use mapare_prestatii
Append Blank
Replace cod_op_service With "SCHIMB_VITEZOMETRU", ;
descr_op_service With "Schimbare vitezometru/instrumente bord", ;
cod_prestatie_rar With "OE-1", ;
auto_send With .T., ;
data_actualizare With Date()
* Procesare comenzi din XML
If !loRar.ProcessXMLComenzi("comenzi.xml")
? "Eroare procesare comenzi: " + loRar.ErrorMsg
* Verificam log-ul pentru detalii
Select rar_log
Browse
Endif
* Sau trimitere prezentare individuala
If !loRar.SendPrezentare(;
"2024-02-04", ; && Data prestatie
"B01AAA", ; && Nr inmatriculare
"VF1234567890", ; && VIN
150000, ; && Km final
0, ; && Km initial
"Test", ; && Observatii
"", ; && Imagine base64
'[{"codPrestatie":"OE-1"}]', ; && Prestatii JSON
"COM001") && Nr comanda pentru logging
? "Eroare trimitere prezentare: " + loRar.ErrorMsg
Endif
Endproc && Test2
* Clasa pentru integrarea cu RAR AutoPass
#DEFINE C_API_TIMEOUT 30
#DEFINE C_TEST_URL "https://apps.rarom.ro/test-rar-autopass"
#DEFINE C_PROD_URL "https://apps.rarom.ro/rar-autopass"
* Clasa pentru integrarea cu RAR AutoPass
DEFINE CLASS RarAutoPass AS Custom
* Proprietati private
lcUrl = ""
lcEmail = ""
lcPassword = ""
lcToken = ""
lcError = ""
llTestMode = .T.
loXMLHTTP = null
* Proprietati publice
ErrorMsg = ""
LastResponse = ""
* Constructor
FUNCTION Init
THIS.lcUrl = ""
THIS.lcEmail = ""
THIS.lcPassword = ""
THIS.lcToken = ""
THIS.lcError = ""
THIS.llTestMode = .T.
THIS.loXMLHTTP = CREATEOBJECT("MSXML2.ServerXMLHTTP.6.0")
THIS.SetHttpTimeout()
* Cream tabelele necesare daca nu exista
THIS.InitializeStructure()
RETURN .T.
ENDFUNC
* Setare timeout pentru requesturi HTTP
FUNCTION SetHttpTimeout
LOCAL llSuccess
llSuccess = .F.
TRY
THIS.loXMLHTTP.setTimeouts(C_API_TIMEOUT*1000, ; && ResolveTimeout
C_API_TIMEOUT*1000, ; && ConnectTimeout
C_API_TIMEOUT*1000, ; && SendTimeout
C_API_TIMEOUT*1000) && ReceiveTimeout
llSuccess = .T.
CATCH TO loError
THIS.ErrorMsg = "Eroare setare timeout: " + loError.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Setare credentiale
FUNCTION SetCredentials
PARAMETERS tlTestMode
LOCAL llSuccess
llSuccess = .F.
TRY
* Setam modul de lucru (test/productie)
THIS.llTestMode = tlTestMode
* Setam URL-ul corespunzator
THIS.lcUrl = IIF(THIS.llTestMode, C_TEST_URL, C_PROD_URL)
* Citim credentialele din fisierul de setari
llSuccess = THIS.ReadSettings(tlTestMode)
CATCH TO loEx
THIS.ErrorMsg = "Eroare setare credentiale: " + loEx.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Initializare structura tabele
FUNCTION InitializeStructure
LOCAL llSuccess
llSuccess = .T.
TRY
IF !FILE("prestatii_rar.dbf")
CREATE TABLE prestatii_rar FREE (;
cod_prest C(10), ; && cod_prestatie
nume_prest C(250), ; && nume_prestatie
data_act D) && data_actualizare
INDEX ON cod_prest TAG cod_prest
USE IN SELECT('prestatii_rar')
ENDIF
IF !FILE("mapare_prestatii.dbf")
CREATE TABLE mapare_prestatii FREE (;
cod_op C(20), ; && cod_op_service
descr_op M, ; && descr_op_service
cod_rar C(10), ; && cod_prestatie_rar
auto_send L, ; && auto_send
data_act D) && data_actualizare
INDEX ON cod_op TAG cod_op
USE IN SELECT('mapare_prestatii')
ENDIF
IF !FILE("rar_log.dbf")
CREATE TABLE rar_log FREE (;
id I AUTOINC, ;
data_prez D, ; && data_prezentare
nr_comanda C(20), ;
vin C(20), ;
nr_inm C(10), ;
km_final N(10), ;
km_init N(10), ; && km_initial
prestatii M, ;
status C(20), ;
error_msg M, ;
data_trim T) && data_trimitere
USE IN SELECT('rar_log')
ENDIF
CATCH TO loEx
THIS.ErrorMsg = "Eroare initializare structura: " + loEx.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Login si obtinere token
FUNCTION Login
LOCAL lcJsonLogin, llSuccess
llSuccess = .F.
lcJsonLogin = '{"email":"' + THIS.lcEmail + '","password":"' + THIS.lcPassword + '"}'
TRY
THIS.loXMLHTTP.Open("POST", THIS.lcUrl + "/public/login", .F.)
THIS.loXMLHTTP.setRequestHeader("Content-Type", "application/json")
THIS.loXMLHTTP.Send(lcJsonLogin)
IF THIS.loXMLHTTP.Status != 200
THIS.ErrorMsg = "Eroare login: " + THIS.loXMLHTTP.responseText
llSuccess = .F.
RETURN llSuccess
ENDIF
* Folosim nfjsonread pentru a parsa raspunsul
loResponse = nfjsonread(THIS.loXMLHTTP.responseText)
IF TYPE('loResponse') == 'O' AND !ISNULL(loResponse)
THIS.lcToken = loResponse.token
IF EMPTY(THIS.lcToken)
THIS.ErrorMsg = "Nu s-a putut obtine token-ul"
llSuccess = .F.
ELSE
llSuccess = .T.
ENDIF
ELSE
THIS.ErrorMsg = "Eroare parsare raspuns JSON"
llSuccess = .F.
ENDIF
CATCH TO loEx
THIS.ErrorMsg = "Eroare login: " + loEx.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Actualizare nomenclator presta?ii
FUNCTION UpdateNomenclator
LPARAMETERS tlForceRefresh
LOCAL llSuccess
llSuccess = .F.
IF !tlForceRefresh AND FILE("prestatii_rar.dbf")
llSuccess = .T.
RETURN llSuccess
ENDIF
IF !THIS.Login()
RETURN .F.
ENDIF
TRY
THIS.loXMLHTTP.Open("GET", THIS.lcUrl + "/nomenclator/getNomenclatorPrestatii", .F.)
THIS.loXMLHTTP.setRequestHeader("Authorization", "Bearer " + THIS.lcToken)
THIS.loXMLHTTP.Send()
IF THIS.loXMLHTTP.Status != 200
THIS.ErrorMsg = "Eroare obtinere nomenclator: " + THIS.loXMLHTTP.responseText
llSuccess = .F.
RETURN llSuccess
ENDIF
* Folosim nfjsonread pentru a parsa raspunsul
loJson = nfjsonread(THIS.loXMLHTTP.responseText)
IF TYPE('loJson') == 'O' AND !ISNULL(loJson) AND TYPE('loJson.data') == 'O'
* Deschidem tabelul prestatii_rar
IF !USED("prestatii_rar")
USE prestatii_rar IN 0
ENDIF
SELECT prestatii_rar
* Procesam fiecare prestatie
FOR EACH loItem IN loJson.data
* Cautam prestatia dupa cod
LOCATE FOR cod_prest = loItem.codPrestatie
IF FOUND()
* Update daca exista ?i s-a modificat numele
IF nume_prest != loItem.numePrestatie
REPLACE ;
nume_prest WITH loItem.numePrestatie, ;
data_act WITH DATE()
ENDIF
ELSE
* Insert daca nu exista
INSERT INTO prestatii_rar (;
cod_prest, ;
nume_prest, ;
data_act) ;
VALUES (;
loItem.codPrestatie, ;
loItem.numePrestatie, ;
DATE())
ENDIF
ENDFOR
llSuccess = .T.
ELSE
THIS.ErrorMsg = "Eroare parsare raspuns JSON pentru nomenclator"
llSuccess = .F.
ENDIF
CATCH TO loEx
THIS.ErrorMsg = "Eroare actualizare nomenclator: " + loEx.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Trimitere prezentare individuala
FUNCTION SendPrezentare
LPARAMETERS tcDataPrest, tcNrInm, tcVin, tnKmFinal, tnKmInitial, ;
tcObs, tcImagineB64, tcPrestatii, tcNrComanda
LOCAL llSuccess, lcJson
llSuccess = .F.
IF !THIS.Login()
RETURN .F.
ENDIF
* Construim JSON-ul pentru prezentare
TEXT TO lcJson NOSHOW TEXTMERGE
{
"dataPrestatie": "<<tcDataPrest>>",
"nrInmatriculare": "<<tcNrInm>>",
"vin": "<<tcVin>>",
"odometruFinal": <<tnKmFinal>>,
"odometruInitial": <<IIF(EMPTY(tnKmInitial), "null", tnKmInitial)>>,
"obs": "<<tcObs>>",
"b64Image": "<<tcImagineB64>>",
"status": "FINALIZATA",
"prestatii": <<tcPrestatii>>
}
ENDTEXT
TRY
THIS.loXMLHTTP.Open("POST", THIS.lcUrl + "/prezentari/postPrezentare", .F.)
THIS.loXMLHTTP.setRequestHeader("Content-Type", "application/json")
THIS.loXMLHTTP.setRequestHeader("Authorization", "Bearer " + THIS.lcToken)
THIS.loXMLHTTP.Send(lcJson)
THIS.LastResponse = THIS.loXMLHTTP.responseText
IF THIS.loXMLHTTP.Status != 200
THIS.ErrorMsg = "Eroare trimitere prezentare: " + THIS.LastResponse
THIS.LogPrezentare(tcDataPrest, tcNrComanda, tcVin, tcNrInm, ;
tnKmFinal, tnKmInitial, tcPrestatii, "ERROR", THIS.ErrorMsg)
llSuccess = .F.
ELSE
THIS.LogPrezentare(tcDataPrest, tcNrComanda, tcVin, tcNrInm, ;
tnKmFinal, tnKmInitial, tcPrestatii, "SUCCESS")
llSuccess = .T.
ENDIF
CATCH TO loEx
THIS.ErrorMsg = "Eroare trimitere prezentare: " + loEx.Message
THIS.LogPrezentare(tcDataPrest, tcNrComanda, tcVin, tcNrInm, ;
tnKmFinal, tnKmInitial, tcPrestatii, "ERROR", THIS.ErrorMsg)
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Logging prezentari
FUNCTION LogPrezentare
LPARAMETERS tcDataPrest, tcNrComanda, tcVin, tcNrInm, tnKmFinal, ;
tnKmInitial, tcPrestatii, tcStatus, tcErrorMsg
LOCAL llSuccess
llSuccess = .F.
TRY
IF !USED("rar_log")
USE rar_log IN 0
ENDIF
INSERT INTO rar_log (;
data_prez, ;
nr_comanda, ;
vin, ;
nr_inm, ;
km_final, ;
km_init, ;
prestatii, ;
status, ;
error_msg, ;
data_trim) ;
VALUES (;
CTOD(tcDataPrest), ;
tcNrComanda, ;
tcVin, ;
tcNrInm, ;
tnKmFinal, ;
tnKmInitial, ;
tcPrestatii, ;
tcStatus, ;
tcErrorMsg, ;
DATETIME())
llSuccess = .T.
CATCH TO loEx
THIS.ErrorMsg = "Eroare logging: " + loEx.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Procesare comenzi din XML
FUNCTION ProcessXMLComenzi
LPARAMETERS tcXMLFile
LOCAL loXML AS MSXML2.DOMDocument.6.0
LOCAL loNodes AS MSXML2.IXMLDOMNodeList
LOCAL loNode AS MSXML2.IXMLDOMNode
LOCAL lcPrestatii, llSuccess
llSuccess = .F.
TRY
loXML = CREATEOBJECT("MSXML2.DOMDocument.6.0")
loXML.async = .F.
IF !loXML.load(tcXMLFile)
THIS.ErrorMsg = "Eroare incarcare XML: " + loXML.parseError.reason
llSuccess = .F.
RETURN llSuccess
ENDIF
* Obtinem toate nodurile de comenzi
loNodes = loXML.selectNodes("/comenzi/comanda")
FOR EACH loNode IN loNodes
* Extragem datele din XML
lcNrComanda = loNode.selectSingleNode("nr_comanda").text
lcDataPrest = loNode.selectSingleNode("data").text
lcVin = loNode.selectSingleNode("vin").text
lcNrInm = loNode.selectSingleNode("nr_inmatriculare").text
lnKmFinal = VAL(loNode.selectSingleNode("km_final").text)
lnKmInitial = VAL(loNode.selectSingleNode("km_initial").text)
lcObs = NVL(loNode.selectSingleNode("observatii").text, "")
* Generam JSON cu prestatii din operatiile comenzii
lcPrestatii = THIS.GetPrestatiiFromXMLNode(loNode.selectNodes("operatii/operatie"))
* Trimitem prezentarea
IF !THIS.SendPrezentare(lcDataPrest, lcNrInm, lcVin, ;
lnKmFinal, lnKmInitial, lcObs, ;
"", lcPrestatii, lcNrComanda)
* Continuam cu urmatoarea comanda chiar daca una esueaza
* dar am logat deja eroarea in SendPrezentare
LOOP
ENDIF
ENDFOR
llSuccess = .T.
CATCH TO loEx
THIS.ErrorMsg = "Eroare procesare XML: " + loEx.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
* Generare JSON prestatii din noduri XML
FUNCTION GetPrestatiiFromXMLNode
LPARAMETERS loOperatiiNodes
LOCAL lcPrestatiiJson, lcCodRar
LOCAL loNode AS MSXML2.IXMLDOMNode
TEXT TO lcPrestatiiJson NOSHOW
[
ENDTEXT
lnCount = 0
FOR EACH loNode IN loOperatiiNodes
lcCodOperatie = loNode.selectSingleNode("cod_operatie").text
lcCodRar = THIS.GetCodRarPentruOperatie(lcCodOperatie)
IF !EMPTY(lcCodRar)
lcPrestatiiJson = lcPrestatiiJson + ;
IIF(lnCount > 0, ",", "") + ;
'{"codPrestatie":"' + lcCodRar + '","idPrezentare":null}'
lnCount = lnCount + 1
ENDIF
ENDFOR
lcPrestatiiJson = lcPrestatiiJson + "]"
RETURN lcPrestatiiJson
ENDFUNC
* Obtinere cod RAR pentru operatie service
FUNCTION GetCodRarPentruOperatie
LPARAMETERS tcCodOperatie
LOCAL lcCodRar
IF !USED("mapare_prestatii")
USE mapare_prestatii IN 0
ENDIF
SELECT mapare_prestatii
LOCATE FOR cod_op = tcCodOperatie
IF FOUND() AND auto_send
lcCodRar = cod_rar
ELSE
lcCodRar = ""
ENDIF
RETURN lcCodRar
ENDFUNC
* Functie pentru citirea credentialelor din settings.xml
FUNCTION ReadSettings
PARAMETERS tlTestMode
LOCAL loXML AS MSXML2.DOMDocument.6.0
LOCAL lcSettingsPath, lcEnvironment, loCredentials
LOCAL lcEmail, lcPassword, llSuccess
llSuccess = .F.
TRY
* Cream obiectul XML
loXML = CREATEOBJECT("MSXML2.DOMDocument.6.0")
loXML.async = .F.
* Determinam calea catre settings.xml
lcSettingsPath = ADDBS(JUSTPATH(SYS(16,0))) + "settings.xml"
* Verificam daca exista fisierul
IF !FILE(lcSettingsPath)
THIS.ErrorMsg = "Fisierul settings.xml nu exista in: " + lcSettingsPath
llSuccess = .F.
RETURN llSuccess
ENDIF
* Incarcam XML-ul
IF !loXML.load(lcSettingsPath)
THIS.ErrorMsg = "Eroare incarcare settings.xml: " + loXML.parseError.reason
llSuccess = .F.
RETURN llSuccess
ENDIF
* Determinam mediul (test/productie)
lcEnvironment = IIF(tlTestMode, "test", "production")
* Selectam credentialele pentru mediul dorit
loCredentials = loXML.selectSingleNode("/settings/" + lcEnvironment + "/credentials")
IF !ISNULL(loCredentials)
lcEmail = loCredentials.selectSingleNode("email").text
lcPassword = loCredentials.selectSingleNode("password").text
* Setam credentialele
THIS.lcEmail = lcEmail
THIS.lcPassword = lcPassword
llSuccess = .T.
ELSE
THIS.ErrorMsg = "Nu s-au gasit credentiale pentru mediul: " + lcEnvironment
llSuccess = .F.
ENDIF
CATCH TO loEx
THIS.ErrorMsg = "Eroare citire setari: " + loEx.Message
llSuccess = .F.
ENDTRY
RETURN llSuccess
ENDFUNC
ENDDEFINE

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<comenzi>
<comanda>
<nr_comanda>TEST001</nr_comanda>
<data>2024-02-05</data>
<vin>WBA1234567890</vin>
<nr_inmatriculare>B101TEST</nr_inmatriculare>
<km_final>125000</km_final>
<km_initial>0</km_initial>
<observatii>Test prezentare service</observatii>
<operatii>
<operatie>
<cod_operatie>OE-1</cod_operatie>
<denumire>Schimbare instrumente bord</denumire>
</operatie>
<operatie>
<cod_operatie>OE-2</cod_operatie>
<denumire>Reparatie instrumente bord</denumire>
</operatie>
</operatii>
</comanda>
<comanda>
<nr_comanda>TEST002</nr_comanda>
<data>2024-02-05</data>
<vin>WDC9876543210</vin>
<nr_inmatriculare>B202TEST</nr_inmatriculare>
<km_final>89750</km_final>
<km_initial>89500</km_initial>
<observatii>Reparatie kilometraj electronic</observatii>
<operatii>
<operatie>
<cod_operatie>OE-1</cod_operatie>
<denumire>Schimbare instrumente bord</denumire>
</operatie>
</operatii>
</comanda>
<comanda>
<nr_comanda>TEST003</nr_comanda>
<data>2024-02-05</data>
<vin>VSSZZZ1234567</vin>
<nr_inmatriculare>B303TEST</nr_inmatriculare>
<km_final>45000</km_final>
<km_initial>0</km_initial>
<observatii>Service general</observatii>
<operatii>
<operatie>
<cod_operatie>OE-2</cod_operatie>
<denumire>Reparatie instrumente bord</denumire>
</operatie>
<operatie>
<cod_operatie>OE-1</cod_operatie>
<denumire>Schimbare instrumente bord</denumire>
</operatie>
</operatii>
</comanda>
</comenzi>