Compare commits
31 Commits
fc1af63014
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 13b4f65723 | |||
| c5b0ce3a25 | |||
| f88b2b9a5b | |||
| 8df728cf8b | |||
| 0684485107 | |||
| be37c2c99c | |||
| 837b455687 | |||
| e21512240f | |||
| 8421d7ba7f | |||
| ec51097277 | |||
| 117f2fb88a | |||
| c6216e006e | |||
| d0c2af8a31 | |||
| 8fa842888a | |||
| 89695721f4 | |||
| c599a9c053 | |||
| b35e62c880 | |||
| 54d97c0349 | |||
| 4d1179f8e5 | |||
| bd09073229 | |||
| 26d2c205c9 | |||
| 4666262c92 | |||
| 72bf63cd04 | |||
| 05d91a05c6 | |||
| 5f944e8bfa | |||
| 1d3e75803f | |||
| f4b48d9c20 | |||
| d350119993 | |||
| 48f15c1da1 | |||
| 5f3a17c5c7 | |||
| a290a51276 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -118,6 +118,9 @@ utile/hpdf/hpdferr.FPT
|
||||
# --- SVN (COMUN este si working copy SVN) ---
|
||||
.svn/
|
||||
|
||||
# --- notite neversionate in git (credentiale) - raman doar in SVN ---
|
||||
docs/local/
|
||||
|
||||
# --- Windows / stare locala ---
|
||||
*.lnk
|
||||
Thumbs.db
|
||||
@@ -130,3 +133,5 @@ bash.exe.stackdump
|
||||
utile/Teste/**/screenshots*/
|
||||
utile/Teste/**/uisync*/
|
||||
utile/Teste/**/*_log.txt
|
||||
utile/Teste/**/watchdog_out/
|
||||
utile/Teste/**/*_dialog*.png
|
||||
|
||||
@@ -609,12 +609,12 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
BackStyle = 1, ;
|
||||
Caption = "Trimise (cu diferente Reg. Vz.)", ;
|
||||
Height = 25, ;
|
||||
Left = 522, ;
|
||||
Left = 687, ;
|
||||
Name = "chkDiferente", ;
|
||||
Style = 0, ;
|
||||
Top = 151, ;
|
||||
Value = .F., ;
|
||||
Width = 197
|
||||
Width = 238
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'pgfeFactura.Page1.chkErori' AS _checkbox WITH ;
|
||||
@@ -625,12 +625,12 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
BackStyle = 1, ;
|
||||
Caption = "Trimise (cu raspuns Erori)", ;
|
||||
Height = 25, ;
|
||||
Left = 346, ;
|
||||
Left = 470, ;
|
||||
Name = "chkErori", ;
|
||||
Style = 0, ;
|
||||
Top = 151, ;
|
||||
Value = .F., ;
|
||||
Width = 170
|
||||
Width = 211
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'pgfeFactura.Page1.chkFortareRaspunsuri' AS _checkbox WITH ;
|
||||
@@ -655,12 +655,12 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
BackStyle = 1, ;
|
||||
Caption = "Netrimise", ;
|
||||
Height = 25, ;
|
||||
Left = 112, ;
|
||||
Left = 154, ;
|
||||
Name = "chkNetrimise", ;
|
||||
Style = 0, ;
|
||||
Top = 151, ;
|
||||
Value = .F., ;
|
||||
Width = 79
|
||||
Width = 117
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'pgfeFactura.Page1.chkPersFizice' AS _checkbox WITH ;
|
||||
@@ -690,7 +690,7 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
Style = 0, ;
|
||||
Top = 151, ;
|
||||
Value = .F., ;
|
||||
Width = 98
|
||||
Width = 141
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'pgfeFactura.Page1.chkTrimis' AS _checkbox WITH ;
|
||||
@@ -716,12 +716,12 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
BackStyle = 1, ;
|
||||
Caption = "Trimise (fara raspuns)", ;
|
||||
Height = 25, ;
|
||||
Left = 195, ;
|
||||
Left = 277, ;
|
||||
Name = "chkTrimise", ;
|
||||
Style = 0, ;
|
||||
Top = 151, ;
|
||||
Value = .F., ;
|
||||
Width = 147
|
||||
Width = 187
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'pgfeFactura.Page1.chkValidareOnline' AS _checkbox WITH ;
|
||||
@@ -5363,7 +5363,7 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
PROCEDURE do_cauta
|
||||
LOCAL lcfiltru, lcFiltru2, lcFiltru3, lcval1, lcColoana, ldData1, ldData2
|
||||
Local lcData1, lcData2, llErori, llNetrimise, llPJ, llTrimise, llDiferente, lnActivePage, lcCond, lcDif2, lcDif3, lcLipsa
|
||||
Local lcData1, lcData2, llErori, llNetrimise, llPJ, llTrimise, llDiferente, lnActivePage, lcCond, lcDif1, lcDif2, lcDif3, lcLipsa, lcFiltruBaza1, lcFiltruBaza2, lcFiltruBaza3, lcPJ, lcNetrimise, lcTrimise, lcErori
|
||||
|
||||
WAIT WINDOW 'Selectie inregistrari...' NOWAIT
|
||||
|
||||
@@ -5411,19 +5411,25 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
lcFiltru3 = m.lcFiltru3 + " and (" + ALLTRIM(THISFORM.filtru_pretty) + ")"
|
||||
ENDIF
|
||||
|
||||
* Filtrul de baza (fara bifele paginii 1), pentru numarul independent din caption (NumaraDiferente)
|
||||
lcFiltruBaza1 = m.lcFiltru
|
||||
|
||||
lcPJ = [(tip_persoana=1)]
|
||||
lcNetrimise = [(NVL(trimis,0) = 0)]
|
||||
lcTrimise = [(trimis = 1 and data_raspuns IS NULL)]
|
||||
lcErori = [(trimis = 1 and tip_mesaj_raspuns = 'ERORI FACTURA')]
|
||||
|
||||
IF m.llPJ
|
||||
lcFiltru = m.lcfiltru + " and (tip_persoana=1)"
|
||||
lcFiltru = m.lcfiltru + " and " + m.lcPJ
|
||||
ENDIF
|
||||
|
||||
IF m.llDiferente
|
||||
lcFiltru = m.lcFiltru + " and (jtotctva is null or ABS(decode(creditnote,0,1,-1) * ROUND(NVL(xtotal_cu_tva , 0.00) * decode(in_valuta,1,curs,1), 2)-NVL(jtotctva, 0.00)) > 0.15)"
|
||||
ENDIF
|
||||
|
||||
* Bifele Diferente / Lipsa din registrul de TVA de pe paginile Primite si Trimise
|
||||
* Bifele Diferente / Lipsa din registrul de TVA, folosite si de NumaraDiferente pentru numarul din caption
|
||||
lcLipsa = [(jtotctva is null)]
|
||||
lcDif1 = [(jtotctva is null or ABS(decode(creditnote,0,1,-1) * ROUND(NVL(xtotal_cu_tva , 0.00) * decode(in_valuta,1,curs,1), 2)-NVL(jtotctva, 0.00)) > 0.15)]
|
||||
lcDif2 = [(jtotctva is not null and (NVL(nume_valuta,'RON') <> 'RON' or ABS(decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-(NVL(jtotctva, 0.00)-NVL(jtva_ti, 0.00))) > 0.15))]
|
||||
lcDif3 = [(jtotctva is not null and (NVL(nume_valuta,'RON') <> 'RON' or ABS(decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00)) > 0.15))]
|
||||
|
||||
lcFiltruBaza2 = m.lcFiltru2
|
||||
lcCond = []
|
||||
WITH this.pgfeFactura.page2
|
||||
IF .chkDiferente.Value
|
||||
@@ -5437,6 +5443,7 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
lcFiltru2 = m.lcFiltru2 + [ and (] + m.lcCond + [)]
|
||||
ENDIF
|
||||
|
||||
lcFiltruBaza3 = m.lcFiltru3
|
||||
lcCond = []
|
||||
WITH this.pgfeFactura.page3
|
||||
IF .chkDiferente.Value
|
||||
@@ -5455,14 +5462,18 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
IF m.llErori
|
||||
lcFiltru = m.lcfiltru + " and (NVL(trimis,0) = 0 or tip_mesaj_raspuns = 'ERORI FACTURA')"
|
||||
ELSE
|
||||
lcFiltru = m.lcfiltru + " and (NVL(trimis,0) = 0)"
|
||||
lcFiltru = m.lcfiltru + " and " + m.lcNetrimise
|
||||
ENDIF
|
||||
CASE m.llTrimise
|
||||
lcFiltru = m.lcfiltru + " and (trimis = 1 and data_raspuns IS NULL)"
|
||||
lcFiltru = m.lcfiltru + " and " + m.lcTrimise
|
||||
CASE m.llErori
|
||||
lcFiltru = m.lcfiltru + " and (trimis = 1 and tip_mesaj_raspuns = 'ERORI FACTURA')"
|
||||
lcFiltru = m.lcfiltru + " and " + m.lcErori
|
||||
ENDCASE
|
||||
|
||||
IF m.llDiferente
|
||||
lcFiltru = m.lcFiltru + " and (" + m.lcDif1 + ")"
|
||||
ENDIF
|
||||
|
||||
If Empty(m.lcFiltru)
|
||||
aMessagebox("Alegeti un criteriu!",0+48,"Atentie")
|
||||
Return
|
||||
@@ -5512,6 +5523,8 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
This.pgfeFactura.page2._grdfooter1.calctotal()
|
||||
This.pgfeFactura.page3._grdfooter1.calctotal()
|
||||
|
||||
This.NumaraDiferente(m.lcFiltruBaza1, m.lcFiltruBaza2, m.lcFiltruBaza3, m.lcDif1, m.lcDif2, m.lcDif3, m.lcLipsa, m.lcNetrimise, m.lcTrimise, m.lcErori, m.lcPJ)
|
||||
|
||||
WAIT CLEAR
|
||||
|
||||
Return m.lcFiltru
|
||||
@@ -6032,6 +6045,16 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
* Mesajul era trunchiat la 41 de caractere
|
||||
This.cMesajFurnizor = SPACE(200)
|
||||
|
||||
* Caption de baza pentru bifele Diferente/Lipsa, refolosit de NumaraDiferente/SeteazaCaptionDiferente
|
||||
This.pgfeFactura.page1.chkPJ.Tag = This.pgfeFactura.page1.chkPJ.Caption
|
||||
This.pgfeFactura.page1.chkNetrimise.Tag = This.pgfeFactura.page1.chkNetrimise.Caption
|
||||
This.pgfeFactura.page1.chkTrimise.Tag = This.pgfeFactura.page1.chkTrimise.Caption
|
||||
This.pgfeFactura.page1.chkErori.Tag = This.pgfeFactura.page1.chkErori.Caption
|
||||
This.pgfeFactura.page1.chkDiferente.Tag = This.pgfeFactura.page1.chkDiferente.Caption
|
||||
This.pgfeFactura.page2.chkDiferente.Tag = This.pgfeFactura.page2.chkDiferente.Caption
|
||||
This.pgfeFactura.page2.chkLipsaRegistru.Tag = This.pgfeFactura.page2.chkLipsaRegistru.Caption
|
||||
This.pgfeFactura.page3.chkDiferente.Tag = This.pgfeFactura.page3.chkDiferente.Caption
|
||||
This.pgfeFactura.page3.chkLipsaRegistru.Tag = This.pgfeFactura.page3.chkLipsaRegistru.Caption
|
||||
|
||||
DODEFAULT()
|
||||
ENDPROC
|
||||
@@ -6044,6 +6067,147 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
Thisform.oAnaf.AnafeFacturaServer.lTest = m.tlTest
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NumaraDiferente
|
||||
LPARAMETERS tcFiltruBaza1, tcFiltruBaza2, tcFiltruBaza3, tcDif1, tcDif2, tcDif3, tcLipsa, tcNetrimise, tcTrimise, tcErori, tcPJ
|
||||
LOCAL lnActivePage, lcView, lcFiltruBaza, lcDif, llLipsa, lcSql, llSucces, lnDif, lnLipsa, lnNetrimise, lnTrimise, lnErori, lnPJ, lcCursor, llFaraBife, lnSelect, lnRec
|
||||
lnActivePage = This.pgfeFactura.ActivePage
|
||||
lnDif = 0
|
||||
lnLipsa = 0
|
||||
|
||||
*!* fara nicio bifa, cursorul afisat e chiar setul de baza: numaram local, fara interogare
|
||||
DO CASE
|
||||
CASE m.lnActivePage = 1
|
||||
lcCursor = 'crsFacturiEmise'
|
||||
llFaraBife = EMPTY(This.pgfeFactura.page1.chkPJ.Value) AND EMPTY(This.pgfeFactura.page1.chkNetrimise.Value) ;
|
||||
AND EMPTY(This.pgfeFactura.page1.chkTrimise.Value) AND EMPTY(This.pgfeFactura.page1.chkErori.Value) ;
|
||||
AND EMPTY(This.pgfeFactura.page1.chkDiferente.Value)
|
||||
CASE m.lnActivePage = 2
|
||||
lcCursor = 'crsFacturiTrimise'
|
||||
llFaraBife = EMPTY(This.pgfeFactura.page3.chkDiferente.Value) AND EMPTY(This.pgfeFactura.page3.chkLipsaRegistru.Value)
|
||||
CASE m.lnActivePage = 3
|
||||
lcCursor = 'crsFacturiPrimite'
|
||||
llFaraBife = EMPTY(This.pgfeFactura.page2.chkDiferente.Value) AND EMPTY(This.pgfeFactura.page2.chkLipsaRegistru.Value)
|
||||
OTHERWISE
|
||||
RETURN
|
||||
ENDCASE
|
||||
|
||||
IF m.llFaraBife AND USED(m.lcCursor)
|
||||
lnSelect = SELECT()
|
||||
lnRec = RECNO(m.lcCursor)
|
||||
IF m.lnActivePage = 1
|
||||
SELECT SUM(IIF(NVL(tip_persoana,1) = 1, 1, 0)) as npj, ;
|
||||
SUM(IIF(NVL(trimis,0) = 0, 1, 0)) as nnetrimise, ;
|
||||
SUM(IIF(NVL(trimis,0) = 1 AND EMPTY(NVL(data_raspuns, {})), 1, 0)) as ntrimise, ;
|
||||
SUM(IIF(NVL(trimis,0) = 1 AND ALLTRIM(NVL(tip_mesaj_raspuns,'')) == 'ERORI FACTURA', 1, 0)) as nerori, ;
|
||||
SUM(IIF(ISNULL(jtotctva) OR ABS(NVL(diferenta,0)) > 0.15, 1, 0)) as ndif ;
|
||||
FROM crsFacturiEmise INTO CURSOR crsNumarBifeLocal NOFILTER
|
||||
lnPJ = NVL(crsNumarBifeLocal.npj,0)
|
||||
lnNetrimise = NVL(crsNumarBifeLocal.nnetrimise,0)
|
||||
lnTrimise = NVL(crsNumarBifeLocal.ntrimise,0)
|
||||
lnErori = NVL(crsNumarBifeLocal.nerori,0)
|
||||
lnDif = NVL(crsNumarBifeLocal.ndif,0)
|
||||
USE IN (SELECT('crsNumarBifeLocal'))
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkDiferente, m.lnDif)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkNetrimise, m.lnNetrimise)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkTrimise, m.lnTrimise)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkErori, m.lnErori)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkPJ, m.lnPJ)
|
||||
ELSE
|
||||
SELECT SUM(IIF(!ISNULL(jtotctva) AND (ALLTRIM(NVL(nume_valuta,'RON')) <> 'RON' OR ABS(NVL(diferenta,0)) > 0.15), 1, 0)) as ndif, ;
|
||||
SUM(IIF(ISNULL(jtotctva), 1, 0)) as nlipsa ;
|
||||
FROM (m.lcCursor) INTO CURSOR crsNumarBifeLocal NOFILTER
|
||||
lnDif = NVL(crsNumarBifeLocal.ndif,0)
|
||||
lnLipsa = NVL(crsNumarBifeLocal.nlipsa,0)
|
||||
USE IN (SELECT('crsNumarBifeLocal'))
|
||||
IF m.lnActivePage = 2
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page3.chkDiferente, m.lnDif)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page3.chkLipsaRegistru, m.lnLipsa)
|
||||
ELSE
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page2.chkDiferente, m.lnDif)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page2.chkLipsaRegistru, m.lnLipsa)
|
||||
ENDIF
|
||||
ENDIF
|
||||
SELECT (m.lcCursor)
|
||||
IF m.lnRec > 0 AND m.lnRec <= RECCOUNT()
|
||||
GO m.lnRec
|
||||
ENDIF
|
||||
SELECT (m.lnSelect)
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
* Pagina 1: fiecare bifa se numara independent pe filtrul de baza, indiferent de celelalte bife
|
||||
IF m.lnActivePage = 1
|
||||
lnNetrimise = 0
|
||||
lnTrimise = 0
|
||||
lnErori = 0
|
||||
lnPJ = 0
|
||||
|
||||
IF !EMPTY(NVL(m.tcFiltruBaza1,''))
|
||||
lcSql = "select count(case when " + m.tcDif1 + " then 1 end) as ndif" + ;
|
||||
", count(case when " + m.tcNetrimise + " then 1 end) as nnetrimise" + ;
|
||||
", count(case when " + m.tcTrimise + " then 1 end) as ntrimise" + ;
|
||||
", count(case when " + m.tcErori + " then 1 end) as nerori" + ;
|
||||
", count(case when " + m.tcPJ + " then 1 end) as npj" + ;
|
||||
" from anaf_vefactura_emis where 1=1 " + m.tcFiltruBaza1
|
||||
|
||||
llSucces = goExecutor.oExecuta(m.lcSql, 'crsNumarDiferente')
|
||||
IF m.llSucces
|
||||
lnDif = NVL(crsNumarDiferente.ndif,0)
|
||||
lnNetrimise = NVL(crsNumarDiferente.nnetrimise,0)
|
||||
lnTrimise = NVL(crsNumarDiferente.ntrimise,0)
|
||||
lnErori = NVL(crsNumarDiferente.nerori,0)
|
||||
lnPJ = NVL(crsNumarDiferente.npj,0)
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkDiferente, m.lnDif)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkNetrimise, m.lnNetrimise)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkTrimise, m.lnTrimise)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkErori, m.lnErori)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page1.chkPJ, m.lnPJ)
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
DO CASE
|
||||
CASE m.lnActivePage = 2
|
||||
lcView = 'anaf_vefactura_trimis'
|
||||
lcFiltruBaza = m.tcFiltruBaza3
|
||||
lcDif = m.tcDif3
|
||||
llLipsa = .T.
|
||||
CASE m.lnActivePage = 3
|
||||
lcView = 'anaf_vefactura_primit'
|
||||
lcFiltruBaza = m.tcFiltruBaza2
|
||||
lcDif = m.tcDif2
|
||||
llLipsa = .T.
|
||||
OTHERWISE
|
||||
RETURN
|
||||
ENDCASE
|
||||
|
||||
* Numarul se reseteaza pe 0 (caption fara paranteza) cand filtrul e gol sau interogarea esueaza
|
||||
IF !EMPTY(NVL(m.lcFiltruBaza,'')) AND !EMPTY(NVL(m.lcDif,''))
|
||||
lcSql = "select count(case when " + m.lcDif + " then 1 end) as ndif" + ;
|
||||
IIF(m.llLipsa, ", count(case when " + m.tcLipsa + " then 1 end) as nlipsa", "") + ;
|
||||
" from " + m.lcView + " where 1=1 " + m.lcFiltruBaza
|
||||
|
||||
llSucces = goExecutor.oExecuta(m.lcSql, 'crsNumarDiferente')
|
||||
IF m.llSucces
|
||||
lnDif = NVL(crsNumarDiferente.ndif,0)
|
||||
IF m.llLipsa
|
||||
lnLipsa = NVL(crsNumarDiferente.nlipsa,0)
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
DO CASE
|
||||
CASE m.lnActivePage = 2
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page3.chkDiferente, m.lnDif)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page3.chkLipsaRegistru, m.lnLipsa)
|
||||
CASE m.lnActivePage = 3
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page2.chkDiferente, m.lnDif)
|
||||
This.SeteazaCaptionDiferente(This.pgfeFactura.page2.chkLipsaRegistru, m.lnLipsa)
|
||||
ENDCASE
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE refreshdetaliifacturi
|
||||
Lparameters tcTip
|
||||
* tcTip: EMISE/TRIMISE/PRIMITE
|
||||
@@ -6119,6 +6283,13 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE SeteazaCaptionDiferente
|
||||
LPARAMETERS toCheck, tnNumar
|
||||
LOCAL lcBaza
|
||||
lcBaza = IIF(EMPTY(NVL(toCheck.Tag,'')), toCheck.Caption, toCheck.Tag)
|
||||
toCheck.Caption = ALLTRIM(lcBaza) + IIF(NVL(tnNumar,0) > 0, ' (' + ALLTRIM(STR(tnNumar)) + ')', '')
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Show
|
||||
LPARAMETERS nStyle
|
||||
DODEFAULT(nStyle)
|
||||
@@ -6165,6 +6336,8 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
this.pgfeFactura.page2.grdFacturiPrimite.HeaderHeight = 35
|
||||
this.pgfeFactura.page3.grdFacturiTrimise.HeaderHeight = 35
|
||||
|
||||
*!* numerele de pe bife apar de la deschidere, numarate local din cursorul deja adus
|
||||
This.NumaraDiferente()
|
||||
|
||||
ENDPROC
|
||||
|
||||
@@ -8884,6 +9057,7 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
*m: importmodifica
|
||||
*m: listarenir
|
||||
*m: modificanote
|
||||
*m: numaradiferenteimport
|
||||
*m: scrienote
|
||||
*p: lprimite
|
||||
*p: nidborderou
|
||||
@@ -9098,12 +9272,12 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
BackStyle = 1, ;
|
||||
Caption = "Cu diferente Reg. TVA", ;
|
||||
Height = 18, ;
|
||||
Left = 180, ;
|
||||
Left = 190, ;
|
||||
Name = "chkDiferente", ;
|
||||
Style = 0, ;
|
||||
Top = 35, ;
|
||||
Value = .F., ;
|
||||
Width = 159
|
||||
Width = 191
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'chkDistribuieDiscount' AS _checkbox WITH ;
|
||||
@@ -9136,7 +9310,7 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
Style = 0, ;
|
||||
Top = 35, ;
|
||||
Value = .F., ;
|
||||
Width = 159
|
||||
Width = 174
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'chkTVAIncasare' AS _checkbox WITH ;
|
||||
@@ -11531,7 +11705,7 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_cauta
|
||||
Local lcCond, lcDif, lcLipsa
|
||||
Local lcCond, lcDif, lcLipsa, lcFiltruBaza
|
||||
lcFiltru = '' && filtru facturi primite
|
||||
|
||||
* DACA FILTRUL NU CONTINE DATA_ACT, SELECTEZ DOAR INREGISTRARILE DIN LUNA CURENTA PANA LA ZI
|
||||
@@ -11547,6 +11721,14 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
lcFiltru = m.lcFiltru + [ and ((data_act >= to_date('] + m.lcData1 + [','ddmmyyyy') and data_act < to_date('] + m.lcData2 + [','ddmmyyyy')) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy')))]
|
||||
ENDIF
|
||||
|
||||
* Filtre buton cautare
|
||||
IF LEN(THISFORM.filtru_pretty)>0
|
||||
lcFiltru = m.lcFiltru + " and (" + ALLTRIM(THISFORM.filtru_pretty) + ")"
|
||||
ENDIF
|
||||
|
||||
* Filtrul de baza (fara chkDiferente/chkLipsaRegistru), pentru numarul independent din caption
|
||||
lcFiltruBaza = m.lcFiltru
|
||||
|
||||
* Bifele Diferente / Lipsa din registrul de TVA
|
||||
lcLipsa = [(jtotctva is null)]
|
||||
lcDif = [(jtotctva is not null and (NVL(nume_valuta,'RON') <> 'RON' or ABS(decode(creditnote,0,1,-1) * NVL(total_cu_tva,0.00) - (NVL(jtotctva,0.00) - NVL(jtva_ti,0.00))) > 0.15))]
|
||||
@@ -11561,11 +11743,6 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
lcFiltru = m.lcFiltru + [ and (] + m.lcCond + [)]
|
||||
ENDIF
|
||||
|
||||
* Filtre buton cautare
|
||||
IF LEN(THISFORM.filtru_pretty)>0
|
||||
lcFiltru = m.lcFiltru + " and (" + ALLTRIM(THISFORM.filtru_pretty) + ")"
|
||||
ENDIF
|
||||
|
||||
If Empty(m.lcFiltru)
|
||||
aMessagebox("Alegeti un criteriu!",0+48,"Atentie")
|
||||
Return
|
||||
@@ -11584,6 +11761,8 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
ENDIF
|
||||
|
||||
|
||||
This.NumaraDiferenteImport(m.lcFiltruBaza, m.lcDif, m.lcLipsa)
|
||||
|
||||
Return m.lcFiltru
|
||||
|
||||
ENDPROC
|
||||
@@ -12988,6 +13167,10 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
this.grdFacturi.SetAll("DynamicForeColor","IIF(creditnote = 1, RGB(225,0,0), RGB(0,0,0))", "Column")
|
||||
this.gridextra1.setup()
|
||||
this.gridextra2.setup()
|
||||
|
||||
* Caption de baza pentru bifele Diferente/Lipsa, refolosit de NumaraDiferenteImport
|
||||
This.chkDiferente.Tag = This.chkDiferente.Caption
|
||||
This.chkLipsaRegistru.Tag = This.chkLipsaRegistru.Caption
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE KeyPress
|
||||
@@ -13179,6 +13362,51 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NumaraDiferenteImport
|
||||
LPARAMETERS tcFiltruBaza, tcDif, tcLipsa
|
||||
LOCAL lcView, lcSql, llSucces, lnDif, lnLipsa, lnSelect, lnRec
|
||||
lnDif = 0
|
||||
lnLipsa = 0
|
||||
|
||||
*!* fara nicio bifa, cursorul afisat e chiar setul de baza: numaram local, fara interogare
|
||||
IF EMPTY(This.chkDiferente.Value) AND EMPTY(This.chkLipsaRegistru.Value) AND USED('crsFacturi')
|
||||
lnSelect = SELECT()
|
||||
lnRec = RECNO('crsFacturi')
|
||||
SELECT SUM(IIF(!ISNULL(jtotctva) AND (ALLTRIM(NVL(nume_valuta,'RON')) <> 'RON' OR ABS(NVL(diferenta,0)) > 0.15), 1, 0)) as ndif, ;
|
||||
SUM(IIF(ISNULL(jtotctva), 1, 0)) as nlipsa ;
|
||||
FROM crsFacturi INTO CURSOR crsNumarBifeLocal NOFILTER
|
||||
lnDif = NVL(crsNumarBifeLocal.ndif,0)
|
||||
lnLipsa = NVL(crsNumarBifeLocal.nlipsa,0)
|
||||
USE IN (SELECT('crsNumarBifeLocal'))
|
||||
This.chkDiferente.Caption = ALLTRIM(IIF(EMPTY(NVL(This.chkDiferente.Tag,'')), This.chkDiferente.Caption, This.chkDiferente.Tag)) + IIF(m.lnDif > 0, ' (' + ALLTRIM(STR(m.lnDif)) + ')', '')
|
||||
This.chkLipsaRegistru.Caption = ALLTRIM(IIF(EMPTY(NVL(This.chkLipsaRegistru.Tag,'')), This.chkLipsaRegistru.Caption, This.chkLipsaRegistru.Tag)) + IIF(m.lnLipsa > 0, ' (' + ALLTRIM(STR(m.lnLipsa)) + ')', '')
|
||||
SELECT crsFacturi
|
||||
IF m.lnRec > 0 AND m.lnRec <= RECCOUNT()
|
||||
GO m.lnRec
|
||||
ENDIF
|
||||
SELECT (m.lnSelect)
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
lcView = IIF(This.lPrimite, 'anaf_vefactura_primit', 'anaf_vefactura_trimis')
|
||||
|
||||
* Numarul se reseteaza pe 0 (caption fara paranteza) cand filtrul e gol sau interogarea esueaza
|
||||
IF !EMPTY(NVL(m.tcFiltruBaza,'')) AND !EMPTY(NVL(m.tcDif,''))
|
||||
lcSql = "select count(case when " + m.tcDif + " then 1 end) as ndif" + ;
|
||||
", count(case when " + m.tcLipsa + " then 1 end) as nlipsa" + ;
|
||||
" from " + m.lcView + " where 1=1 " + m.tcFiltruBaza
|
||||
|
||||
llSucces = goExecutor.oExecuta(m.lcSql, 'crsNumarDiferenteImport')
|
||||
IF m.llSucces
|
||||
lnDif = NVL(crsNumarDiferenteImport.ndif,0)
|
||||
lnLipsa = NVL(crsNumarDiferenteImport.nlipsa,0)
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
This.chkDiferente.Caption = ALLTRIM(IIF(EMPTY(NVL(This.chkDiferente.Tag,'')), This.chkDiferente.Caption, This.chkDiferente.Tag)) + IIF(m.lnDif > 0, ' (' + ALLTRIM(STR(m.lnDif)) + ')', '')
|
||||
This.chkLipsaRegistru.Caption = ALLTRIM(IIF(EMPTY(NVL(This.chkLipsaRegistru.Tag,'')), This.chkLipsaRegistru.Caption, This.chkLipsaRegistru.Tag)) + IIF(m.lnLipsa > 0, ' (' + ALLTRIM(STR(m.lnLipsa)) + ')', '')
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE scrienote
|
||||
ENDPROC
|
||||
|
||||
@@ -13194,6 +13422,8 @@ DEFINE CLASS frm_import_efactura AS _frmbase OF "_frm_base.vcx"
|
||||
Thisform.CompleteazaFactura() && cap factura
|
||||
Thisform.actualizeaza_grid2()
|
||||
Thisform.CompleteazaDetaliiFactura() && detalii factura
|
||||
*!* numerele de pe bife apar de la deschidere, numarate local din cursorul deja adus
|
||||
This.NumaraDiferenteImport()
|
||||
|
||||
|
||||
ENDPROC
|
||||
|
||||
@@ -1131,8 +1131,10 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
|
||||
*< OBJECTDATA: ObjPath="Clb_serie" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Ed_tx_explicatie" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="cb_explicatie_saft" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="ck_pret_cu_tva" UniqueID="" Timestamp="" />
|
||||
|
||||
*<DefinedPropArrayMethod>
|
||||
*m: do_aplica_mod_pret
|
||||
*m: do_calculeaza_adaos
|
||||
*m: do_calculeaza_discount
|
||||
*m: do_calculeaza_pretctva
|
||||
@@ -1155,7 +1157,7 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
|
||||
BorderStyle = 1
|
||||
Caption = "Form"
|
||||
DoCreate = .T.
|
||||
Height = 450
|
||||
Height = 500
|
||||
larata = .T.
|
||||
lcuadaos = .T.
|
||||
lmodpretctva = .F.
|
||||
@@ -1284,6 +1286,16 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
|
||||
_lbbase1.Top = 6
|
||||
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
|
||||
|
||||
ADD OBJECT 'ck_pret_cu_tva' AS _checkbox WITH ;
|
||||
Alignment = 0, ;
|
||||
Caption = "Pret cu TVA inclus", ;
|
||||
ControlSource = "poArticol.preturi_cu_tva", ;
|
||||
Left = 6, ;
|
||||
Name = "ck_pret_cu_tva", ;
|
||||
TabIndex = 24, ;
|
||||
Top = 464
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT 'clb_articol' AS clb_tx_simplu WITH ;
|
||||
Left = 6, ;
|
||||
Name = "clb_articol", ;
|
||||
@@ -1792,6 +1804,51 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
|
||||
_lbbase1.Top = 6
|
||||
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
|
||||
|
||||
PROCEDURE do_aplica_mod_pret
|
||||
Lparameters lnTip && 1 = sume in lei, 2 = sume in valuta
|
||||
If Inlist(poDate.tip,1,5,10,22,23,25,29,41) && documente pe baza de lista de preturi (1/5 factura lei si valuta, 10 factura fiscala in valuta, 22 aviz clienti, 23/25/41 transfer subunitati, 29 aviz clienti debitori): pretul e editabil oricum, pe restul doar daca e 0
|
||||
If poArticol.preturi_cu_tva = 0
|
||||
Thisform.lmodpretftva = .T.
|
||||
Thisform.clb_pretftva.do_activeaza(lnTip)
|
||||
Else
|
||||
Thisform.lmodpretctva = .T.
|
||||
Thisform.clb_pretctva.do_activeaza(lnTip)
|
||||
Endif
|
||||
Else
|
||||
If Type('Thisform.clb_procent_adaos') = 'O'
|
||||
Thisform.clb_procent_adaos.Visible = .F.
|
||||
Endif
|
||||
Thisform.lcuadaos = .F.
|
||||
If poArticol.preturi_cu_tva = 0 And ;
|
||||
((poArticol.pretftva = 0 And lnTip = 1) Or (poArticol.pretftva_val = 0 And lnTip = 2))
|
||||
Thisform.lmodpretftva = .T.
|
||||
Thisform.clb_pretftva.do_activeaza(lnTip)
|
||||
Else
|
||||
If poArticol.preturi_cu_tva = 1 And ;
|
||||
((poArticol.pretctva = 0 And lnTip = 1) Or (poArticol.pretctva_val = 0 And lnTip = 2))
|
||||
Thisform.lmodpretctva = .T.
|
||||
Thisform.clb_pretctva.do_activeaza(lnTip)
|
||||
Endif
|
||||
Endif
|
||||
Endif
|
||||
|
||||
If poArticol.preturi_cu_tva = 0
|
||||
Thisform.clb_discount_unitar.do_activeaza(lnTip)
|
||||
Thisform.clb_totalfdiscount.lb_explicatii.Caption = []
|
||||
Thisform.clb_totalcdiscount.lb_explicatii.Caption = []
|
||||
Thisform.clb_pret_diminuat.lb_explicatii.Caption = [(2) - (5)]
|
||||
Else
|
||||
Thisform.clb_discountctva.do_activeaza(lnTip)
|
||||
Thisform.clb_totalfdiscount.lb_explicatii.Caption = [(1) * (4)]
|
||||
Thisform.clb_totalcdiscount.lb_explicatii.Caption = [(1) * ( (4) - (7) )]
|
||||
With Thisform.clb_pret_diminuat
|
||||
.lb_explicatie.Caption = [Pret unitar diminuat cu TVA]
|
||||
.lb_explicatii.Caption = [(4) - (7)]
|
||||
Endwith
|
||||
Endif
|
||||
Thisform.ck_pret_cu_tva.Enabled = (Thisform.lmodpretftva Or Thisform.lmodpretctva)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_calculeaza_adaos
|
||||
Lparameters tnValoare,tnTip
|
||||
If Thisform.lcuadaos
|
||||
@@ -2364,54 +2421,7 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
|
||||
*!* *!* modificare v 2.0.46 ^
|
||||
*!* modificare v 2.0.74 ^
|
||||
|
||||
*!* modificare v 2.0.4
|
||||
*!* If Iif(Type('poArticol.modificabil')<>'U',poArticol.modificabil,0) = 1
|
||||
*!* modificare v 2.0.30 : am adaugat 41
|
||||
*!* modificare v 2.0.44 : am adaugat 42
|
||||
*!* If Inlist(poDate.tip,1,3,5,21,22,23,25,28,29,41,42)
|
||||
If Inlist(poDate.tip,1,5,10,22,23,25,29,41) && modificare v 2.0.56 : am adaugat 10
|
||||
*!* modificare v 2.0.4 ^
|
||||
If poArticol.preturi_cu_tva = 0
|
||||
Thisform.lmodpretftva = .T.
|
||||
Thisform.clb_pretftva.do_activeaza(lnTip)
|
||||
Else
|
||||
Thisform.lmodpretctva = .T.
|
||||
*!* modificare v 2.0.4
|
||||
*!* Thisform.RemoveObject('clb_procent_adaos')
|
||||
*!* thisform.lcuadaos = .F.
|
||||
*!* modificare v 2.0.4 ^
|
||||
Thisform.clb_pretctva.do_activeaza(lnTip)
|
||||
Endif
|
||||
Else
|
||||
Thisform.clb_procent_adaos.Visible = .F.
|
||||
Thisform.lcuadaos = .F.
|
||||
If poArticol.preturi_cu_tva = 0 And ;
|
||||
((poArticol.pretftva = 0 And lnTip = 1) Or (poArticol.pretftva_val = 0 And lnTip = 2))
|
||||
Thisform.lmodpretftva = .T.
|
||||
Thisform.clb_pretftva.do_activeaza(lnTip)
|
||||
Else
|
||||
If poArticol.preturi_cu_tva = 1 And ;
|
||||
((poArticol.pretctva = 0 And lnTip = 1) Or (poArticol.pretctva_val = 0 And lnTip = 2))
|
||||
Thisform.lmodpretctva = .T.
|
||||
Thisform.clb_pretctva.do_activeaza(lnTip)
|
||||
Endif
|
||||
Endif
|
||||
Endif
|
||||
|
||||
If poArticol.preturi_cu_tva = 0
|
||||
Thisform.clb_discount_unitar.do_activeaza(lnTip)
|
||||
Thisform.clb_totalfdiscount.lb_explicatii.Caption = []
|
||||
Thisform.clb_totalcdiscount.lb_explicatii.Caption = []
|
||||
Thisform.clb_pret_diminuat.lb_explicatii.Caption = [(2) - (5)]
|
||||
Else
|
||||
Thisform.clb_discountctva.do_activeaza(lnTip)
|
||||
Thisform.clb_totalfdiscount.lb_explicatii.Caption = [(1) * (4)]
|
||||
Thisform.clb_totalcdiscount.lb_explicatii.Caption = [(1) * ( (4) - (7) )]
|
||||
With Thisform.clb_pret_diminuat
|
||||
.lb_explicatie.Caption = [Pret unitar diminuat cu TVA]
|
||||
.lb_explicatii.Caption = [(4) - (7)]
|
||||
Endwith
|
||||
Endif
|
||||
Thisform.do_aplica_mod_pret(lnTip)
|
||||
|
||||
*!* modificare v 2.0.19
|
||||
*!* If (poDate.tip=2 And pnTipFacturare=3) Or INLIST(poDate.tip,4,23)
|
||||
@@ -2570,6 +2580,19 @@ DEFINE CLASS frm_articol_factura AS _frmbase OF "_frm_base.vcx"
|
||||
Thisform.UpdateExplicatieSaft()
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE ck_pret_cu_tva.InteractiveChange
|
||||
Local lnTip
|
||||
poArticol.preturi_cu_tva = This.Value
|
||||
lnTip = Iif(poArticol.tip_valuta = 0, 1, 2)
|
||||
If This.Value = 1
|
||||
Thisform.do_calculeaza_pretftva(Iif(lnTip = 1, poArticol.pretctva, poArticol.pretctva_val), lnTip)
|
||||
Else
|
||||
Thisform.do_calculeaza_pretctva(Iif(lnTip = 1, poArticol.pretftva, poArticol.pretftva_val), lnTip)
|
||||
Endif
|
||||
Thisform.do_aplica_mod_pret(lnTip)
|
||||
Thisform.do_calculeaza_totaluri()
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE clb_cantitate.Text_simplu1.InteractiveChange
|
||||
lcval=This.ControlSource
|
||||
&lcval=This.Value
|
||||
@@ -3146,7 +3169,7 @@ DEFINE CLASS frm_articol_gest_factura AS frm_articol_factura OF "ofacturare.vcx"
|
||||
*<PropValue>
|
||||
cgridsortlist = grd_gestiuni
|
||||
DoCreate = .T.
|
||||
Height = 510
|
||||
Height = 546
|
||||
lretur = .F.
|
||||
Name = "frm_articol_gest_factura"
|
||||
Width = 835
|
||||
@@ -3398,6 +3421,9 @@ DEFINE CLASS frm_articol_gest_factura AS frm_articol_factura OF "ofacturare.vcx"
|
||||
Cb_contract._cbbase1.Top = 3
|
||||
Cb_contract._cbbase1.Width = 274
|
||||
Cb_contract._lbbase1.Name = "_lbbase1"
|
||||
ck_pret_cu_tva.Left = 13
|
||||
ck_pret_cu_tva.Name = "ck_pret_cu_tva"
|
||||
ck_pret_cu_tva.Top = 510
|
||||
*</PropValue>
|
||||
|
||||
ADD OBJECT 'Cb_tx_articol' AS cb_tx_cautare WITH ;
|
||||
@@ -11048,6 +11074,7 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
*< OBJECTDATA: ObjPath="grd_contracte.cNumar_contract.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="grd_contracte.cCodbare.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="grd_contracte.cCodbare.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="But_modifica1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="But_sterge1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="lb_total_mod" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Gridextra1" UniqueID="" Timestamp="" />
|
||||
@@ -11162,6 +11189,16 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
Gridsort1.Top = 36
|
||||
*</PropValue>
|
||||
|
||||
ADD OBJECT 'But_modifica1' AS but_modifica WITH ;
|
||||
Anchor = 9, ;
|
||||
caction = do_modifica, ;
|
||||
Left = 773, ;
|
||||
Name = "But_modifica1", ;
|
||||
TabIndex = 13, ;
|
||||
Top = 61, ;
|
||||
Visible = .T.
|
||||
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
|
||||
|
||||
ADD OBJECT 'But_renunt1' AS but_renunt WITH ;
|
||||
Anchor = 8, ;
|
||||
Height = 27, ;
|
||||
@@ -13161,12 +13198,15 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_alege_stoc
|
||||
Lparameters tnIdArticol,tnCantitate,tcNumeArticol,tlImplicit,tnPret,tnDiscount,toGrid, tlRetur
|
||||
Lparameters tnIdArticol,tnCantitate,tcNumeArticol,tlImplicit,tnPret,tnDiscount,toGrid, tlRetur, tnIdTempExclus
|
||||
* llImplicit => vezi thisform.do_adauga
|
||||
* tnPret => doar pentru retururi : e pretul de vanzare fara TVA
|
||||
* toGrid => gridul din care vine articolul
|
||||
* tlRetur => factura normala cu articol retur (nu factura de retur tip 8,9). se comporta la fel ca factura de retur. se selecteaza din RUL, dar nu stiu factura din care fac retur
|
||||
|
||||
* tnIdTempExclus => id_temp-ul liniei modificate, exclus din cantitatea deja retinuta pe factura (0 la adaugare)
|
||||
If Type('tnIdTempExclus') <> 'N'
|
||||
tnIdTempExclus = 0
|
||||
Endif
|
||||
Private pnIdArticol
|
||||
Local llReturn,lofrmadarticol,lcSql, llFacturareFaraStoc
|
||||
llFactuareFaraStoc = .F.
|
||||
@@ -13232,7 +13272,7 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
* Arat cantitatile din stoc - cantitatile deja pe factura curenta
|
||||
Select Iif(poDate.tip=41,-1,1)*Sum(cantitate) As cantitate,id_articol,id_gestiune,pret_achizitie,serie,lot,Cont, ;
|
||||
id_part_rez,id_lucrare_rez,pretv_orig,pretd,id_valuta_d ;
|
||||
FROM crsfactura Where id_articol = pnIdArticol ;
|
||||
FROM crsfactura Where id_articol = pnIdArticol And id_temp <> tnIdTempExclus ;
|
||||
GROUP By id_articol,id_gestiune,pret_achizitie,serie,lot,Cont,id_part_rez,id_lucrare_rez,pretv_orig,pretd,id_valuta_d ;
|
||||
INTO CURSOR crsFacturaArticoleTemp
|
||||
|
||||
@@ -13275,6 +13315,12 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
SELECT (m.lcCursor)
|
||||
Go Top
|
||||
If tnIdTempExclus > 0
|
||||
Locate For id_gestiune = poArticol.id_gestiune And Pret = poArticol.pret_achizitie And Cont = poArticol.Cont And Nvl(serie,'') = Nvl(poArticol.serie,'') And Nvl(lot,'') = Nvl(poArticol.lot,'') And Nvl(id_part_rez,0) = Nvl(poArticol.id_part_rez,0) And Nvl(id_lucrare_rez,0) = Nvl(poArticol.id_lucrare_rez,0) And pretv = poArticol.pretv_orig And pretd = poArticol.pretd And Nvl(id_valuta,0) = Nvl(poArticol.id_valuta_d,0)
|
||||
If !Found()
|
||||
Go Top
|
||||
Endif
|
||||
Endif
|
||||
Do Case
|
||||
Case Reccount(lcCursor) = 0
|
||||
amessagebox("Articolul "+Alltrim(tcNumeArticol)+" nu mai este pe stoc!",0+48,"Atentie")
|
||||
@@ -13697,6 +13743,176 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
*!* modificare v 2.0.67 ^
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_modifica
|
||||
If Reccount('crsfactura')>0
|
||||
Private poArticol, pnProcentDiscountMem
|
||||
Local lnRecno, ofrmadarticol
|
||||
Select crsfactura
|
||||
lnRecno = Recno()
|
||||
Scatter Name poArticol MEMO
|
||||
|
||||
AddProperty(poArticol,'preturi_cu_tva',poArticol.cu_tva)
|
||||
AddProperty(poArticol,'discount_unitar',poArticol.discountftva)
|
||||
AddProperty(poArticol,'discount_unitar_ctva',poArticol.discountctva)
|
||||
AddProperty(poArticol,'pretftva_val',poArticol.vpretftva)
|
||||
AddProperty(poArticol,'pretctva_val',poArticol.vpretctva)
|
||||
AddProperty(poArticol,'discount_unitar_val',poArticol.vdiscountftva)
|
||||
AddProperty(poArticol,'discount_unitar_ctva_val',poArticol.vdiscountctva)
|
||||
Removeproperty(poArticol,'cu_tva')
|
||||
Removeproperty(poArticol,'discountftva')
|
||||
Removeproperty(poArticol,'discountctva')
|
||||
Removeproperty(poArticol,'vpretftva')
|
||||
Removeproperty(poArticol,'vpretctva')
|
||||
Removeproperty(poArticol,'vdiscountftva')
|
||||
Removeproperty(poArticol,'vdiscountctva')
|
||||
AddProperty(poArticol,'tva',poArticol.pretctva - poArticol.pretftva)
|
||||
AddProperty(poArticol,'tva_val',poArticol.pretctva_val - poArticol.pretftva_val)
|
||||
|
||||
pnProcentDiscountMem = 0
|
||||
If Nvl(gnMemProcDisc, 0) = 1
|
||||
pnProcentDiscountMem = Thisform.nproc_disc_mem
|
||||
Endif
|
||||
* plafonul de cantitate = stocul disponibil reconstituit din cursorul sursa; fara randul in cursor ramane cantitatea liniei
|
||||
Local lnCantitateMax, lcCursorStoc, lcAliasCrt, lnRecnoStoc, lnCantitateVeche, lnIdTempLinie, lnDeltaCantitate, lnTotalCantitate
|
||||
lnCantitateMax = poArticol.cantitate
|
||||
lcCursorStoc = Iif(poArticol.opt_facturare = 0, [crsarticole], [crsarticole1])
|
||||
If Used(lcCursorStoc)
|
||||
lcAliasCrt = Alias()
|
||||
Select (lcCursorStoc)
|
||||
lnRecnoStoc = Recno()
|
||||
Locate For id_c = poArticol.id_c
|
||||
If Found()
|
||||
Do Case
|
||||
Case (gnScadereStoc = 1 And poDate.tip = 23) Or Inlist(poDate.tip, 4, 21, 28, 42, 47) && adaugarea scade stocul; lista e cea validata la plafon (fara 3 si 25): 23 transfer subunitati, 4 din avize, 21/28/42/47 catre clienti
|
||||
lnCantitateMax = cantitate + poArticol.cantitate
|
||||
Case Inlist(poDate.tip, 8, 9, 24) && adaugarea creste stocul: 8/9 retur factura in lei si in valuta, 24 aviz de retur
|
||||
lnCantitateMax = cantitate - poArticol.cantitate
|
||||
Endcase
|
||||
Endif
|
||||
Try
|
||||
Go lnRecnoStoc
|
||||
Catch
|
||||
Go Top
|
||||
Endtry
|
||||
Select (lcAliasCrt)
|
||||
Endif
|
||||
|
||||
gnButon = 2
|
||||
lnCantitateVeche = poArticol.cantitate
|
||||
lnIdTempLinie = poArticol.id_temp
|
||||
Do Case
|
||||
Case (poArticol.gestionabil = 0 Or gnScadereStoc = 0 Or poDate.tip = 45) && 45 = ROARESTAURANT
|
||||
ofrmadarticol = Createobject("frm_articol_factura", lnCantitateMax, .F.)
|
||||
ofrmadarticol.Show(1)
|
||||
Release ofrmadarticol
|
||||
Otherwise
|
||||
Thisform.do_alege_stoc(poArticol.id_articol, lnCantitateMax, poArticol.denumire, .F., poArticol.pretftva, poArticol.discount_unitar, Thisform.grd_factura, .F., lnIdTempLinie)
|
||||
Endcase
|
||||
If gnButon = 1
|
||||
Select crsfactura
|
||||
Try
|
||||
Go lnRecno
|
||||
Catch
|
||||
Go Top
|
||||
Endtry
|
||||
If Used('crsartselectate')
|
||||
lnTotalCantitate = poArticol.cantitate
|
||||
Select crsartselectate
|
||||
Go Top
|
||||
poArticol.pret_achizitie = Pret
|
||||
poArticol.serie = Nvl(serie, [])
|
||||
poArticol.lot = Nvl(lot, [])
|
||||
poArticol.id_gestiune = id_gestiune
|
||||
poArticol.Cont = Alltrim(Cont)
|
||||
poArticol.cantitate = cantitate
|
||||
poArticol.pretv_orig = pretv
|
||||
poArticol.id_lucrare_rez = id_lucrare_rez
|
||||
poArticol.id_part_rez = id_part_rez
|
||||
poArticol.pretd = pretd
|
||||
poArticol.id_valuta_d = id_valuta
|
||||
Select crsfactura
|
||||
Endif
|
||||
Gather Name poArticol Fields Like pret_achizitie, denumire, cantitate, id_articol, Id_Pol, Cont, id_gestiune, Proc_Tvav, ;
|
||||
pretftva, valftva, valtva, valctva, valdiscountftva, valdiscounttva, valdiscountctva, Pretctva, ;
|
||||
valdiminuatftva, valdiminuattva, valdiminuatctva, ;
|
||||
vvalftva, vvaltva, vvalctva, vvaldiscountftva, vvaldiscounttva, vvaldiscountctva, ;
|
||||
vvaldiminuatftva, vvaldiminuattva, vvaldiminuatctva, id_c, lot, serie, explicatie, ;
|
||||
id_valuta, gestionabil, tip_valuta, id_jtva_coloana, taxcode, id_lucrare_rez, id_part_rez, pretv_orig, pretd, id_valuta_d, id_ctr, opt_facturare, nume_val MEMO
|
||||
Replace cu_tva With poArticol.preturi_cu_tva, ;
|
||||
discountftva With poArticol.discount_unitar, discountctva With poArticol.discount_unitar_ctva, ;
|
||||
vpretftva With Nvl(poArticol.pretftva_val,0), vpretctva With Nvl(poArticol.pretctva_val,0), ;
|
||||
vdiscountftva With Nvl(poArticol.discount_unitar_val,0), vdiscountctva With Nvl(poArticol.discount_unitar_ctva_val,0)
|
||||
If Used('crsartselectate')
|
||||
Select crsartselectate
|
||||
Skip
|
||||
Scan Rest
|
||||
poArticol.pret_achizitie = Pret
|
||||
poArticol.serie = Nvl(serie, [])
|
||||
poArticol.lot = Nvl(lot, [])
|
||||
poArticol.id_gestiune = id_gestiune
|
||||
poArticol.Cont = Alltrim(Cont)
|
||||
poArticol.cantitate = cantitate
|
||||
poArticol.pretv_orig = pretv
|
||||
poArticol.id_lucrare_rez = id_lucrare_rez
|
||||
poArticol.id_part_rez = id_part_rez
|
||||
poArticol.pretd = pretd
|
||||
poArticol.id_valuta_d = id_valuta
|
||||
Select crsfactura
|
||||
Append Blank
|
||||
Gather Name poArticol Fields Like pret_achizitie, denumire, cantitate, id_articol, Id_Pol, ;
|
||||
Cont, id_gestiune, Proc_Tvav, pretftva, Pretctva, ;
|
||||
id_c, lot, serie, explicatie, ;
|
||||
id_valuta, gestionabil, tip_valuta, id_jtva_coloana, taxcode, id_lucrare_rez, id_part_rez, pretv_orig, pretd, id_valuta_d, nume_val, id_ctr, opt_facturare MEMO
|
||||
Replace id_temp With Recno(), codmat With Nvl(poArticol.codmat, Space(50)), ;
|
||||
codbare With Nvl(poArticol.codbare, Space(50)), ;
|
||||
codmatf With Nvl(poArticol.codmatf, Space(50)), um With Nvl(poArticol.um, Space(50)), ;
|
||||
Curs With Nvl(poArticol.Curs, 0), multiplicator With Nvl(poArticol.multiplicator, 1), ;
|
||||
cu_tva With poArticol.preturi_cu_tva, ;
|
||||
vpretftva With Nvl(poArticol.pretftva_val, 0), vpretctva With Nvl(poArticol.pretctva_val, 0), ;
|
||||
discountftva With poArticol.discount_unitar, discountctva With poArticol.discount_unitar_ctva, ;
|
||||
vdiscountftva With Nvl(poArticol.discount_unitar_val, 0), ;
|
||||
vdiscountctva With Nvl(poArticol.discount_unitar_ctva_val, 0)
|
||||
poArticol = calculeaza_totaluri(poArticol)
|
||||
Gather Name poArticol Fields Like valftva, valtva, valctva, ;
|
||||
valdiscountftva, valdiscounttva, valdiscountctva, ;
|
||||
valdiminuatftva, valdiminuattva, valdiminuatctva, ;
|
||||
vvalftva, vvaltva, vvalctva, ;
|
||||
vvaldiscountftva, vvaldiscounttva, vvaldiscountctva, ;
|
||||
vvaldiminuatftva, vvaldiminuattva, vvaldiminuatctva MEMO
|
||||
Endscan
|
||||
Use In crsartselectate
|
||||
poArticol.cantitate = lnTotalCantitate
|
||||
Select crsfactura
|
||||
Endif
|
||||
lnDeltaCantitate = poArticol.cantitate - lnCantitateVeche
|
||||
If lnDeltaCantitate <> 0 And Used(lcCursorStoc)
|
||||
lcAliasCrt = Alias()
|
||||
Select (lcCursorStoc)
|
||||
lnRecnoStoc = Recno()
|
||||
Do Case
|
||||
Case (gnScadereStoc = 1 And poDate.tip = 23) Or Inlist(poDate.tip, 4, 21, 28, 42, 47)
|
||||
Replace cantitate With cantitate - lnDeltaCantitate For id_c = poArticol.id_c
|
||||
Case Inlist(poDate.tip, 8, 9, 24)
|
||||
Replace cantitate With cantitate + lnDeltaCantitate For id_c = poArticol.id_c
|
||||
Endcase
|
||||
Try
|
||||
Go lnRecnoStoc
|
||||
Catch
|
||||
Go Top
|
||||
Endtry
|
||||
Select (lcAliasCrt)
|
||||
Endif
|
||||
If Nvl(gnMemProcDisc, 0) = 1
|
||||
Thisform.nproc_disc_mem = pnProcentDiscountMem
|
||||
Endif
|
||||
Thisform.do_calculeaza_totaluri()
|
||||
Thisform.grd_factura.Refresh()
|
||||
Thisform.grd_factura.SetFocus()
|
||||
Endif
|
||||
Release poArticol, pnProcentDiscountMem
|
||||
Endif
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_renunt
|
||||
*!* modificare 19.01.2007
|
||||
DODEFAULT()
|
||||
@@ -14006,7 +14222,6 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
pnParametruAditional = 0
|
||||
llReturn = .T.
|
||||
lcListaIncasare = ''
|
||||
SET STEP ON
|
||||
llEproforma = (poDate.eProforma = 1)
|
||||
|
||||
If Inlist(poDate.ntip_incasare, 11, 2, 3) && 11 = CHITANTA, 2 = BON FISCAL, 3 = POS/Card
|
||||
@@ -15513,6 +15728,10 @@ DEFINE CLASS frm_facturare_articole AS _frmbase OF "_frm_base.vcx"
|
||||
*Nu sterge
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE grd_factura.DblClick
|
||||
Thisform.do_modifica()
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE grd_factura.Init
|
||||
*Nu sterge
|
||||
ENDPROC
|
||||
|
||||
@@ -150,7 +150,7 @@ DEFINE CLASS frm_borderou_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
ADD OBJECT 'Cmd_executa1' AS cmd_executa WITH ;
|
||||
Anchor = 6, ;
|
||||
Caption = "Marcheaz<61> \<trimis", ;
|
||||
Caption = "Marcheaz<61> \<trimis", ;
|
||||
ForeColor = 0,128,0, ;
|
||||
Height = 27, ;
|
||||
Left = 140, ;
|
||||
@@ -1334,8 +1334,10 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
*< OBJECTDATA: ObjPath="But_attach1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="But_listare1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="But_verifica1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="But_editare1" UniqueID="" Timestamp="" />
|
||||
|
||||
*<DefinedPropArrayMethod>
|
||||
*m: do_editare_factura
|
||||
*m: do_listare_cc
|
||||
*m: do_listare_centr
|
||||
*m: do_listare_document
|
||||
@@ -1350,7 +1352,7 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
*<PropValue>
|
||||
BorderStyle = 1
|
||||
cbuton2 = but_listare1;but_listare2;But_listare3
|
||||
cbuton3 = but_modifica1;but_modifica2
|
||||
cbuton3 = but_modifica1;but_modifica2;But_editare1
|
||||
cfiltru_initial =
|
||||
cgridsortlist = grid_facturi,grid_detalii
|
||||
DoCreate = .T.
|
||||
@@ -1410,6 +1412,17 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
Visible = .F.
|
||||
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
|
||||
|
||||
ADD OBJECT 'But_editare1' AS but_modifica WITH ;
|
||||
Anchor = 12, ;
|
||||
caction = do_editare_factura, ;
|
||||
Caption = "", ;
|
||||
Left = 650, ;
|
||||
Name = "But_editare1", ;
|
||||
TabIndex = 29, ;
|
||||
ToolTipText = "Editare factura (articole, cantitati, preturi)", ;
|
||||
Top = 341
|
||||
*< END OBJECT: ClassLib="cmd_butoane.vcx" BaseClass="commandbutton" />
|
||||
|
||||
ADD OBJECT 'But_listare1' AS but_listare WITH ;
|
||||
Anchor = 8, ;
|
||||
Left = 698, ;
|
||||
@@ -3471,7 +3484,7 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
Anchor = 12, ;
|
||||
AutoSize = .T., ;
|
||||
BackStyle = 0, ;
|
||||
Caption = "Total <20>n valuta", ;
|
||||
Caption = "Total <20>n valuta", ;
|
||||
FontSize = 10, ;
|
||||
Height = 18, ;
|
||||
Left = 311, ;
|
||||
@@ -3711,6 +3724,150 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
This.do_cauta()
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_editare_factura
|
||||
If !This.lactiv3
|
||||
Return
|
||||
Endif
|
||||
|
||||
If Reccount('crsfacturi') = 0
|
||||
amessagebox("Nu exista inregistrari pentru editare!",0+48,"Atentie")
|
||||
Return
|
||||
Endif
|
||||
|
||||
If glLunaInchisa
|
||||
Return
|
||||
Endif
|
||||
|
||||
Local lnSters, llEProforma, lnIdSet, lnIdFactD, lnSucces, Omodif, llGasitRand
|
||||
Private pnAn, pnLuna, lnCod, lnIdFact, lnIdVanzare
|
||||
Store 0 To pnAn, pnLuna, lnCod, lnIdFact, lnIdSet, lnIdFactD, lnIdVanzare
|
||||
|
||||
Select crsfacturi
|
||||
lnIdVanzare = id_vanzare
|
||||
lnCod = cod
|
||||
pnAn = Year(data_act)
|
||||
pnLuna = Month(data_act)
|
||||
lnSters = sters
|
||||
lnIdFact = id_fact
|
||||
llEProforma = (eproforma = 1)
|
||||
|
||||
If lnSters = 1
|
||||
amessagebox("Acest document este deja sters!",0+48,"Atentie")
|
||||
Return
|
||||
Endif
|
||||
|
||||
If llEProforma
|
||||
amessagebox("Proformele nu pot fi editate pe aceasta cale!",0+48,"Atentie")
|
||||
Return
|
||||
Endif
|
||||
|
||||
If (pnAn * 12) + pnLuna <> (gnAn * 12) + gnLuna
|
||||
amessagebox('Nu puteti edita decat inregistrari din luna curenta!',0,'Atentie!')
|
||||
Return
|
||||
Endif
|
||||
|
||||
*** verificare restrictie editare documente cu referinte (incasari/plati)
|
||||
If ReferinteDocumenteNota(pnAn, pnLuna, lnCod) && odocumente.prg
|
||||
amessagebox("Documentul are referinte (incasari/plati). Nu poate fi editat.", 0+48,"Editare")
|
||||
Return
|
||||
Endif
|
||||
|
||||
*** verificare restrictie editare facturi trimise in eFactura
|
||||
If EsteInEFactura(lnIdFact) && ofacturare_editare.prg
|
||||
amessagebox("Documentul a fost trimis in eFactura. Nu poate fi editat.", 0+48,"Editare")
|
||||
Return
|
||||
Endif
|
||||
|
||||
If IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.) && ofacturare_editare.prg
|
||||
If Reccount('actactan') = 0
|
||||
amessagebox("Nu exista nota contabila pentru aceasta factura.",0+48,"Atentie")
|
||||
Else
|
||||
Select actactan
|
||||
llGasitRand = .F.
|
||||
If lnIdFact > 0
|
||||
Locate For Nvl(id_fact, 0) = lnIdFact
|
||||
llGasitRand = Found()
|
||||
Endif
|
||||
If !llGasitRand
|
||||
*** rezerva: nota nu contine id_fact-ul din vanzari (avize, transferuri, documente vechi)
|
||||
Go Top
|
||||
lnIdFact = id_fact
|
||||
Endif
|
||||
lnIdSet = id_set
|
||||
lnIdFactD = id_factd
|
||||
|
||||
Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
|
||||
|
||||
Select tact
|
||||
Omodif = Createobject([frm_modific2024], lnIdSet)
|
||||
Omodif.Show()
|
||||
|
||||
If buton = 1
|
||||
If Thisform.do_deschide_tranzactie()
|
||||
Select actactan
|
||||
lnSucces = OSCRIE_IN_FISIERE(2,.T.,.T.)
|
||||
If lnSucces > 0
|
||||
If Used('actactan')
|
||||
Use In actactan
|
||||
Endif
|
||||
Select tact
|
||||
Replace id_jtva_coloana With Null, proc_tva With 0 For cu_Tva = 0
|
||||
Select * From tact Into Cursor actactan Readwrite
|
||||
Replace All id_util With gnIdUtil, sters With 0
|
||||
If Used('rul_temp')
|
||||
Use In rul_temp
|
||||
Endif
|
||||
Select * From trul Into Cursor RUL_TEMP Readwrite
|
||||
Replace All id_util With gnIdUtil, sters With 0
|
||||
If Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
Endif
|
||||
Select * From trul_obinv Into Cursor RUL_TEMP_OBINV Readwrite
|
||||
Replace All id_util With gnIdUtil, sters With 0
|
||||
lnSucces = OSCRIE_IN_FISIERE(0,.T.,.T.)
|
||||
Endif
|
||||
If lnSucces > 0
|
||||
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,Null,] + Alltrim(Str(lnIdSet)) + [,] + ;
|
||||
Alltrim(Str(lnCod)) + [,] + Alltrim(Str(lnIdFact)) + [,] + Alltrim(Str(lnIdFactD)) + [,?gnIdUtil); end;]
|
||||
lnSucces = Iif(goExecutor.oExecuta(lcSql),1,-1)
|
||||
Endif
|
||||
If Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1))
|
||||
If lnSucces > 0
|
||||
Thisform.do_cauta()
|
||||
Endif
|
||||
Endif
|
||||
Endif
|
||||
Endif
|
||||
Endif
|
||||
|
||||
If Used('actactan')
|
||||
Use In actactan
|
||||
Endif
|
||||
If Used('tact')
|
||||
Use In tact
|
||||
Endif
|
||||
If Used('rul_temp')
|
||||
Use In rul_temp
|
||||
Endif
|
||||
If Used('trul')
|
||||
Use In trul
|
||||
Endif
|
||||
If Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
Endif
|
||||
If Used('trul_obinv')
|
||||
Use In trul_obinv
|
||||
Endif
|
||||
Endif
|
||||
|
||||
Select crsfacturi
|
||||
Locate For id_vanzare = lnIdVanzare
|
||||
If !Found()
|
||||
Go Top
|
||||
Endif
|
||||
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_listare
|
||||
*!* 26.11.2019
|
||||
*!* marius.mutu
|
||||
@@ -4333,7 +4490,6 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
Select crsdetalii
|
||||
Calculate Max(proc_tvav) To lnProcTvav
|
||||
SET STEP ON
|
||||
creeaza_facturacrs([crsfactura])
|
||||
|
||||
prelucreaza_facturacrs([crsdetalii], [crsfactura], lnProcTvav, lnDiscount, lnDiscountVal)
|
||||
@@ -4382,7 +4538,6 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
||||
PROCEDURE do_modifica
|
||||
Local ofrmmodificare As "frm_modifica_factura"
|
||||
Local lcSql, lnSucces
|
||||
SET STEP ON
|
||||
PRIVATE poRec, pneFactura
|
||||
If Reccount('crsfacturi') > 0
|
||||
Local lnRecno, lnNrInreg, lnNrInregMod
|
||||
@@ -4990,7 +5145,7 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
|
||||
_shape2.Top = 0
|
||||
_shape2.Width = 64
|
||||
_shape2.ZOrderSet = 2
|
||||
Lb_titlu_alb_b121.Caption = "Modific<69> explica<63>ie articol"
|
||||
Lb_titlu_alb_b121.Caption = "Modific<69> explica<63>ie articol"
|
||||
Lb_titlu_alb_b121.Name = "Lb_titlu_alb_b121"
|
||||
Lb_titlu_alb_b121.TabIndex = 5
|
||||
Lb_titlu_alb_b121.ZOrderSet = 3
|
||||
@@ -5048,7 +5203,7 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
|
||||
_edbase1.Name = "_edbase1", ;
|
||||
_edbase1.Top = 23, ;
|
||||
_edbase1.Width = 325, ;
|
||||
_lbbase1.Caption = "Explica<63>ie", ;
|
||||
_lbbase1.Caption = "Explica<63>ie", ;
|
||||
_lbbase1.Name = "_lbbase1"
|
||||
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
|
||||
|
||||
@@ -5282,7 +5437,7 @@ DEFINE CLASS frm_modifica_factura AS frm_termin_renunt OF "_frm_child.vcx"
|
||||
Text_simplu1.Name = "Text_simplu1", ;
|
||||
Text_simplu1.Top = 3, ;
|
||||
Text_simplu1.Width = 177, ;
|
||||
Lb_simplu1.Caption = "Data <20>i ora expedierii", ;
|
||||
Lb_simplu1.Caption = "Data <20>i ora expedierii", ;
|
||||
Lb_simplu1.Name = "Lb_simplu1"
|
||||
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
|
||||
|
||||
@@ -5332,7 +5487,7 @@ DEFINE CLASS frm_modifica_factura AS frm_termin_renunt OF "_frm_child.vcx"
|
||||
Top = 128, ;
|
||||
ZOrderSet = 9, ;
|
||||
img_cautare.Name = "img_cautare", ;
|
||||
clb_tx_cautare.Lb_simplu1.Caption = "Ma<4D>ina", ;
|
||||
clb_tx_cautare.Lb_simplu1.Caption = "Ma<4D>ina", ;
|
||||
clb_tx_cautare.Lb_simplu1.Name = "Lb_simplu1", ;
|
||||
clb_tx_cautare.Name = "clb_tx_cautare", ;
|
||||
clb_tx_cautare.Text_simplu1.Left = 133, ;
|
||||
@@ -6822,7 +6977,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
|
||||
Anchor = 12, ;
|
||||
AutoSize = .T., ;
|
||||
BackStyle = 0, ;
|
||||
Caption = "Total <20>n valuta", ;
|
||||
Caption = "Total <20>n valuta", ;
|
||||
FontSize = 10, ;
|
||||
Height = 18, ;
|
||||
Left = 311, ;
|
||||
@@ -6854,7 +7009,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
|
||||
OPTION1.Top = 5, ;
|
||||
OPTION1.Value = 1, ;
|
||||
OPTION2.AutoSize = .T., ;
|
||||
OPTION2.Caption = "<22>n valuta", ;
|
||||
OPTION2.Caption = "<22>n valuta", ;
|
||||
OPTION2.FontCharSet = 238, ;
|
||||
OPTION2.FontSize = 10, ;
|
||||
OPTION2.Left = 55, ;
|
||||
@@ -6862,7 +7017,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
|
||||
OPTION2.Top = 5, ;
|
||||
Option3.AutoSize = .T., ;
|
||||
Option3.BackStyle = 0, ;
|
||||
Option3.Caption = "<22>n RON", ;
|
||||
Option3.Caption = "<22>n RON", ;
|
||||
Option3.FontCharSet = 238, ;
|
||||
Option3.FontSize = 10, ;
|
||||
Option3.Height = 18, ;
|
||||
@@ -6893,7 +7048,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
|
||||
OPTION1.Top = 5, ;
|
||||
OPTION1.Value = 0, ;
|
||||
OPTION2.AutoSize = .T., ;
|
||||
OPTION2.Caption = "<22>terse", ;
|
||||
OPTION2.Caption = "<22>terse", ;
|
||||
OPTION2.FontCharSet = 238, ;
|
||||
OPTION2.FontSize = 10, ;
|
||||
OPTION2.ForeColor = 255,0,0, ;
|
||||
@@ -6902,7 +7057,7 @@ DEFINE CLASS frm_proforme AS _frmbase OF "_frm_base.vcx"
|
||||
OPTION2.Top = 5, ;
|
||||
Option3.AutoSize = .T., ;
|
||||
Option3.BackStyle = 0, ;
|
||||
Option3.Caption = "Ne<4E>terse", ;
|
||||
Option3.Caption = "Ne<4E>terse", ;
|
||||
Option3.FontCharSet = 238, ;
|
||||
Option3.FontSize = 10, ;
|
||||
Option3.Height = 18, ;
|
||||
|
||||
@@ -10199,7 +10199,8 @@ DEFINE CLASS import_nota AS frm_termin_renunt OF "_frm_child.vcx"
|
||||
*!* Randul D, unic pe nota (doc_key gol, nr_doc 99999999): diferenta = baza documentelor
|
||||
*!* care participa la pret - Suma(pret*cant) cu pretul incarcat. Cont dominant = contul de
|
||||
*!* clasa 3 cu baza ABS maxima; fara clasa 3 -> clasa 2, cu contul fix 6588. Diferenta se
|
||||
*!* scrie doar in lei. Antetul se mosteneste de la documentul principal.
|
||||
*!* scrie doar in lei, fara TVA si fara cod de taxa SAFT. Antetul se mosteneste de la
|
||||
*!* documentul principal.
|
||||
Local lcSel, lnMinNrDoc, lnTotalLei, lnTotalVal, lnBazaParticipa
|
||||
Local lcContDominant, lnBazaDominantaAbs, lcScd1, lnDiferentaLei, lnDiferentaVal, lcExplicatie
|
||||
Local llGasitClasa3, loAntet
|
||||
@@ -10310,7 +10311,7 @@ DEFINE CLASS import_nota AS frm_termin_renunt OF "_frm_child.vcx"
|
||||
Replace partc With '', id_partc With 0, partd With '', id_partd With 0
|
||||
Endif
|
||||
Replace scd With lcScd1, scc With lcContDominant, suma With lnDiferentaLei, suma_val With 0, ;
|
||||
explicatia With lcExplicatie, id_jtva_coloana With Null, ptva With 0, cu_tva With 0, ;
|
||||
explicatia With lcExplicatie, id_jtva_coloana With Null, taxcode With 0, ptva With 0, cu_tva With 0, ;
|
||||
in_valuta With 0, participa_valuta With .F., nume_val With '', id_valuta With 0, curs With 0
|
||||
|
||||
Select (lcSel)
|
||||
|
||||
@@ -6628,6 +6628,33 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE2.grdRulajeObinv.cvaloarecTVA.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE2.grdRulajeObinv.cvaloarevTVA.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE2.grdRulajeObinv.cvaloarevTVA.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cDenumireArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cDenumireArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cCodmatArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cCodmatArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cSerieArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cSerieArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cLotArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cLotArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cProcTvavArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cProcTvavArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cDiscountUnitarArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cDiscountUnitarArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cGestiuneArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cGestiuneArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cValutaArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cValutaArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cExplicatieArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cExplicatieArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cTaxcodeArt.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cTaxcodeArt.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE2.grdRulajeObinv.cvaloarevcTVA.cvaloarevcTVA" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE2.grdRulajeObinv.cvaloarevcTVA.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Grid1" UniqueID="" Timestamp="" />
|
||||
@@ -6720,6 +6747,8 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
*< OBJECTDATA: ObjPath="Grid1.Column43.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Grid1.Column43.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Grid1.Column43._combobox1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Grid1.Column44.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Grid1.Column44.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Command1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Gridextra1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Command2" UniqueID="" Timestamp="" />
|
||||
@@ -6762,6 +6791,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
*m: grid_focus_prima_coloana
|
||||
*m: resize_grid1
|
||||
*m: salveazaxml
|
||||
*m: sincronizeaza_nnir
|
||||
*m: updateexplicatiesaft
|
||||
*m: updateexplicatiesaftrul
|
||||
*m: valideaza_data
|
||||
@@ -6771,17 +6801,21 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
*p: ccontrol
|
||||
*p: cpaymentcode
|
||||
*p: fel_compensare
|
||||
*p: larearticolevanzari
|
||||
*p: lavertizatexigibilizare
|
||||
*p: leditare
|
||||
*p: lmodificare
|
||||
*p: lnotanoua
|
||||
*p: lverificare
|
||||
*p: lvizualizare
|
||||
*p: nidvanzare
|
||||
*p: nid_set
|
||||
*p: nnnirvechi
|
||||
*p: noldsuma && Valoarea la intrarea in campul "Suma"
|
||||
*p: nprimadata
|
||||
*p: nsuma && Total suma inregistrari
|
||||
*p: ntaxcode
|
||||
*p: ntipvanzare
|
||||
*p: obackupxml
|
||||
*p: oldvalue
|
||||
*p: oset
|
||||
@@ -6801,6 +6835,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
DoCreate = .T.
|
||||
FontCharSet = 238
|
||||
Height = 508
|
||||
larearticolevanzari = .F.
|
||||
lavertizatexigibilizare = .F.
|
||||
leditare = .F.
|
||||
lmodificare = .F.
|
||||
@@ -6808,11 +6843,14 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
lverificare = .F.
|
||||
lvizualizare = .F.
|
||||
Name = "frm_modific2024"
|
||||
nidvanzare = 0
|
||||
nid_set = 0
|
||||
nnnirvechi = 0
|
||||
noldsuma = 0
|
||||
nprimadata = 0
|
||||
nsuma = 0
|
||||
ntaxcode = 0
|
||||
ntipvanzare = 0
|
||||
obackupxml = NULL
|
||||
oldvalue =
|
||||
oset = NULL
|
||||
@@ -7143,7 +7181,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
ADD OBJECT 'Grid1' AS grid WITH ;
|
||||
Anchor = 10, ;
|
||||
BackColor = 244,250,255, ;
|
||||
ColumnCount = 43, ;
|
||||
ColumnCount = 44, ;
|
||||
DeleteMark = .F., ;
|
||||
FontCharSet = 238, ;
|
||||
FontSize = 10, ;
|
||||
@@ -7185,7 +7223,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column2.Width = 71, ;
|
||||
Column3.Alignment = 0, ;
|
||||
Column3.BackColor = 244,250,255, ;
|
||||
Column3.ColumnOrder = 15, ;
|
||||
Column3.ColumnOrder = 16, ;
|
||||
Column3.ControlSource = "fdoc", ;
|
||||
Column3.FontCharSet = 238, ;
|
||||
Column3.FontName = "Arial", ;
|
||||
@@ -7215,7 +7253,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column5.Width = 53, ;
|
||||
Column6.Alignment = 0, ;
|
||||
Column6.BackColor = 244,250,255, ;
|
||||
Column6.ColumnOrder = 7, ;
|
||||
Column6.ColumnOrder = 8, ;
|
||||
Column6.ControlSource = "partd", ;
|
||||
Column6.FontCharSet = 238, ;
|
||||
Column6.FontName = "Arial", ;
|
||||
@@ -7225,7 +7263,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column6.Width = 114, ;
|
||||
Column7.Alignment = 1, ;
|
||||
Column7.BackColor = 244,250,255, ;
|
||||
Column7.ColumnOrder = 10, ;
|
||||
Column7.ColumnOrder = 11, ;
|
||||
Column7.ControlSource = "scd", ;
|
||||
Column7.FontCharSet = 238, ;
|
||||
Column7.FontName = "Arial", ;
|
||||
@@ -7235,7 +7273,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column7.Width = 57, ;
|
||||
Column8.Alignment = 1, ;
|
||||
Column8.BackColor = 244,250,255, ;
|
||||
Column8.ColumnOrder = 12, ;
|
||||
Column8.ColumnOrder = 13, ;
|
||||
Column8.ControlSource = "scc", ;
|
||||
Column8.FontCharSet = 238, ;
|
||||
Column8.FontName = "Arial", ;
|
||||
@@ -7245,7 +7283,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column8.Width = 62, ;
|
||||
Column9.Alignment = 1, ;
|
||||
Column9.BackColor = 244,250,255, ;
|
||||
Column9.ColumnOrder = 14, ;
|
||||
Column9.ColumnOrder = 15, ;
|
||||
Column9.ControlSource = "suma", ;
|
||||
Column9.DynamicForeColor = "IIF(SUMA>=0, RGB(0,0,0), RGB(255,0,0))", ;
|
||||
Column9.FontCharSet = 238, ;
|
||||
@@ -7258,7 +7296,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column9.Width = 93, ;
|
||||
Column10.Alignment = 0, ;
|
||||
Column10.BackColor = 244,250,255, ;
|
||||
Column10.ColumnOrder = 8, ;
|
||||
Column10.ColumnOrder = 9, ;
|
||||
Column10.ControlSource = "partc", ;
|
||||
Column10.FontCharSet = 238, ;
|
||||
Column10.FontName = "Arial", ;
|
||||
@@ -7268,7 +7306,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column10.Width = 100, ;
|
||||
Column11.Alignment = 0, ;
|
||||
Column11.BackColor = 244,250,255, ;
|
||||
Column11.ColumnOrder = 9, ;
|
||||
Column11.ColumnOrder = 10, ;
|
||||
Column11.ControlSource = "explicatia", ;
|
||||
Column11.FontCharSet = 238, ;
|
||||
Column11.FontName = "Arial", ;
|
||||
@@ -7277,7 +7315,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column11.ReadOnly = .F., ;
|
||||
Column11.Width = 77, ;
|
||||
Column12.BackColor = 244,250,255, ;
|
||||
Column12.ColumnOrder = 37, ;
|
||||
Column12.ColumnOrder = 38, ;
|
||||
Column12.ControlSource = "cod", ;
|
||||
Column12.FontCharSet = 238, ;
|
||||
Column12.FontName = "Arial", ;
|
||||
@@ -7286,7 +7324,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column12.ReadOnly = .T., ;
|
||||
Column12.Width = 52, ;
|
||||
Column13.BackColor = 244,250,255, ;
|
||||
Column13.ColumnOrder = 16, ;
|
||||
Column13.ColumnOrder = 17, ;
|
||||
Column13.ControlSource = "pereched", ;
|
||||
Column13.FontCharSet = 238, ;
|
||||
Column13.FontName = "Arial", ;
|
||||
@@ -7295,7 +7333,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column13.ReadOnly = .F., ;
|
||||
Column13.Width = 106, ;
|
||||
Column14.BackColor = 244,250,255, ;
|
||||
Column14.ColumnOrder = 31, ;
|
||||
Column14.ColumnOrder = 32, ;
|
||||
Column14.ControlSource = "explicatia4", ;
|
||||
Column14.FontCharSet = 238, ;
|
||||
Column14.FontName = "Arial", ;
|
||||
@@ -7304,7 +7342,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column14.ReadOnly = .F., ;
|
||||
Column14.Width = 120, ;
|
||||
Column15.BackColor = 244,250,255, ;
|
||||
Column15.ColumnOrder = 24, ;
|
||||
Column15.ColumnOrder = 25, ;
|
||||
Column15.ControlSource = "nrord", ;
|
||||
Column15.FontCharSet = 238, ;
|
||||
Column15.FontName = "Arial", ;
|
||||
@@ -7312,7 +7350,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column15.Name = "Column15", ;
|
||||
Column15.ReadOnly = .F., ;
|
||||
Column16.BackColor = 244,250,255, ;
|
||||
Column16.ColumnOrder = 26, ;
|
||||
Column16.ColumnOrder = 27, ;
|
||||
Column16.ControlSource = "nresp", ;
|
||||
Column16.FontCharSet = 238, ;
|
||||
Column16.FontName = "Arial", ;
|
||||
@@ -7322,7 +7360,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column16.Name = "Column16", ;
|
||||
Column16.ReadOnly = .F., ;
|
||||
Column17.BackColor = 244,250,255, ;
|
||||
Column17.ColumnOrder = 27, ;
|
||||
Column17.ColumnOrder = 28, ;
|
||||
Column17.ControlSource = "dst_chlt", ;
|
||||
Column17.FontCharSet = 238, ;
|
||||
Column17.FontName = "Arial", ;
|
||||
@@ -7332,7 +7370,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column17.Name = "Column17", ;
|
||||
Column17.ReadOnly = .F., ;
|
||||
Column18.BackColor = 244,250,255, ;
|
||||
Column18.ColumnOrder = 32, ;
|
||||
Column18.ColumnOrder = 33, ;
|
||||
Column18.ControlSource = "explicatia5", ;
|
||||
Column18.FontCharSet = 238, ;
|
||||
Column18.FontName = "Arial", ;
|
||||
@@ -7341,7 +7379,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column18.ReadOnly = .F., ;
|
||||
Column18.Width = 119, ;
|
||||
Column19.BackColor = 244,250,255, ;
|
||||
Column19.ColumnOrder = 23, ;
|
||||
Column19.ColumnOrder = 24, ;
|
||||
Column19.ControlSource = "datascad", ;
|
||||
Column19.FontCharSet = 238, ;
|
||||
Column19.FontName = "Arial", ;
|
||||
@@ -7351,7 +7389,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column19.Visible = .T., ;
|
||||
Column19.Width = 87, ;
|
||||
Column20.BackColor = 244,250,255, ;
|
||||
Column20.ColumnOrder = 28, ;
|
||||
Column20.ColumnOrder = 29, ;
|
||||
Column20.ControlSource = "suma_val", ;
|
||||
Column20.FontCharSet = 238, ;
|
||||
Column20.FontName = "Arial", ;
|
||||
@@ -7361,7 +7399,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column20.ReadOnly = .F., ;
|
||||
Column20.Width = 89, ;
|
||||
Column21.BackColor = 244,250,255, ;
|
||||
Column21.ColumnOrder = 30, ;
|
||||
Column21.ColumnOrder = 31, ;
|
||||
Column21.ControlSource = "curs", ;
|
||||
Column21.FontCharSet = 238, ;
|
||||
Column21.FontName = "Arial", ;
|
||||
@@ -7371,7 +7409,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column21.ReadOnly = .F., ;
|
||||
Column21.Width = 72, ;
|
||||
Column22.BackColor = 244,250,255, ;
|
||||
Column22.ColumnOrder = 33, ;
|
||||
Column22.ColumnOrder = 34, ;
|
||||
Column22.ControlSource = "gestin", ;
|
||||
Column22.FontCharSet = 238, ;
|
||||
Column22.FontName = "Arial", ;
|
||||
@@ -7380,7 +7418,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column22.ReadOnly = .F., ;
|
||||
Column22.Width = 116, ;
|
||||
Column23.BackColor = 244,250,255, ;
|
||||
Column23.ColumnOrder = 11, ;
|
||||
Column23.ColumnOrder = 12, ;
|
||||
Column23.ControlSource = "ascd", ;
|
||||
Column23.FontCharSet = 238, ;
|
||||
Column23.FontName = "Arial", ;
|
||||
@@ -7389,7 +7427,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column23.ReadOnly = .F., ;
|
||||
Column23.Width = 46, ;
|
||||
Column24.BackColor = 244,250,255, ;
|
||||
Column24.ColumnOrder = 13, ;
|
||||
Column24.ColumnOrder = 14, ;
|
||||
Column24.ControlSource = "ascc", ;
|
||||
Column24.FontCharSet = 238, ;
|
||||
Column24.FontName = "Arial", ;
|
||||
@@ -7398,7 +7436,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column24.ReadOnly = .F., ;
|
||||
Column24.Width = 48, ;
|
||||
Column25.BackColor = 244,250,255, ;
|
||||
Column25.ColumnOrder = 38, ;
|
||||
Column25.ColumnOrder = 39, ;
|
||||
Column25.ControlSource = "id_set", ;
|
||||
Column25.FontCharSet = 238, ;
|
||||
Column25.FontName = "Arial", ;
|
||||
@@ -7407,7 +7445,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column25.ReadOnly = .T., ;
|
||||
Column25.Width = 71, ;
|
||||
Column26.BackColor = 244,250,255, ;
|
||||
Column26.ColumnOrder = 19, ;
|
||||
Column26.ColumnOrder = 20, ;
|
||||
Column26.ControlSource = "proc_tva", ;
|
||||
Column26.FontCharSet = 238, ;
|
||||
Column26.FontName = "Arial", ;
|
||||
@@ -7416,7 +7454,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column26.ReadOnly = .T., ;
|
||||
Column26.Width = 54, ;
|
||||
Column27.BackColor = 244,250,255, ;
|
||||
Column27.ColumnOrder = 17, ;
|
||||
Column27.ColumnOrder = 18, ;
|
||||
Column27.ControlSource = "perechec", ;
|
||||
Column27.FontCharSet = 238, ;
|
||||
Column27.FontName = "Arial", ;
|
||||
@@ -7425,7 +7463,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column27.ReadOnly = .F., ;
|
||||
Column27.Width = 104, ;
|
||||
Column28.BackColor = 244,250,255, ;
|
||||
Column28.ColumnOrder = 35, ;
|
||||
Column28.ColumnOrder = 36, ;
|
||||
Column28.ControlSource = "sectie", ;
|
||||
Column28.FontCharSet = 238, ;
|
||||
Column28.FontName = "Arial", ;
|
||||
@@ -7434,7 +7472,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column28.ReadOnly = .F., ;
|
||||
Column28.Width = 88, ;
|
||||
Column29.BackColor = 244,250,255, ;
|
||||
Column29.ColumnOrder = 29, ;
|
||||
Column29.ColumnOrder = 30, ;
|
||||
Column29.ControlSource = "nume_val", ;
|
||||
Column29.FontCharSet = 238, ;
|
||||
Column29.FontName = "Arial", ;
|
||||
@@ -7443,7 +7481,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column29.ReadOnly = .F., ;
|
||||
Column29.Width = 79, ;
|
||||
Column30.BackColor = 244,250,255, ;
|
||||
Column30.ColumnOrder = 39, ;
|
||||
Column30.ColumnOrder = 40, ;
|
||||
Column30.ControlSource = "id_partd", ;
|
||||
Column30.FontCharSet = 238, ;
|
||||
Column30.FontName = "Arial", ;
|
||||
@@ -7452,7 +7490,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column30.ReadOnly = .T., ;
|
||||
Column30.Width = 55, ;
|
||||
Column31.BackColor = 244,250,255, ;
|
||||
Column31.ColumnOrder = 40, ;
|
||||
Column31.ColumnOrder = 41, ;
|
||||
Column31.ControlSource = "id_partc", ;
|
||||
Column31.FontCharSet = 238, ;
|
||||
Column31.FontName = "Arial", ;
|
||||
@@ -7461,7 +7499,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column31.ReadOnly = .T., ;
|
||||
Column31.Width = 55, ;
|
||||
Column32.BackColor = 244,250,255, ;
|
||||
Column32.ColumnOrder = 34, ;
|
||||
Column32.ColumnOrder = 35, ;
|
||||
Column32.ControlSource = "gestout", ;
|
||||
Column32.FontCharSet = 238, ;
|
||||
Column32.FontName = "Arial", ;
|
||||
@@ -7470,7 +7508,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column32.ReadOnly = .F., ;
|
||||
Column32.Width = 92, ;
|
||||
Column33.BackColor = 244,250,255, ;
|
||||
Column33.ColumnOrder = 36, ;
|
||||
Column33.ColumnOrder = 37, ;
|
||||
Column33.ControlSource = "sucursala", ;
|
||||
Column33.FontCharSet = 238, ;
|
||||
Column33.FontName = "Arial", ;
|
||||
@@ -7479,7 +7517,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column33.ReadOnly = .F., ;
|
||||
Column33.Width = 121, ;
|
||||
Column34.BackColor = 244,250,255, ;
|
||||
Column34.ColumnOrder = 25, ;
|
||||
Column34.ColumnOrder = 26, ;
|
||||
Column34.ControlSource = "contract", ;
|
||||
Column34.FontCharSet = 238, ;
|
||||
Column34.FontName = "Arial", ;
|
||||
@@ -7488,7 +7526,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column34.ReadOnly = .T., ;
|
||||
Column34.Width = 65, ;
|
||||
Column35.BackColor = 244,250,255, ;
|
||||
Column35.ColumnOrder = 20, ;
|
||||
Column35.ColumnOrder = 21, ;
|
||||
Column35.ControlSource = "explicatie_tva", ;
|
||||
Column35.FontCharSet = 238, ;
|
||||
Column35.FontName = "Arial", ;
|
||||
@@ -7497,7 +7535,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column35.ReadOnly = .F., ;
|
||||
Column35.Width = 136, ;
|
||||
Column36.BackColor = 244,250,255, ;
|
||||
Column36.ColumnOrder = 18, ;
|
||||
Column36.ColumnOrder = 19, ;
|
||||
Column36.ControlSource = "cu_tva", ;
|
||||
Column36.FontCharSet = 238, ;
|
||||
Column36.FontName = "Arial", ;
|
||||
@@ -7517,7 +7555,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column37.ReadOnly = .F., ;
|
||||
Column37.Width = 58, ;
|
||||
Column38.BackColor = 244,250,255, ;
|
||||
Column38.ColumnOrder = 41, ;
|
||||
Column38.ColumnOrder = 42, ;
|
||||
Column38.ControlSource = "id_fact", ;
|
||||
Column38.FontCharSet = 238, ;
|
||||
Column38.FontName = "Arial", ;
|
||||
@@ -7526,7 +7564,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column38.ReadOnly = .T., ;
|
||||
Column38.Width = 94, ;
|
||||
Column39.BackColor = 244,250,255, ;
|
||||
Column39.ColumnOrder = 42, ;
|
||||
Column39.ColumnOrder = 43, ;
|
||||
Column39.ControlSource = "id_factd", ;
|
||||
Column39.FontCharSet = 238, ;
|
||||
Column39.FontName = "Arial", ;
|
||||
@@ -7535,7 +7573,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column39.ReadOnly = .T., ;
|
||||
Column39.Width = 75, ;
|
||||
Column40.BackColor = 244,250,255, ;
|
||||
Column40.ColumnOrder = 43, ;
|
||||
Column40.ColumnOrder = 44, ;
|
||||
Column40.ControlSource = "id_factc", ;
|
||||
Column40.FontCharSet = 238, ;
|
||||
Column40.FontName = "Arial", ;
|
||||
@@ -7555,7 +7593,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column41.Width = 22, ;
|
||||
Column42.BackColor = 244,250,255, ;
|
||||
Column42.Bound = .F., ;
|
||||
Column42.ColumnOrder = 21, ;
|
||||
Column42.ColumnOrder = 22, ;
|
||||
Column42.ControlSource = "Iif(Seek(tAct.taxcode,'saft_taxtable','taxcode'),saft_taxtable.taxname,'')", ;
|
||||
Column42.CurrentControl = "_combobox1", ;
|
||||
Column42.FontCharSet = 238, ;
|
||||
@@ -7566,7 +7604,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column42.Width = 184, ;
|
||||
Column43.BackColor = 244,250,255, ;
|
||||
Column43.Bound = .F., ;
|
||||
Column43.ColumnOrder = 22, ;
|
||||
Column43.ColumnOrder = 23, ;
|
||||
Column43.ControlSource = "Iif(Seek(tAct.paymentcode,'saft_mecanisme_plati','mcode'),saft_mecanisme_plati.paymentname,'')", ;
|
||||
Column43.CurrentControl = "_combobox1", ;
|
||||
Column43.FontCharSet = 238, ;
|
||||
@@ -7574,7 +7612,17 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Column43.Name = "Column43", ;
|
||||
Column43.ReadOnly = .F., ;
|
||||
Column43.Sparse = .F., ;
|
||||
Column43.Width = 146
|
||||
Column43.Width = 146, ;
|
||||
Column44.Alignment = 1, ;
|
||||
Column44.BackColor = 244,250,255, ;
|
||||
Column44.ColumnOrder = 7, ;
|
||||
Column44.ControlSource = "nnir", ;
|
||||
Column44.FontCharSet = 238, ;
|
||||
Column44.FontName = "Arial", ;
|
||||
Column44.FontSize = 10, ;
|
||||
Column44.Name = "Column44", ;
|
||||
Column44.ReadOnly = .F., ;
|
||||
Column44.Width = 60
|
||||
*< END OBJECT: BaseClass="grid" />
|
||||
|
||||
ADD OBJECT 'Grid1.cAles._CHECKBOX1' AS _checkbox WITH ;
|
||||
@@ -8442,6 +8490,29 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
SelectedBackColor = 49,106,197
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'Grid1.Column44.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Nr. NIR", ;
|
||||
FontCharSet = 238, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1"
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'Grid1.Column44.Text1' AS textbox WITH ;
|
||||
Alignment = 1, ;
|
||||
BackColor = 244,250,255, ;
|
||||
BorderStyle = 0, ;
|
||||
FontCharSet = 238, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .F., ;
|
||||
SelectedBackColor = 49,106,197
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'Grid1.Column5.Header5' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Nr.Doc.", ;
|
||||
@@ -8592,6 +8663,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
Height = 142, ;
|
||||
Left = 5, ;
|
||||
Name = "pgfArticole", ;
|
||||
PageCount = 3, ;
|
||||
Top = 361, ;
|
||||
Width = 764, ;
|
||||
ZOrderSet = 0, ;
|
||||
@@ -8600,7 +8672,10 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
PAGE1.Name = "PAGE1", ;
|
||||
PAGE2.Caption = "Rulaje obiecte inventar in folosinta (8039)", ;
|
||||
PAGE2.ForeColor = 0,128,64, ;
|
||||
PAGE2.Name = "PAGE2"
|
||||
PAGE2.Name = "PAGE2", ;
|
||||
PAGE3.Caption = "Articole factura", ;
|
||||
PAGE3.ForeColor = 128,0,128, ;
|
||||
PAGE3.Name = "PAGE3"
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="pageframe" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE1._grdfooter1' AS _grdfooter WITH ;
|
||||
@@ -12179,6 +12254,374 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura' AS _grdrow WITH ;
|
||||
Anchor = 15, ;
|
||||
ColumnCount = 13, ;
|
||||
DeleteMark = .F., ;
|
||||
FontSize = 10, ;
|
||||
GridLineColor = 128,128,128, ;
|
||||
HeaderHeight = 35, ;
|
||||
Height = 107, ;
|
||||
Left = 0, ;
|
||||
Name = "grdArticoleFactura", ;
|
||||
ReadOnly = .T., ;
|
||||
RecordSource = "tvd", ;
|
||||
RowHeight = 19, ;
|
||||
TabIndex = 4, ;
|
||||
Tag = "RESIZABLE", ;
|
||||
Top = 0, ;
|
||||
Width = 759, ;
|
||||
ZOrderSet = 1, ;
|
||||
Column1.ControlSource = "tvd.denumire", ;
|
||||
Column1.FontName = "Arial", ;
|
||||
Column1.FontSize = 10, ;
|
||||
Column1.Name = "cDenumireArt", ;
|
||||
Column1.Width = 170, ;
|
||||
Column2.ControlSource = "tvd.codmat", ;
|
||||
Column2.FontName = "Arial", ;
|
||||
Column2.FontSize = 10, ;
|
||||
Column2.Name = "cCodmatArt", ;
|
||||
Column2.Width = 90, ;
|
||||
Column3.ControlSource = "tvd.serie", ;
|
||||
Column3.FontName = "Arial", ;
|
||||
Column3.FontSize = 10, ;
|
||||
Column3.Name = "cSerieArt", ;
|
||||
Column3.Width = 70, ;
|
||||
Column4.ControlSource = "tvd.lot", ;
|
||||
Column4.FontName = "Arial", ;
|
||||
Column4.FontSize = 10, ;
|
||||
Column4.Name = "cLotArt", ;
|
||||
Column4.Width = 60, ;
|
||||
Column5.ControlSource = "tvd.cantitate", ;
|
||||
Column5.FontName = "Arial", ;
|
||||
Column5.FontSize = 10, ;
|
||||
Column5.Format = "R", ;
|
||||
Column5.InputMask = (get_mask(12,gnPCANT)), ;
|
||||
Column5.Name = "cCantitateArt", ;
|
||||
Column5.Width = 70, ;
|
||||
Column6.ControlSource = "tvd.pret", ;
|
||||
Column6.FontName = "Arial", ;
|
||||
Column6.FontSize = 10, ;
|
||||
Column6.Format = "R", ;
|
||||
Column6.InputMask = (get_mask(12,gnPPRET)), ;
|
||||
Column6.Name = "cPretArt", ;
|
||||
Column6.Width = 70, ;
|
||||
Column7.ControlSource = "tvd.pret_cu_tva", ;
|
||||
Column7.FontName = "Arial", ;
|
||||
Column7.FontSize = 10, ;
|
||||
Column7.Format = "R", ;
|
||||
Column7.InputMask = (get_mask(12,gnPPRET)), ;
|
||||
Column7.Name = "cPretCuTvaArt", ;
|
||||
Column7.Width = 80, ;
|
||||
Column8.ControlSource = "tvd.proc_tvav", ;
|
||||
Column8.FontName = "Arial", ;
|
||||
Column8.FontSize = 10, ;
|
||||
Column8.Format = "R", ;
|
||||
Column8.InputMask = "9.99", ;
|
||||
Column8.Name = "cProcTvavArt", ;
|
||||
Column8.Width = 55, ;
|
||||
Column9.ControlSource = "tvd.discount_unitar", ;
|
||||
Column9.FontName = "Arial", ;
|
||||
Column9.FontSize = 10, ;
|
||||
Column9.Format = "R", ;
|
||||
Column9.InputMask = (get_mask(12,gnPPRET)), ;
|
||||
Column9.Name = "cDiscountUnitarArt", ;
|
||||
Column9.Width = 90, ;
|
||||
Column10.ControlSource = "tvd.nume_gestiune", ;
|
||||
Column10.FontName = "Arial", ;
|
||||
Column10.FontSize = 10, ;
|
||||
Column10.Name = "cGestiuneArt", ;
|
||||
Column10.Width = 90, ;
|
||||
Column11.ControlSource = "tvd.nume_val", ;
|
||||
Column11.FontName = "Arial", ;
|
||||
Column11.FontSize = 10, ;
|
||||
Column11.Name = "cValutaArt", ;
|
||||
Column11.Width = 60, ;
|
||||
Column12.ControlSource = "tvd.explicatie", ;
|
||||
Column12.FontName = "Arial", ;
|
||||
Column12.FontSize = 10, ;
|
||||
Column12.Name = "cExplicatieArt", ;
|
||||
Column12.Width = 150, ;
|
||||
Column13.ControlSource = "tvd.taxcode", ;
|
||||
Column13.FontName = "Arial", ;
|
||||
Column13.FontSize = 10, ;
|
||||
Column13.Name = "cTaxcodeArt", ;
|
||||
Column13.Width = 60
|
||||
*< END OBJECT: ClassLib="_grd_base.vcx" BaseClass="grid" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Cantitate", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cCodmatArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Cod material", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cCodmatArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cDenumireArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Articol", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cDenumireArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cDiscountUnitarArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Discount unitar", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cDiscountUnitarArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cExplicatieArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Explicatie", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cExplicatieArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cGestiuneArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Gestiune", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cGestiuneArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cLotArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Lot", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cLotArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Pret", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Pret cu TVA", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cProcTvavArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "TVA %", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cProcTvavArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cSerieArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Serie", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cSerieArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cTaxcodeArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Taxcode", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cTaxcodeArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cValutaArt.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Valuta", ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cValutaArt.Text1' AS textbox WITH ;
|
||||
BackColor = 225,225,225, ;
|
||||
BorderStyle = 0, ;
|
||||
FontName = "Arial", ;
|
||||
FontSize = 10, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T., ;
|
||||
SelectedBackColor = 100,185,255
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT 'txtSuma' AS _textbox WITH ;
|
||||
Alignment = 3, ;
|
||||
Anchor = 8, ;
|
||||
@@ -13027,13 +13470,16 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE do_modifica_explicatie_tva
|
||||
LOCAL lnCotaFiltru
|
||||
If tact.cu_tva = 1
|
||||
*!* modificare ROACONT v 2.4.4
|
||||
*!* filtreaza explicatiile dupa cota TVA a liniei curente; proc_tva e in forma 1.19, cota 0/gol = fara filtru
|
||||
lnCotaFiltru = Round((Nvl(tact.proc_tva,0) - 1) * 100, 2)
|
||||
If TYPE('tact.tipnota') = 'N' AND tact.tipnota = 1
|
||||
*!* explicatii TVA exigibile din JC ( 1 ), JV ( 3 ) sau toate ( 5 )
|
||||
locauta = caut_explicatie_tva(Nvl(tact.id_jtva_coloana,-1),,,iif(tact.scc=[4428],1,iif(tact.scd=[4428],3,5)))
|
||||
locauta = caut_explicatie_tva(Nvl(tact.id_jtva_coloana,-1),,,iif(tact.scc=[4428],1,iif(tact.scd=[4428],3,5)),lnCotaFiltru)
|
||||
Else
|
||||
locauta = caut_explicatie_tva(Nvl(tact.id_jtva_coloana,-1))
|
||||
locauta = caut_explicatie_tva(Nvl(tact.id_jtva_coloana,-1),,,,lnCotaFiltru)
|
||||
Endif
|
||||
*!* locauta = caut_explicatie_tva(Nvl(tact.id_jtva_coloana,-1))
|
||||
*!* modificare ROACONT v 2.4.4 ^
|
||||
@@ -13613,6 +14059,9 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
This.grid1.Anchor = 11
|
||||
This.but_renunt1.Anchor = 8
|
||||
|
||||
If This.nid_set = 90101
|
||||
This.grid1.Column44.ReadOnly = .T.
|
||||
Endif
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Load
|
||||
@@ -13623,6 +14072,16 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
If !Used('saft_mecanisme_plati')
|
||||
update_saft_mecanisme_plati()
|
||||
ENDIF
|
||||
|
||||
*!* cursorul tvd, gol - din functia comuna daca ofacturare_editare.prg e incarcat
|
||||
If !Used('tvd')
|
||||
IF "OFACTURARE_EDITARE" $ Upper(Set("Procedure"))
|
||||
CreeazaCursorTvdGol()
|
||||
ELSE
|
||||
*!* structura se repeta: in ROACONT/ROAGEST functia comuna nu e incarcata
|
||||
CREATE CURSOR tvd (id_vanzare I, id_vanzare_det I, id_articol I, cantitate N(12,3), pret N(14,4), pret_cu_tva N(14,4), proc_tvav N(6,4), discount_unitar N(14,4), id_gestiune I, cont C(20), id_valuta I, id_jtva_coloana I, serie C(20), explicatie C(60), taxcode I, lot C(20), sters I, denumire C(100), codmat C(30), nume_gestiune C(60), nume_val C(20))
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Resize
|
||||
@@ -13683,6 +14142,19 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
|
||||
this.gridextra1.setup()
|
||||
LOCAL lcPrefFile, lcPrefFileContents, lcKey, lcPrefs
|
||||
LOCAL ARRAY laNnirPrefs(1)
|
||||
lcPrefFile = This.gridextra1.GetUserApplicationDataPath() + This.gridextra1.GridPreferenceFile
|
||||
lcPrefFileContents = ""
|
||||
IF FILE(m.lcPrefFile)
|
||||
lcPrefFileContents = FILETOSTR(m.lcPrefFile)
|
||||
ENDIF
|
||||
lcKey = SYS(1272, This.grid1) + "("
|
||||
lcPrefs = STREXTRACT(m.lcPrefFileContents, m.lcKey, ")", 1, 1)
|
||||
*!* pozitioneaza coloana la prima deschidere, cat timp preferintele salvate nu o acopera
|
||||
IF EMPTY(m.lcPrefs) OR ALINES(laNnirPrefs, m.lcPrefs, 7, ",") < This.grid1.ColumnCount * 2
|
||||
This.grid1.Column44.ColumnOrder = 7
|
||||
ENDIF
|
||||
this.grid1.SetAll("dynamicbackcolor", "IIF(ALES, RGB(255,255,225), RGB(255,255,255))", "Column")
|
||||
This.CalculeazaTotal()
|
||||
*!* 24.05.2011 ^
|
||||
@@ -13697,6 +14169,27 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
This.Grid1.HeaderHeight = 37
|
||||
this.pgfArticole.page1.grdRulaje.HeaderHeight = 37
|
||||
this.pgfArticole.page2.grdRulajeObinv.HeaderHeight = 37
|
||||
* pagina de articole factura (VANZARI/VANZARI_DETALII) - apare doar cand ofacturare_editare.prg
|
||||
* e incarcat (doar ROAFACTURARE - ROACONT/ROAGEST nu-l inregistreaza) si documentul are rand in vanzari
|
||||
This.lAreArticoleVanzari = .F.
|
||||
This.nIdVanzare = 0
|
||||
This.nTipVanzare = 0
|
||||
IF "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) AND Reccount('tact') > 0
|
||||
IncarcaVanzareDinNota('tact')
|
||||
IF Reccount('tvanz') = 1
|
||||
This.lAreArticoleVanzari = .T.
|
||||
This.nIdVanzare = tvanz.id_vanzare
|
||||
This.nTipVanzare = tvanz.tip
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
IF This.lAreArticoleVanzari
|
||||
IncarcaArticoleFactura(This.nIdVanzare)
|
||||
This.pgfArticole.PageCount = 3
|
||||
ELSE
|
||||
This.pgfArticole.PageCount = 2
|
||||
ENDIF
|
||||
|
||||
|
||||
This.grid1.column42.visible = m.gl406 && saft taxa
|
||||
This.grid1.column43.visible = m.gl406 && saft plata
|
||||
@@ -13717,6 +14210,37 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE sincronizeaza_nnir
|
||||
*!* propaga NNIR-ul modificat pe toate liniile notei si pe rulajele asociate
|
||||
LPARAMETERS tnNnirVechi, tnNnirNou
|
||||
LOCAL lcSelect, lnRecno
|
||||
IF NVL(m.tnNnirVechi, 0) = NVL(m.tnNnirNou, 0)
|
||||
RETURN
|
||||
ENDIF
|
||||
lcSelect = SELECT()
|
||||
lnRecno = RECNO('tact')
|
||||
UPDATE tact SET nnir = m.tnNnirNou WHERE NVL(nnir, 0) = m.tnNnirVechi
|
||||
IF USED('trul')
|
||||
UPDATE trul SET nnir = m.tnNnirNou WHERE NVL(nnir, 0) = m.tnNnirVechi
|
||||
IF _TALLY > 0
|
||||
Thisform.pgfArticole.page1.grdRulaje.Refresh()
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF USED('trul_obinv')
|
||||
UPDATE trul_obinv SET nnir = m.tnNnirNou WHERE NVL(nnir, 0) = m.tnNnirVechi
|
||||
IF _TALLY > 0
|
||||
Thisform.pgfArticole.page2.grdRulajeObinv.Refresh()
|
||||
ENDIF
|
||||
ENDIF
|
||||
SELECT tact
|
||||
IF BETWEEN(m.lnRecno, 1, RECCOUNT('tact'))
|
||||
GO m.lnRecno
|
||||
ELSE
|
||||
GO TOP
|
||||
ENDIF
|
||||
SELECT (m.lcSelect)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE updateexplicatiesaft
|
||||
* Daca nu este activata SAFT 406 nu fac nimic
|
||||
IF !m.gl406
|
||||
@@ -14201,6 +14725,10 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
.Column35.ReadOnly = .T. && cod
|
||||
.Column25.ReadOnly = .T. && id_set
|
||||
ENDWITH
|
||||
*!* pastreaza blocarea NNIR pentru notele de inventar (id_set = 90101)
|
||||
IF Thisform.nid_set = 90101
|
||||
This.Column44.ReadOnly = .T.
|
||||
ENDIF
|
||||
*!* 10.08.2011 ^
|
||||
*!* pot selecta inregistrari din alte sucursale pentru operatiile de copiere, adaugare care
|
||||
This.cAles.ReadOnly = .F.
|
||||
@@ -14674,6 +15202,19 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
||||
thisform.cPaymentCode = ALLTRIM(tAct.paymentcode)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Grid1.Column44.Text1.LostFocus
|
||||
Local lnNnirNou, lnNnirVechi
|
||||
lnNnirVechi = thisform.nnnirvechi
|
||||
lnNnirNou = NVL(tAct.nnir, 0)
|
||||
Thisform.sincronizeaza_nnir(m.lnNnirVechi, m.lnNnirNou)
|
||||
Thisform.nnnirvechi = m.lnNnirNou
|
||||
Thisform.Grid1.Refresh()
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Grid1.Column44.Text1.When
|
||||
Thisform.nnnirvechi = NVL(tAct.nnir, 0)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE Grid1.Column6.Text1.InteractiveChange
|
||||
ADDPROPERTY(this, 'lInteractiveChange')
|
||||
LOCAL lnIdPart
|
||||
|
||||
@@ -25,7 +25,7 @@ DEFINE CLASS actualizare_curs_bnr AS _custom OF "_baza.vcx"
|
||||
|
||||
*<PropValue>
|
||||
ccursor = ccrsbnr
|
||||
clink = https://www.bnr.ro/nbrfxrates.xml
|
||||
clink = https://curs.bnr.ro/nbrfxrates.xml
|
||||
ctempfile = C:\temp\temp.xml
|
||||
ddata = {}
|
||||
Height = 17
|
||||
|
||||
@@ -3063,6 +3063,31 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataOraV.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cUtilV.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cUtilV.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataOravAnaf.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataOravAnaf.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cTvaIncasare.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cTvaIncasare.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cTvaIncasare._checkbox1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cSplitTva.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cSplitTva.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cSplitTva._checkbox1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cInactiv.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cInactiv.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cInactiv._checkbox1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputScpTva.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputScpTva.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitScpTva.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitScpTva.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataAnulImpScpTva.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataAnulImpScpTva.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputTvaInc.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataInceputTvaInc.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitTvaInc.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataSfarsitTvaInc.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataInactivare.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataInactivare.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataReactivare.Header1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="_grdbase1.cDataReactivare.Text1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="Gridextra1" UniqueID="" Timestamp="" />
|
||||
*< OBJECTDATA: ObjPath="lblInfo" UniqueID="" Timestamp="" />
|
||||
|
||||
@@ -3112,7 +3137,7 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
|
||||
ADD OBJECT '_grdbase1' AS _grdbase WITH ;
|
||||
Anchor = 15, ;
|
||||
ColumnCount = 16, ;
|
||||
ColumnCount = 27, ;
|
||||
DeleteMark = .F., ;
|
||||
HeaderHeight = 32, ;
|
||||
Height = 190, ;
|
||||
@@ -3157,19 +3182,19 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Column6.ControlSource = "codpostal", ;
|
||||
Column6.Name = "cCodPostal", ;
|
||||
Column6.ReadOnly = .T., ;
|
||||
Column6.Visible = .T., ;
|
||||
Column6.Visible = .F., ;
|
||||
Column6.Width = 75, ;
|
||||
Column7.ColumnOrder = 11, ;
|
||||
Column7.ControlSource = "telefon", ;
|
||||
Column7.Name = "cTelefon", ;
|
||||
Column7.ReadOnly = .T., ;
|
||||
Column7.Visible = .T., ;
|
||||
Column7.Visible = .F., ;
|
||||
Column7.Width = 75, ;
|
||||
Column8.ColumnOrder = 12, ;
|
||||
Column8.ControlSource = "fax", ;
|
||||
Column8.Name = "cFax", ;
|
||||
Column8.ReadOnly = .T., ;
|
||||
Column8.Visible = .T., ;
|
||||
Column8.Visible = .F., ;
|
||||
Column8.Width = 75, ;
|
||||
Column9.ColumnOrder = 6, ;
|
||||
Column9.ControlSource = "platitortvavies", ;
|
||||
@@ -3177,7 +3202,7 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Column9.Name = "cPlatitorTVAVies", ;
|
||||
Column9.ReadOnly = .T., ;
|
||||
Column9.Sparse = .F., ;
|
||||
Column9.Visible = .T., ;
|
||||
Column9.Visible = .F., ;
|
||||
Column9.Width = 54, ;
|
||||
Column10.ColumnOrder = 5, ;
|
||||
Column10.ControlSource = "datatvamfin", ;
|
||||
@@ -3210,7 +3235,57 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Column16.ControlSource = "utilv", ;
|
||||
Column16.Name = "cUtilV", ;
|
||||
Column16.ReadOnly = .T., ;
|
||||
Column16.Width = 114
|
||||
Column16.Width = 114, ;
|
||||
Column17.ControlSource = "dataorav_anaf", ;
|
||||
Column17.Name = "cDataOravAnaf", ;
|
||||
Column17.ReadOnly = .T., ;
|
||||
Column17.Width = 85, ;
|
||||
Column18.ControlSource = "tvaincasare", ;
|
||||
Column18.CurrentControl = "_checkbox1", ;
|
||||
Column18.Name = "cTvaIncasare", ;
|
||||
Column18.ReadOnly = .T., ;
|
||||
Column18.Sparse = .F., ;
|
||||
Column18.Width = 54, ;
|
||||
Column19.ControlSource = "splittva", ;
|
||||
Column19.CurrentControl = "_checkbox1", ;
|
||||
Column19.Name = "cSplitTva", ;
|
||||
Column19.ReadOnly = .T., ;
|
||||
Column19.Sparse = .F., ;
|
||||
Column19.Width = 54, ;
|
||||
Column20.ControlSource = "inactiv", ;
|
||||
Column20.CurrentControl = "_checkbox1", ;
|
||||
Column20.Name = "cInactiv", ;
|
||||
Column20.ReadOnly = .T., ;
|
||||
Column20.Sparse = .F., ;
|
||||
Column20.Width = 54, ;
|
||||
Column21.ControlSource = "data_inceput_scptva", ;
|
||||
Column21.Name = "cDataInceputScpTva", ;
|
||||
Column21.ReadOnly = .T., ;
|
||||
Column21.Width = 85, ;
|
||||
Column22.ControlSource = "data_sfarsit_scptva", ;
|
||||
Column22.Name = "cDataSfarsitScpTva", ;
|
||||
Column22.ReadOnly = .T., ;
|
||||
Column22.Width = 85, ;
|
||||
Column23.ControlSource = "data_anul_imp_scptva", ;
|
||||
Column23.Name = "cDataAnulImpScpTva", ;
|
||||
Column23.ReadOnly = .T., ;
|
||||
Column23.Width = 85, ;
|
||||
Column24.ControlSource = "data_inceput_tvainc", ;
|
||||
Column24.Name = "cDataInceputTvaInc", ;
|
||||
Column24.ReadOnly = .T., ;
|
||||
Column24.Width = 85, ;
|
||||
Column25.ControlSource = "data_sfarsit_tvainc", ;
|
||||
Column25.Name = "cDataSfarsitTvaInc", ;
|
||||
Column25.ReadOnly = .T., ;
|
||||
Column25.Width = 85, ;
|
||||
Column26.ControlSource = "data_inactivare", ;
|
||||
Column26.Name = "cDataInactivare", ;
|
||||
Column26.ReadOnly = .T., ;
|
||||
Column26.Width = 85, ;
|
||||
Column27.ControlSource = "data_reactivare", ;
|
||||
Column27.Name = "cDataReactivare", ;
|
||||
Column27.ReadOnly = .T., ;
|
||||
Column27.Width = 85
|
||||
*< END OBJECT: ClassLib="_grd_base.vcx" BaseClass="grid" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cAdresa.Header1' AS header WITH ;
|
||||
@@ -3261,6 +3336,70 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Visible = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataAnulImpScpTva.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Anulare scutire TVA", ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataAnulImpScpTva.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataInactivare.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Data inactivare", ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataInactivare.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataInceputScpTva.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Inceput scutire TVA", ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataInceputScpTva.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataInceputTvaInc.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Inceput TVA incasare", ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataInceputTvaInc.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataOra.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Creat la", ;
|
||||
@@ -3289,6 +3428,69 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Name = "Text1"
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataOravAnaf.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Data ANAF", ;
|
||||
Name = "Header1"
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataOravAnaf.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataReactivare.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Data reactivare", ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataReactivare.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataSfarsitScpTva.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Sfarsit scutire TVA", ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataSfarsitScpTva.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataSfarsitTvaInc.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Sfarsit TVA incasare", ;
|
||||
Name = "Header1", ;
|
||||
WordWrap = .T.
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataSfarsitTvaInc.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1", ;
|
||||
ReadOnly = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cDataTVAMfin.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Data TVA MFIN", ;
|
||||
@@ -3337,6 +3539,29 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Visible = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cInactiv._checkbox1' AS _checkbox WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "", ;
|
||||
Left = 19, ;
|
||||
Name = "_checkbox1", ;
|
||||
ReadOnly = .T., ;
|
||||
Top = 96
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cInactiv.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Inactiv", ;
|
||||
Name = "Header1"
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cInactiv.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1"
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cJudet.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Judet", ;
|
||||
@@ -3418,6 +3643,29 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Visible = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cSplitTva._checkbox1' AS _checkbox WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "", ;
|
||||
Left = 19, ;
|
||||
Name = "_checkbox1", ;
|
||||
ReadOnly = .T., ;
|
||||
Top = 120
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cSplitTva.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Split TVA", ;
|
||||
Name = "Header1"
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cSplitTva.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1"
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cStare.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Stare", ;
|
||||
@@ -3448,6 +3696,29 @@ DEFINE CLASS frm_verificare_parteneri_istoric AS _frmbase OF "_frm_base.vcx"
|
||||
Visible = .T.
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cTvaIncasare._checkbox1' AS _checkbox WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "", ;
|
||||
Left = 19, ;
|
||||
Name = "_checkbox1", ;
|
||||
ReadOnly = .T., ;
|
||||
Top = 144
|
||||
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="checkbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cTvaIncasare.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "TVA incasare", ;
|
||||
Name = "Header1"
|
||||
*< END OBJECT: BaseClass="header" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cTvaIncasare.Text1' AS textbox WITH ;
|
||||
BackColor = 255,255,255, ;
|
||||
BorderStyle = 0, ;
|
||||
ForeColor = 0,0,0, ;
|
||||
Margin = 0, ;
|
||||
Name = "Text1"
|
||||
*< END OBJECT: BaseClass="textbox" />
|
||||
|
||||
ADD OBJECT '_grdbase1.cUtil.Header1' AS header WITH ;
|
||||
Alignment = 2, ;
|
||||
Caption = "Creat de", ;
|
||||
|
||||
17
docs/capcana_grid_preferinte_utilizator.md
Normal file
17
docs/capcana_grid_preferinte_utilizator.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Capcana: coloana noua intr-un grid existent ajunge la coada (preferinte GridExtras)
|
||||
|
||||
`GridExtras` (`COMUN\utile\GridExtras\gridextras.vc2:1051`, `restoregridpreferences` /
|
||||
`savegridpreferences`) salveaza **per utilizator** latimea si ordinea coloanelor fiecarui grid,
|
||||
in `%APPDATA%\...\gridprefs.tmp`, sub cheia `SYS(1272, grid)` (ex. `frm_modific2024.grid1`).
|
||||
Salvarea se face live, la `columnmoved`/`columnresize`, nu la iesirea din formular.
|
||||
|
||||
Consecinta: `ColumnOrder` setat in clasa e neutralizat la runtime pentru orice utilizator care a
|
||||
deschis deja formularul inainte de livrare - `gridextra1.setup()` restaureaza ordinea veche, iar
|
||||
coloana nou adaugata (care nu exista in preferinte) ajunge ultima.
|
||||
|
||||
Solutie: repozitionare la runtime, in `Show()`, **dupa** `gridextra1.setup()`, aplicata o singura
|
||||
data - cat timp preferintele salvate nu acopera toate coloanele (implementat pe
|
||||
`frm_modific2024`, `COMUN\clase\omodificari.vc2`, coloana `nnir`).
|
||||
|
||||
La testare: pozitia coloanei nu e o asertiune stabila intre masini. Se asertesteaza tare
|
||||
`ControlSource` si `ReadOnly`; `ColumnOrder` ramane informativ.
|
||||
@@ -5,6 +5,16 @@ Actualizarea automata a aplicatiilor si a bazei ruleaza din jobul `CONTAFIN_ORAC
|
||||
**UpdateScripts** (umple `UPD_DATABASE`) -> **UpdateDatabaseSqlPlus** (aplica scripturile pe scheme).
|
||||
O etapa esuata le opreste pe toate urmatoarele.
|
||||
|
||||
## Scriptul de diagnostic
|
||||
|
||||
`COMUN\utile\diag_actualizare.ps1 -Alias <ALIAS_TNS>` ruleaza tot lantul de mai jos si scoate un
|
||||
verdict (unde a ramas rularea, care e scriptul candidat, unde e eroarea). Strict read-only; `-Disc`
|
||||
adauga verificarea spatiului pe discurile serverului (singura parte care scrie ceva — un `.ps1`
|
||||
temporar in `DMPDIR`). Foloseste-l intai; sectiunile de mai jos explica ce citeste si de ce.
|
||||
|
||||
Cand cauza e spatiul (tablespace plin, audit/loguri Oracle care umplu discul), continua cu
|
||||
`depanare-spatiu-oracle.md` si `COMUN\utile\diag_spatiu.ps1`.
|
||||
|
||||
## Unde te uiti, in ordine
|
||||
|
||||
| Ce | Unde |
|
||||
@@ -52,6 +62,31 @@ Fisierul se poate citi si fara acces la desktopul serverului, prin `UTL_FILE` pe
|
||||
`DMPDIR` (`fopen(...,'R',32767)` + `get_line` in bucla; tine ultimele N linii intr-un tablou —
|
||||
partea utila e la sfarsit).
|
||||
|
||||
### Caz: nu orice esec de script e o problema de SQL (SIGMA, 03.08.2026)
|
||||
|
||||
`ff_2026_07_29_02_COMUN_TVA11.SQL` a picat pe `MARCU` cu `ORA-01653: unable to extend table
|
||||
SYS.INFO ... in tablespace SYSTEM` (din `SYS.PINFO`/`SYS.AUTH_PACK`, recursiv). Tablespace-ul
|
||||
`SYSTEM` era plin: autoextensibil, dar cu `maxbytes` atins la 600 MB, ~2 MB liberi. **Orice**
|
||||
script ar fi picat identic — `AUTH_PACK` scrie in `SYS.INFO` la fiecare conectare. Cand eroarea nu
|
||||
priveste obiectele scriptului, verifica intai spatiul.
|
||||
|
||||
Ce a contat, pentru data viitoare:
|
||||
|
||||
- **`maxbytes` mic nu e o limita XE.** Cele 11 GB ale XE sunt pe *date utilizator*; un plafon mic pe
|
||||
`SYSTEM.DBF` e o setare de instalare. Se ridica din `contafin_oracle` (are `ALTER DATABASE`):
|
||||
`alter database datafile '<cale>\SYSTEM.DBF' autoextend on next 50M maxsize 2000M;`
|
||||
- **Spatiul pe discul serverului se verifica fara RDP**, cu `sys.ExecuteScriptOS` (vezi mai jos) —
|
||||
`Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3"`, iesire in `DMPDIR`, citita cu `UTL_FILE`.
|
||||
Job asincron, dar raspunde in cateva secunde.
|
||||
- **`SYS.INFO` e tabel ROA, nu obiect de dictionar** (log de login scris de `PINFO`, ~7 randuri per
|
||||
conectare, +16-17k randuri/luna, nimic din baza nu-l citeste). Se poate goli, **dar numai ca
|
||||
`SYSDBA`**: privilegiile `ANY` (`DROP ANY TABLE`, `DELETE ANY TABLE`) nu se aplica pe obiectele
|
||||
din schema `SYS` cat timp `O7_DICTIONARY_ACCESSIBILITY=FALSE`, deci din `contafin_oracle` iese
|
||||
`ORA-01031`.
|
||||
- Restul lui `SYSTEM` era dictionar Oracle (`IDL_UB1$`, `SOURCE$`, `IDL_UB2$`, `ARGUMENT$` ~207 MB) —
|
||||
de neatins fara export/import. `AUD$`/`FGA_LOG$` erau goale. Recyclebin-ul si bloat-ul de scheduler
|
||||
stateau in `ROA`/`SYSAUX`, nu in `SYSTEM`.
|
||||
|
||||
## Descarcarea (UpdateApp)
|
||||
|
||||
Cu `server_info.POWERSHELLDOWNLOAD = '1'`, `PACK_UTILS.DownloadFileOS` scrie un `.ps1` cu `curl` in
|
||||
@@ -98,6 +133,31 @@ end;
|
||||
/
|
||||
```
|
||||
|
||||
## Emailuri: log de actualizare vs buletin informativ
|
||||
|
||||
Sunt **doua emailuri diferite, trimise de doua masini diferite** — se confunda usor.
|
||||
|
||||
| | Log de actualizare | Buletin informativ |
|
||||
|---|---|---|
|
||||
| Cine trimite | baza de date, `PACK_UPDATE.EmailLog` (`UTL_SMTP` direct catre `EMAIL_SMTP:EMAIL_PORT`, `AUTH LOGIN`) | **serverul de update** (ASP.NET); baza doar face un GET pe `optiuni.UPD_URL_BULETININF` (cu `|CUSTOMERID|`) prin `PACK_UTILS.URL2Clob`, din `UpdateApp` |
|
||||
| Destinatari | `server_info.EMAIL_TO` + `EMAIL_CC` | configurati pe serverul de update, **nu** in `server_info` (ex. `office@romfast.ro`) |
|
||||
| Subiect / continut | `Actualizare ROA dd.mm.yyyy hh24:mi:ss`; liniile din `UPD_LOG`, text simplu separat cu TAB | compus de serverul de update |
|
||||
| In `UPD_LOG` | erorile SMTP: `EROARE: utl_smpt ERROR CODE ...` | raspunsul HTTP, verbatim (ex. `ERR-1-BULETIN INFORMATIV NU S-A TRIMIS. MOTIVUL: Error: 1429`) |
|
||||
|
||||
Detalii care conteaza la depanare:
|
||||
|
||||
- **`EMAIL_CC` nu produce un antet `Cc:`.** Codul il concateneaza cu virgula la `EMAIL_TO` si trimite
|
||||
`RCPT TO` pentru toti; antetul e un singur `To: <toti>`. Deci un email primit *in Cc* nu vine de la
|
||||
`EmailLog`.
|
||||
- **`EMAIL_FROM` e per server de client** (`roaupdate-<client>@romfast.ro`) si difera de contul
|
||||
autentificat, care e acelasi peste tot (`EMAIL_USERNAME = roaupdate@romfast.ro`). Expeditorul e
|
||||
singurul indiciu din email despre serverul care l-a trimis. Daca `EMAIL_FROM` lipseste, se compune
|
||||
din `UTL_INADDR.get_host_name`.
|
||||
- **Un buletin esuat nu opreste nimic**: raspunsul `ERR-1-...` e text normal, se scrie in `UPD_LOG` si
|
||||
actualizarea merge mai departe. Doar exceptiile HTTP ajung ca `ERR: <url> ...`.
|
||||
- **Un SMTP picat, in schimb, opreste tot** — `EmailLog` ridica `ORA-20000` care mascheaza eroarea
|
||||
reala (vezi „Capcane" mai sus). E singurul loc din lantul de email care are voie sa arunce.
|
||||
|
||||
## Configurare (CONTAFIN_ORACLE)
|
||||
|
||||
- `server_info`: `POWERSHELLDOWNLOAD`, `POWERSHELLPATH`, `POWERSHELLTIMEOUT`, `CURLPATH`,
|
||||
@@ -110,7 +170,7 @@ end;
|
||||
|
||||
Tunel SSH pe 1521 + alias TNS pe `127.0.0.1` in `D:\ROA\instantclient_19_18\tnsnames.ora`
|
||||
(ex. `ROA_ROMCONSTRUCT`), utilizator `contafin_oracle`. Vezi `oracle_export.md` pentru client si
|
||||
capcana de encoding; parolele stau in `docs/local/` al proiectului, neversionat.
|
||||
capcana de encoding; parolele stau in `COMUN\docs\local\oracle.md` (neversionat in git).
|
||||
|
||||
Serverele de client pot fi Oracle 10g: unele coloane din `dba_scheduler_*` lipsesc
|
||||
(`dba_scheduler_running_jobs.last_start_date`) — foloseste `dba_scheduler_job_run_details`.
|
||||
|
||||
122
docs/depanare-spatiu-oracle.md
Normal file
122
docs/depanare-spatiu-oracle.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Depanare spatiu Oracle la clienti
|
||||
|
||||
```powershell
|
||||
powershell -File COMUN\utile\diag_spatiu.ps1 -Alias <ALIAS_TNS> [-Disc] [-SysPassword <parola>] [-Top 30]
|
||||
```
|
||||
|
||||
Strict read-only in afara lui `-Disc` (singura parte care scrie: un `.ps1` temporar in `DMPDIR`,
|
||||
lansat cu `sys.ExecuteScriptOS` si sters la final). Actiunile de curatare sunt doar **sugerate**,
|
||||
niciodata executate. 8 sectiuni: conexiune/versiune (CDB-PDB), tablespace + top segmente, audit,
|
||||
alert log/trace/ADR, archivelog/FRA, disc server, alti mancatori de spatiu, verdict.
|
||||
|
||||
Pentru actualizarea blocata de spatiu, punctul de plecare e `depanare-pack-update.md`.
|
||||
|
||||
## Jobul automat `DIAGSPATIU_ZILNIC` (SVN r17969)
|
||||
|
||||
Echivalentul in baza al scriptului de mai sus, rulat zilnic la 06:00 de la fiecare client:
|
||||
`co_2026_08_03_02` (tabela `DIAG_SPATIU_LOG`, istoric purjat la 90 zile), `co_2026_08_03_03`
|
||||
(`PACK_DIAG_SPATIU`), `co_2026_08_03_04` (jobul), `sys_2026_08_03_05` (granturi). Praguri identice
|
||||
cu `diag_spatiu.ps1`; **email doar la prag depasit**, tacere completa altfel. Sursa de referinta:
|
||||
`COMUN\docs\PACK_DIAG_SPATIU.pck`.
|
||||
|
||||
Sectiunile informative (recyclebin, UNDO, TEMP, istoric statistici/scheduler, top segmente, audit
|
||||
SYS, disc) se scriu doar cand exista deja o alerta — dau context, nu alerteaza singure.
|
||||
|
||||
`co_2026_08_06_08_DIAG_SPATIU_PACK` + `sys_2026_08_06_07_DIAG_SPATIU_GRANT3` (06.08.2026) scriu la
|
||||
top segmente si **tabela/coloana din care provine segmentul** (`DetaliuSegment`: `DBA_LOBS`,
|
||||
`DBA_LOB_PARTITIONS`, `DBA_INDEXES`; segmentele temporare se marcheaza ca atare) — fara asta un
|
||||
`SYS_LOB0000630560C00017$$` de 4 GB in email nu spune nimic, iar serverul clientului nu e accesibil
|
||||
direct. Atentie: pentru `LOB PARTITION`, `dba_segments.segment_name` e `lob_name`, nu
|
||||
`lob_partition_name`.
|
||||
|
||||
Emailurile ajung pe `marius.mutu@romfast.ro`, cate un expeditor per client
|
||||
(`roaupdate_<client>@romfast.ro`); citirea lor: `email-thunderbird.md`.
|
||||
|
||||
`co_2026_08_06_01_DIAG_SPATIU_PACK` (06.08.2026) corecteaza doua lucruri vazute pe primele rulari:
|
||||
|
||||
- **pragul absolut (2048 MB) nu se mai aplica tablespace-urilor al caror maxim e sub el** — orice
|
||||
`UNDOTBS`/`SYSTEM` plafonat la 500–2048 MB alerta zilnic, prin definitie; acolo ramane doar garda
|
||||
relativa de 15%.
|
||||
- **emailul contine tot logul rularii** (alertele intai, apoi toate randurile din `DIAG_SPATIU_LOG`,
|
||||
cu `!` pe cele peste prag, sortate pe sectiune si valoare descrescator), nu doar un pointer catre
|
||||
tabela. Corpul e plafonat la 30000 de caractere (`EmailDiagSpatiu` lucreaza pe `VARCHAR2(32000)`),
|
||||
cu marcaj `... restul in DIAG_SPATIU_LOG` la depasire.
|
||||
|
||||
## Mecanisme reutilizabile (din investigatia pentru job)
|
||||
|
||||
- **`CONTAFIN_ORACLE.SERVER_INFO`** tine parolele `PASSWORD_SYS`/`PASSWORD_CONTAFIN_ORACLE`
|
||||
(zip+base64, nu criptare), caile `SQLPLUSPATH`/`POWERSHELLPATH`/`DMPDIR`, cheile `EMAIL_*` si
|
||||
cache-ul `VERSIUNE_<SCHEMA>`. Parola se citeste cu `PACK_UPDATE.GetSchemaParola('<SCHEMA>')`
|
||||
(decodeaza doar pentru `SYS` si `CONTAFIN_ORACLE`; pentru schemele de firma intoarce
|
||||
`'ROMFASTSOFT'` hardcodat).
|
||||
- **Rulare ca `SYS` din PL/SQL**: scrii un `.sql` in `DMPDIR` cu `connect sys/<parola>@ROA as
|
||||
sysdba` + `spool`, il lansezi cu `sys.UpdateSQLPLUS` si astepti fisierul de iesire; pentru OS,
|
||||
`sys.ExecuteScriptOS` (PowerShell). Ambele sunt asincrone (job `dbms_scheduler` de tip
|
||||
`executable`, auto-drop) — mecanismul folosit si de `PACK_UPDATE.UpdateDatabaseSqlPlus`. Fisierele
|
||||
temporare au nume proprii, ca sa nu se bata cu `script_master.sql` al actualizarii.
|
||||
- **`PACK_UPDATE.EmailLog` nu e reutilizabila** pentru alt continut: subiectul e hardcodat
|
||||
("Actualizare ROA ...") si corpul vine din `UPD_LOG`. Pentru alte alerte, bloc `UTL_SMTP` propriu
|
||||
care citeste aceleasi chei `EMAIL_*`.
|
||||
- **Scripturile `sys_*`** se aplica automat, ca orice `co_`/`ff_`: prefixul e recunoscut in
|
||||
`PACK_UPDATE.UpdateSchema*`, schema `SYS` se actualizeaza **prima**, iar `UpdateVersiune` isi
|
||||
scrie randul in `CONTAFIN_ORACLE.versiune` (schema `SYS` n-are tabela proprie). Deci un `sys_`
|
||||
livrat in aceeasi zi ruleaza inaintea scripturilor `co_` care depind de el.
|
||||
|
||||
## Ce umple spatiul, in ordinea frecventei
|
||||
|
||||
- **Tablespace cu `maxbytes` atins** — nu "disc plin", ci un plafon pus la instalare. Pe XE limita
|
||||
de 11/12 GB e pe *date utilizator*, nu pe `SYSTEM`.
|
||||
- **`SYSAUX`** — SQL Tuning Sets (`wri$_sqlset_*`), AWR, audit policies active pe un PDB nou.
|
||||
- **Fisierele `.aud`** din `audit_file_dest` (`adump`) — zeci de mii, niciodata curatate; **nu se vad
|
||||
din SQL**, doar cu `-Disc`.
|
||||
- **Alert log / trace / incident** (`diagnostic_dest`) — se purja cu `adrci purge`.
|
||||
- **FRA plina cu `log_mode=ARCHIVELOG`** → `ORA-00257`/`ORA-19809`; baza se blocheaza brusc, fara
|
||||
eroare vizibila in aplicatie.
|
||||
- Recyclebin, `UNDO` umflat, istoric statistici/scheduler, `TEMP`.
|
||||
- **Tabele de log ale aplicatiei** care cresc nelimitat (tiparul `SYS.INFO` de pe SIGMA) — apar in
|
||||
raportul de top segmente, numele difera per client.
|
||||
|
||||
## Cazuri
|
||||
|
||||
- **Rompetrol Energy** (XE 21c): `ORA-12954`, limita de 12 GB pe `dba_data_files` atinsa. `SYSAUX`
|
||||
umflat la 7.8 GB din SQL Tuning Sets (~5 GB) + AWR + audit policies. `TRUNCATE wri$_sqlset_*` a
|
||||
eliberat segmentele, dar `RESIZE` a picat cu `ORA-03297` (`SYSAUX` nu se shrink pe XE 21c) →
|
||||
singura solutie a fost **recrearea PDB-ului**, 13.5 GB → 3 GB. Detalii:
|
||||
`E:\proiecte\ROMFASTSQL\proxmox\lxc108-oracle\clienti\oracle-xe-21c\` (`README.md`,
|
||||
`depanare-ora-12954-spatiu.md`).
|
||||
- **ROA_CENTRAL** (`ORA-65114`, 02.08.2026): acelasi tipar, rezolvat prin curatenie tintita in loc
|
||||
de recreare PDB; SQL-uri gata scrise in acelasi repo (`docs/curatenie-spatiu-oracle.sql`).
|
||||
- **SIGMA** (03.08.2026): `SYSTEM` plafonat la 600 MB — vezi `depanare-pack-update.md`.
|
||||
|
||||
## Capcane
|
||||
|
||||
- **Segmentele `TEMPORARY` dintr-un tablespace permanent nu dispar intotdeauna la restart** (ACN,
|
||||
06.08.2026: 1.3 GB ramasi si dupa repornirea serviciului). Daca `v$sort_usage` e gol, sunt orfane
|
||||
si se curata fortat, ca `SYS`: `alter session set events 'immediate trace name DROP_SEGMENTS level
|
||||
<ts#+1>'` (`ts#` din `v$tablespace`) — la ACN au disparut instantaneu, cu tot spatiul recuperat.
|
||||
Daca nici asa nu pleaca, apartin unui DDL neterminat — cauta `SYS_JOURNAL%` (index online) sau
|
||||
obiecte `INVALID/UNUSABLE` in schema respectiva.
|
||||
- **`shrink space` pe un LOB cere ASSM**; pe un tablespace MSSM da `ORA-10635` (cazul `ROA` la ACN).
|
||||
Echivalentul care merge: `alter table t move lob (col) store as (tablespace <ts>)` — reconstruieste
|
||||
segmentul, tine tabela blocata cat dureaza si cere spatiu liber cat segmentul mutat.
|
||||
- **Privilegiile `ANY` nu se aplica pe obiectele din schema `SYS`** cat timp
|
||||
`O7_DICTIONARY_ACCESSIBILITY=FALSE` — orice curatare acolo cere `SYSDBA`.
|
||||
- Parola `SYS` e de obicei cea generica (vezi `COMUN\docs\local\oracle.md`), dar **nu la toti
|
||||
clientii** (ex. ROMCONSTRUCT) — cand nu merge, se ia cu `PACK_UPDATE.GetSchemaParola('SYS')`.
|
||||
`-SysPassword` ramane optional: diagnosticul de baza merge complet fara el, doar sectiunile
|
||||
SYSDBA se sar.
|
||||
- **Rolurile nu se aplica in pachete cu drepturi de definitor**: un pachet care refera static
|
||||
`dba_*`/`v$*` iese `INVALID` la clientul care are accesul doar prin rolul `DBA`, chiar daca
|
||||
aceleasi interogari merg din SQL*Plus. De aceea granturile directe din `sys_2026_08_03_05`.
|
||||
Lantul de actualizare **nu** se opreste in acest caz: `sqlplus` iese cu cod 0 la eroare de
|
||||
compilare, deci se vede doar ca pachet invalid + job cazut.
|
||||
- **Curatenia poate esua din lipsa de spatiu** (`DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL` a picat asa la
|
||||
Rompetrol): intai ridici plafonul, apoi cureti.
|
||||
- `RESIZE` pe datafile da `ORA-03297` daca extentele folosite nu sunt la coada fisierului — un
|
||||
`DELETE` fara `MOVE`/`SHRINK` nu recupereaza MB.
|
||||
- Dimensiunile reale ale fisierelor de pe disc nu se vad din SQL — `-Disc`, prin `ExecuteScriptOS`.
|
||||
- **`-Disc` merge doar pe servere Windows** (`ExecuteScriptOS` lanseaza PowerShell). Pe Linux
|
||||
expira curat dupa 60s, cu mesaj.
|
||||
- **`MAX_PDB_STORAGE` se citeste doar de pe un alias care tinteste radacina CDB.** De pe un
|
||||
serviciu de PDB (cazul obisnuit al aliasurilor din `tnsnames.ora`), `alter session set
|
||||
container=CDB$ROOT` da `ORA-01031` — e nevoie de un alias separat spre radacina.
|
||||
41
docs/email-thunderbird.md
Normal file
41
docs/email-thunderbird.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Citirea emailurilor (Thunderbird Portable)
|
||||
|
||||
Conectorul Gmail din Claude vede **doar** `mmarius28@gmail.com`. Conturile de lucru
|
||||
(`marius.mutu@romfast.ro` etc.) nu sunt acolo — se citesc local, din mbox-urile Thunderbird:
|
||||
|
||||
```
|
||||
D:\UTIL\portable\PortableApps\ThunderbirdPortable\Data\profile\ImapMail\<cont>\INBOX
|
||||
```
|
||||
|
||||
Conturi active (dupa `LastWriteTime`): `mail.romfast.ro` (~36 MB, contul principal) si
|
||||
`mail.romfast-1.ro` (~108 MB). Restul (`seanet.ro`, `romfast-4.ro`, `imap.googlemail.com`, …)
|
||||
sunt vechi de ani.
|
||||
|
||||
```powershell
|
||||
powershell -File COMUN\utile\citeste_email.ps1 -Cauta 'Diagnostic spatiu' -Ultimele 10
|
||||
powershell -File COMUN\utile\citeste_email.ps1 -Nr <linie> [-Linii 200]
|
||||
```
|
||||
|
||||
Prima forma listeaza `Cont / Linie / Data / De_la / Subiect` (filtru `-Cauta` pe subiect **sau**
|
||||
expeditor, `-Cont mail.romfast.ro` restrange la un cont); a doua tipareste mesajul care incepe la
|
||||
linia respectiva, pana la urmatorul separator mbox.
|
||||
|
||||
## Capcane
|
||||
|
||||
- **Nu da `Grep`/ripgrep pe folder**: `INBOX.sbd\Sent` are ~2.5 GB si cautarea expira.
|
||||
- **Numerotarea liniilor difera intre unelte** (`Select-String` vs `Get-Content` vs `StreamReader`)
|
||||
— mbox-ul are linii cu `\r` singur. Foloseste numarul dat de `citeste_email.ps1`, pentru ca
|
||||
`-Nr` citeste cu acelasi cititor; daca linia ceruta nu e inceput de mesaj, scriptul trece la
|
||||
contul urmator (`-Nr` fara `-Cont` cauta in toate).
|
||||
- Thunderbird tine fisierul deschis → citire doar cu `FileShare::ReadWrite` (scriptul o face).
|
||||
- Mesajele sunt in ordine cronologica, **cel mai nou la sfarsitul fisierului**; separatorul e
|
||||
`From - <data>`. Corpurile HTML/base64 se tipar brut — pentru ele ia doar `Content-Type` si
|
||||
primele linii, nu tot mesajul.
|
||||
|
||||
## Emailuri automate ROA
|
||||
|
||||
| Expeditor | Ce e |
|
||||
|---|---|
|
||||
| `roaupdate_acn@`, `roaupdate-sigma@`, `roaupdate-clever@`, `roaupdate-automotive@` … | jobul `DIAGSPATIU_ZILNIC`, subiect `Diagnostic spatiu Oracle <BAZA> <data> <ora>`, cate un expeditor per client. Vezi `depanare-spatiu-oracle.md` |
|
||||
|
||||
Emailul vine **doar la prag depasit**; tacere = totul in regula.
|
||||
@@ -76,6 +76,21 @@ fals `roundtrip text1 != text2`. Ruleaza atunci cu lista rebazata:
|
||||
- Metoda noua de clasa cere `*m: nume` in `*<DefinedPropArrayMethod>`; fara ea, prima salvare
|
||||
din IDE o arunca tacut, iar refresh-ul urmator absoarbe pierderea in cache (si in .bak-uri).
|
||||
Override-urile de metode de baza (Init, Show, hook-uri) nu au nevoie de `*m:`.
|
||||
- **Proprietate noua de clasa cere identic `*p: nume` in `*<DefinedPropArrayMethod>`** — nu doar
|
||||
valoarea in `*<PropValue>`. Fara `*p:`, valoarea se scrie in text, **trece fidelity-check-ul**
|
||||
(fidelity compara doar text-sursa cu text-regenerat) si ajunge in binar ca text, dar VFP nu o
|
||||
materializeaza pe obiect: `PEMSTATUS(o,'nume',5)` da `.F.` si orice acces cade cu eroarea 1734
|
||||
"Property ... is not found". Dovedit in ambele sensuri pe o clasa de proba izolata (cu `*p:` ->
|
||||
`.T.`, fara -> `.F.`).
|
||||
- **FoxBin2Prg sorteaza alfabetic cu `_` DUPA literele obisnuite**, nu in ordine ASCII brut (unde
|
||||
`'_' (0x5F) < 'v' (0x76)` pe litere mici). O intrare `*p:`/`*m:` scrisa de mana in ordine "ASCII
|
||||
corecta" pica fidelity-check-ul; ordinea canonica se citeste din textul regenerat in
|
||||
`<staging>\verify\*.vc2` (vezi punctul de mai jos despre pozitia metodelor noi — se aplica identic
|
||||
proprietatilor).
|
||||
- FoxBin2Prg NU pastreaza pozitia in text a unei metode noi: o regenereaza la pozitia
|
||||
alfabetica din `*<DefinedPropArrayMethod>`. O metoda scrisa in alta parte a fisierului
|
||||
face fidelity-check-ul sa pice. Sursa de adevar pentru relocare e textul regenerat din
|
||||
`<staging>\verify\` - muta metoda unde apare acolo si reia write-back-ul.
|
||||
- Salvarea din VFP IDE peste un binar scris de txt2vcx poate PIERDE si definitii `*m:` deja
|
||||
existente, desi corpurile PROCEDURE raman (patit pe ROAGEST: `import_adauga_factura.recalc_tva`,
|
||||
`import_nota.do_adauga/do_copie/do_reface`); simptom: crash la Createobject cu
|
||||
|
||||
53
docs/flux-modificare-stergere-nota-jurnal.md
Normal file
53
docs/flux-modificare-stergere-nota-jurnal.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Flux: modificare/stergere nota in Registrul Jurnal
|
||||
|
||||
Comportament CORECT (nu bug): la **modificarea** unei note din Registrul Jurnal, documentul
|
||||
original nu se suprascrie. Se marcheaza `sters = 1` pe randurile vechi (`ACT`/`RUL`/`RUL_OBINV`),
|
||||
apoi se scrie un document NOU cu alt `cod`, pastrand acelasi `id_fact`/`id_factd`. Ambele operatii
|
||||
ruleaza intr-o tranzactie manuala unica (commit sau rollback pe amandoua).
|
||||
|
||||
## Unde
|
||||
|
||||
- `afisjurcom.do_modifica` - `COMUN\clase\comun.vc2:2222-2562`. Deschide tranzactia manuala
|
||||
(`Thisform.do_deschide_tranzactie()`, linia 2448), apoi `oscrie_in_fisiere(2,...)` = STERGE
|
||||
(linia 2451), apoi `oscrie_in_fisiere(0,...)` = SCRIE (linia 2479), apoi
|
||||
`pack_contafin.finalizeaza_modificare_nota(...)` (2484-2486), apoi
|
||||
`Thisform.do_inchide_tranzactie(...)` (linia 2535) - commit daca tot ce a rulat inainte a
|
||||
reusit, rollback altfel.
|
||||
- `do_deschide_tranzactie`/`do_inchide_tranzactie` (`_frmbase`, `COMUN\clase\_frm_base.vc2:252,279`;
|
||||
varianta identica ca procedura globala in `COMUN\programe\oproceduri_rulaje.prg:287,303`):
|
||||
`SQLSetProp(gnHandle,'Transactions',2)` la deschidere, `SQLCOMMIT`/`SQLROLLBACK` +
|
||||
`SQLSetProp(...,'Transactions',1)` la inchidere.
|
||||
- `oscrie_in_fisiere.prg` (`COMUN\programe\oscrie_in_fisiere.prg`): `tnScrie_Sterge` 0=scriere,
|
||||
2=stergere. Apeleaza server-side `pack_contafin.init_scriere_act_rul_local` +
|
||||
`final_scriere_act_rul_local` -> `finalizeaza_scriere_act_rul`, care ruleaza `SCRIE_IN_ACT`
|
||||
(scriere) sau `STERGE_DIN_ACT` (stergere) din `PACK_CONTAFIN.pck`.
|
||||
- `PACK_CONTAFIN.STERGE_DIN_ACT` (`COMUN\docs\PACK_CONTAFIN.pck:1815-1859`):
|
||||
`UPDATE ACT SET STERS = 1 ... WHERE COD = tnCod` - marcheaza vechiul document, pe `cod`-ul vechi.
|
||||
- `PACK_CONTAFIN.SCRIE_IN_ACT` (`PACK_CONTAFIN.pck:630-901`): `LN_COD := pack_contafin.GET_COD()`
|
||||
(linia 648) aloca un `cod` nou; `UPDATE ACT_TEMP SET COD = LN_COD, ...` (linia 897) il scrie pe
|
||||
noul document - `ID_FACT` nu e atins, ramane cel din documentul original.
|
||||
- `PACK_CONTAFIN.finalizeaza_modificare_nota` (`PACK_CONTAFIN.pck:8601-8651`): aloca din nou
|
||||
`lnCodNou := pack_contafin.get_cod()` si actualizeaza pe codul nou `vanzari`
|
||||
(`pack_facturare.actualizeaza_vanzari`) si `atasamente_vanzari`. `nom_lucrari` se actualizeaza
|
||||
DOAR pentru `id_set IN (31003,31004,31005,31011)` (repune `id_fact`), nu general. `gest_inventar`
|
||||
NU se leaga de `cod`-ul nou - se identifica dupa `dataora_validat + an + luna` (cazul
|
||||
`id_set = 90101`, note de inventariere).
|
||||
|
||||
## Atentie: nu e valabil la fel pentru stergerea simpla
|
||||
|
||||
`afisjurcom.do_sterge` (`comun.vc2:2565-2724`) ofera doua optiuni (`xmenu`, linia 2625):
|
||||
- **Stergere document** (`lnOptiune = 1`): DOAR `OSCRIE_IN_FISIERE(2,...)` + `finalizeaza_stergere_nota`
|
||||
- marcheaza `sters = 1`, NU se creeaza document nou.
|
||||
- **Anulare document** (`lnOptiune = 2`): STERGE (linia 2698) + SCRIE (linia 2709, cu sumele puse pe
|
||||
0) - creeaza si document nou, la fel ca la modificare - dar aici cele doua apeluri NU sunt
|
||||
invelite intr-o tranzactie manuala comuna (nu apare `do_deschide_tranzactie`/
|
||||
`do_inchide_tranzactie` in `do_sterge`); fiecare `OSCRIE_IN_FISIERE` isi gestioneaza singur
|
||||
commit-ul (vezi `tlModificare`/`llManualTransactions` in `oscrie_in_fisiere.prg:111-165`).
|
||||
|
||||
## Implicatii practice
|
||||
|
||||
- Codul (`cod`) unui document din Registrul Jurnal NU e stabil dupa modificare/anulare - se schimba
|
||||
la fiecare editare. Cod hardcodat sau retinut dintr-o executare anterioara devine invalid.
|
||||
- Regasirea documentului editat se face dupa `id_fact` (sau alt marcaj stabil), niciodata dupa `cod`.
|
||||
- Randurile `sters = 1` ramase in `ACT`/`RUL`/`RUL_OBINV` dupa o modificare sunt normale (istoric),
|
||||
nu date corupte sau duplicate de curatat.
|
||||
@@ -10,11 +10,15 @@ PL/SQL Developer.
|
||||
- Alias TNS: `ROA_CENTRAL` → `10.0.20.121:1521`, `SERVICE_NAME=ROA` (vezi `tnsnames.ora`).
|
||||
- Schema/utilizator: `MARIUSM_AUTO` (schema de dezvoltare a lui Marius).
|
||||
- **Schema de lucru pentru verificari: `MARIUSM_AUTO` pe `ROA_CENTRAL`** - nu `ACN` sau altele.
|
||||
- **Parola nu e versionată** — local, în `D:\ROA\ROAGEST\docs\local\oracle.md` (ignorat de git).
|
||||
- **Parola nu e versionată în git** — în `COMUN\docs\local\oracle.md` (ignorat de git, există în SVN).
|
||||
|
||||
`PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus sinonim `PUBLIC`.
|
||||
Exportul de referință se face din `MARIUSM_AUTO`.
|
||||
|
||||
Înainte de a lua o sursă de acolo ca referință pentru o modificare, verifică că `MARIUSM_AUTO` are
|
||||
toate scripturile aplicate — procedura e în `scripturi-migrare-db.md`, secțiunea
|
||||
"Sursa de referință pentru DDL".
|
||||
|
||||
## Gotcha sqlplus pe Windows/PowerShell
|
||||
|
||||
Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF-16 sparge parserul
|
||||
|
||||
@@ -4,6 +4,45 @@ Regula (valabila in toate proiectele ROA/VFP): un singur subagent care duce o mi
|
||||
(iteratii de teste, investigatii, mai multe sarcini inlantuite) acumuleaza context urias —
|
||||
calitate degradata, cost mare. Nu se lucreaza asa.
|
||||
|
||||
## REGULA ZERO: predarea contextului e OBLIGATORIE, nu optionala
|
||||
|
||||
Se aplica **identic sesiunii principale si oricarui subagent**. Nu e o recomandare de eficienta,
|
||||
e o conditie de corectitudine: un context supraincarcat pierde tacut decizii deja luate si reia
|
||||
investigatii deja platite.
|
||||
|
||||
**Declansatoare — la oricare dintre ele, predarea porneste imediat:**
|
||||
|
||||
1. contextul propriu a trecut de **~50% din fereastra** (orchestrator) sau de **~200-250k tokens**
|
||||
(subagent);
|
||||
2. harness-ul anunta compactare automata (`PreCompact`) — **prea tarziu ca sa mai amani, dar nu
|
||||
prea tarziu ca sa scrii fisierul**; scrie handoff-ul inainte sa raspunzi orice altceva;
|
||||
3. utilizatorul semnaleaza ca s-a atins limita;
|
||||
4. s-a terminat un bloc de lucru — indiferent cat context a mai ramas.
|
||||
|
||||
**Procedura, in ordine, fara exceptii:**
|
||||
|
||||
1. **Opreste lucrul.** Nu incepe o sarcina noua, nu porni o rulare noua. Daca esti in mijlocul unei
|
||||
editari, du-o pana la o stare **consistenta pe disc** (text si binare sincronizate) si atat.
|
||||
2. **Scrie handoff-ul pe disc** (`docs\handoff_<subiect>.md`). Nu in mesaj, nu in raport — **pe
|
||||
disc**. Un mesaj catre orchestrator se pierde; fisierul nu.
|
||||
3. **Confirma in doua randuri** ce ai lasat in urma si daca ceva e intr-o stare periculoasa
|
||||
(fisier editat fara write-back, tranzactie deschisa, proces ramas viu, date de test consumate).
|
||||
4. **Opreste-te.** Blocul urmator il ia un agent proaspat. "Mai am putin" nu e motiv de amanare —
|
||||
exact acolo se pierd lucrurile.
|
||||
|
||||
**Obligatia e a fiecaruia, nu doar a orchestratorului.** Un subagent care simte ca se apropie de
|
||||
prag **anunta singur** si cere predarea; nu asteapta sa fie oprit. Un orchestrator care se apropie
|
||||
de prag isi scrie propriul handoff si preda orchestrarea unei sesiuni noi — regula nu are portita
|
||||
pentru "eu doar coordonez".
|
||||
|
||||
**Ce intra obligatoriu in handoff**: inventarul livrabilelor cu `fisier:linie`; ce e terminat si ce
|
||||
nu; **daca write-back-ul e facut** pentru fiecare fisier atins; comanda exacta de rulare a testelor
|
||||
si unde scriu logurile; ce s-a stabilit deja (ca sa nu se reia); ce e interzis; starea datelor de
|
||||
test consumate; capcanele de mediu platite. Fara analize noi — doar stare.
|
||||
|
||||
Doua lectii platite scump, amandoua din aceeasi cauza — un agent tinut peste prag (`s5-nivel2`
|
||||
533k, `s2d-modifica-gestiuni` 434k). Predarea e aproape gratuita: raportul e oricum deja scris.
|
||||
|
||||
## Cum se lucreaza
|
||||
|
||||
- Sesiunea principala (sau un agent primar) e ORCHESTRATOR: imparte planul pe sarcini
|
||||
@@ -58,7 +97,9 @@ diagnostic, fixuri aplicate direct in loc de delegate.
|
||||
care intoarce da/nu, nu continutul din care ai deduce singur.
|
||||
- **Nu aplica fixuri direct** decat sub ~5 linii si doar daca ai deja contextul in sesiune.
|
||||
- **Prag si pe orchestrator**: la ~50% din fereastra, scrie handoff-ul si reia orchestrarea
|
||||
dintr-o sesiune noua. Handoff-ul e deja pe disc - exact pentru asta exista.
|
||||
dintr-o sesiune noua. Handoff-ul e deja pe disc - exact pentru asta exista. Vezi **Regula zero**
|
||||
de la inceputul fisierului: obligatia e aceeasi ca pentru subagenti, fara portita pentru
|
||||
"eu doar coordonez".
|
||||
|
||||
## Model de lucru: backlog de story-uri mici, context mic per story
|
||||
|
||||
|
||||
83
docs/publicare-scripturi-db.md
Normal file
83
docs/publicare-scripturi-db.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Publicarea scripturilor de baza de date catre clienti
|
||||
|
||||
Scriptul: `COMUN\utile\publicare_scripturi.ps1`. Inlocuieste pasii manuali din `tasks.exe`
|
||||
(`D:\PROIECTE\fox\tasks`, formularul din `clase\generare_script.vcx`), care raman varianta de rezerva.
|
||||
Cum se scrie un script de migrare: `scripturi-migrare-db.md`.
|
||||
|
||||
```powershell
|
||||
powershell -File COMUN\utile\publicare_scripturi.ps1 -DryRun # ce ar face pe luna curenta
|
||||
powershell -File COMUN\utile\publicare_scripturi.ps1 # luna curenta, tot fluxul
|
||||
powershell -File COMUN\utile\publicare_scripturi.ps1 -Luna 2026-08 # alta luna
|
||||
powershell -File COMUN\utile\publicare_scripturi.ps1 -Fisier a.sql,b.sql # doar scripturile date
|
||||
```
|
||||
|
||||
Alte optiuni: `-DoarImport` (fara arhiva), `-DoarArhiva` (doar regenerare arhiva), `-Toate`
|
||||
(republica si scripturile identice), `-FaraVerificareZip`, `-Settings`, `-ZipPath`, `-DirScripturi`,
|
||||
`-Alias`, `-User`, `-Password`, `-SqlPlus`.
|
||||
|
||||
## Configurarea
|
||||
|
||||
Se citeste din `settings.ini`-ul lui `tasks.exe` (`D:\PROIECTE\fox\tasks\settings.ini`, schimbabil
|
||||
cu `-Settings`), aceleasi chei pe care le foloseste formularul; orice parametru dat explicit bate
|
||||
ini-ul.
|
||||
|
||||
| din ini | ce devine |
|
||||
|---|---|
|
||||
| `[connection] host_database` | nume de **DSN ODBC** — aliasul TNS e cheia `ServerName` a DSN-ului din registri (`CENTRAL` → `ROA_CENTRAL`) |
|
||||
| `[connection] username_database` / `password_database` | utilizatorul Oracle |
|
||||
| `[folder] script_folder` | directorul scripturilor, cu `\SCRIPTURI\` → `\SCRIPTURI_CLAR\` (+ `\<an>\<luna>\`) |
|
||||
| `[folder] roa_output` | + `_UPDATE\` = directorul arhivelor |
|
||||
| `[folder] sqlplus_exe` | clientul Oracle (si `TNS_ADMIN` = directorul lui) |
|
||||
| `[script]` | prefixele valide (`CO_`, `FF_`, `RF_`, `SYS_`, `JCS_`) — prefix necunoscut = avertisment |
|
||||
|
||||
`sqlplus_exe` arata spre `instantclient_19_18`; `instantclient_11_2_0_2` (valoarea de dinainte) are
|
||||
un `tnsnames.ora` vechi, cu `ROA_CENTRAL` pe `10.0.20.122` in loc de `.121`, deci conexiunea expira.
|
||||
`settings.ini` e local (ignorat de SVN).
|
||||
|
||||
## Cei doi pasi
|
||||
|
||||
**1. Import** — fiecare `.sql` intra ca un rand in `CONTAFIN_ORACLE.UPD_DATABASE` de pe `ROA_CENTRAL`,
|
||||
cu `SCRIPT_ORDER = 0` (randul contine scriptul intreg, nu instructiuni parsate), `SCRIPT_NAME` cu
|
||||
MAJUSCULE si `.SQL`, `SCRIPT_TYPE` = ce urmeaza dupa `NN_`, `SCRIPT_CONTENT` = fisierul in clar.
|
||||
`ID` vine din trigger, `DATAORA` din `SYSDATE` implicit, `SCRIPT_APPVER`/`SCRIPT_EXTRA_FILE` raman
|
||||
goale. Daca `SCRIPT_NAME` exista deja, se face **update pe acelasi `id`** — asa se republica un
|
||||
script corectat, pentru ca clientul face `MERGE ... on (a.id = b.id)`.
|
||||
|
||||
**2. Arhiva lunara** — in `Y:\ROAUPDATE\_UPDATE\` se scriu `database_YYYYMMDD_YYYYMMDD.zip` **si**
|
||||
`databasen_...zip` (identice azi: `database_` era varianta criptata cu `wrap.exe`, nu se mai
|
||||
foloseste). Fiecare contine XML-ul cu acelasi nume ca zip-ul (format `VFPData`/`crsxml`,
|
||||
Windows-1252, CRLF, tab-uri, `script_content` gol) plus cate un `<STEM_MAJUSCULE>.sql` per script.
|
||||
Indexii `roa_database.xml` / `roa_databasen.xml` listeaza arhivele existente si se schimba doar
|
||||
cand apare o luna noua.
|
||||
|
||||
Continutul din arhiva se citeste **inapoi din baza**, nu de pe disc — deci arhiva contine exact ce
|
||||
va primi clientul.
|
||||
|
||||
## Verificari facute automat
|
||||
|
||||
- fisier cu sfarsituri de linie LF: **refuzat** (parsarea pe client se face pe `CHR(13)+CHR(10)`);
|
||||
- dupa import, continutul e citit inapoi din CLOB si comparat octet cu octet cu fisierul; la
|
||||
diferenta se opreste inainte de arhiva;
|
||||
- scripturile deja publicate cu acelasi continut se sar (`-Toate` forteaza republicarea);
|
||||
- arhiva generata se citeste inapoi cu cititorul clientului (`pack_utils.decodebase64` +
|
||||
`zip_util_pkg.get_file`) si se compara lungime + MD5 per fisier — o arhiva facuta din PowerShell
|
||||
este citita corect de `zip_util_pkg`;
|
||||
- fisierele inlocuite din `_UPDATE` se copiaza intai in `_UPDATE\_backup\<data_ora>\`.
|
||||
|
||||
`Y:\ROAUPDATE\_UPDATE\` e **live**: clientii descarca de acolo imediat ce fisierul e pus.
|
||||
|
||||
## Ce face clientul
|
||||
|
||||
`PACK_UPDATE.UpdateScripts` (`COMUN\docs\PACK_UPDATE.pck`) descarca indexul, apoi arhivele care
|
||||
acopera perioada neaplicata, extrage XML-ul cu `zip_util_pkg.get_file`, face `MERGE` in
|
||||
`UPD_DATABASE` pe `id`, apoi pentru fiecare rand cu `script_extra_file` pune continutul fisierului
|
||||
in `script_content` — pentru `.sql` text clar, fara base64 (base64 e doar pentru instructiunile
|
||||
parsate, alta ramura). Actualizare blocata: `depanare-pack-update.md`.
|
||||
|
||||
## Detalii de implementare
|
||||
|
||||
Continutul circula **hexazecimal** in ambele sensuri (`utl_i18n.raw_to_char` / `string_to_raw` cu
|
||||
`WE8MSWIN1252`), pe bucati de 900 de octeti, in blocuri PL/SQL de cate 15 bucati. Motivul: baza e
|
||||
`AL32UTF8`, fisierele sunt CP1252, iar comanda trimisa lui `sqlplus` ramane ASCII pur — nu depinde
|
||||
de `NLS_LANG` si nu poate strica octetii >= 0x80. Consecinta utila: comparatia dintre fisier si
|
||||
CLOB e exacta, nu pe lungime.
|
||||
@@ -12,13 +12,20 @@
|
||||
handoff-uri/planuri de runda, `*.pre_runda*.bak`, `.bak`-urile din cache-ul text si artefactele
|
||||
de test (`screenshots*`, `uisync*`, `.fxp`, `.err`, loguri). Sterge doar fisiere neurmarite de
|
||||
git — cele tracked sunt sarite.
|
||||
2. Comentarii in cod: minime, strict functionale, descriu comportamentul CURENT (ca si cum ar fi
|
||||
scris asa de la inceput) — o linie de regula, 2-3 doar pentru metode cu contract nebanal
|
||||
(parametri, cursor asteptat/lasat deschis, pozitionare la iesire). Istoricul modificarilor
|
||||
sta DOAR in ANTETUL fisierului (niciodata inline) — la fel in `.prg` si in PL/SQL Oracle.
|
||||
INTERZIS in comentariu: nume de agent ("claude"), referinte la propuneri/decizii/etape
|
||||
(`docs/propuneri_*.md`, "M2", "T3", "dec.6", "runda27", "E7", "D-H2"), istoricul modificarii
|
||||
("inlocuieste...", "nu mai depinde de...", "mutat din..."), date si autori pe cod nou.
|
||||
2. Comentarii in cod SI in scripturile de migrare `.sql`: minime, strict functionale, descriu
|
||||
comportamentul CURENT (ca si cum ar fi scris asa de la inceput). **Doar daca e cazul** — un
|
||||
comentariu se scrie acolo unde explica o **ramura** sau un **filtru** care nu se citeste singur,
|
||||
ca sa se inteleaga codul; unde codul e limpede, nu se comenteaza. O linie de regula, 2-3 doar
|
||||
pentru metode cu contract nebanal (parametri, cursor asteptat/lasat deschis, pozitionare la
|
||||
iesire), 4-5 in antetul unui script de migrare (ce e obiectul si ce contract are). Istoricul
|
||||
modificarilor sta DOAR in ANTETUL fisierului (niciodata inline) — la fel in `.prg`, in `.sql`
|
||||
si in PL/SQL Oracle.
|
||||
INTERZIS in comentariu: nume de agent ("claude"), referinte la planuri, stories, propuneri,
|
||||
decizii, etape sau erori (`docs/plan_*.md`, `docs/propuneri_*.md`, "#6", "S4", "M2", "T3",
|
||||
"dec.6", "runda27", "E7", "D-H2"), trimiteri la rapoartele din `docs/` ("vezi raportul,
|
||||
sectiunea ..."), justificarea alegerii facute (de ce numele acesta, de ce s-a respins varianta
|
||||
cealalta), istoricul modificarii ("inlocuieste...", "nu mai depinde de...", "mutat din..."),
|
||||
date si autori pe cod nou.
|
||||
Comentarii vechi in stil jurnal nu se rescriu din oficiu — doar cand blocul e oricum atins
|
||||
sau la cerere explicita.
|
||||
Antet: o singura intrare CUMULATIVA per functionalitate (`*!* DD.MM.YYYY` / `*!* autor` /
|
||||
@@ -46,6 +53,20 @@
|
||||
se umple contextul. Misiuni lungi: subagenti proaspeti per sarcina (max ~200-250k
|
||||
tokens/subagent), nu unul singur cu context acumulat; handoff compact pe disc:
|
||||
`orchestrare-subagenti.md`.
|
||||
**Verificarea a ce se intoarce** — pentru executie delegarea merge, pentru concluzii nu:
|
||||
- **citeste contractul functiei apelate, nu-l presupune.** Un raport care descrie corect
|
||||
structura codului poate gresi sensul: ex. `goExecutor.oExecute` intoarce succes/insucces
|
||||
(`CT_SUCCES`/`CT_INSUCCES`), NU numarul de randuri — o garda `If lnSucces > 0` citita ca
|
||||
"are randuri" a produs un bug inexistent, raportat ca blocant. Deschide functia.
|
||||
- **fix ingust, nu supra-constructie.** Cand premisa se corecteaza, corectia se restrange:
|
||||
mecanismele noi introduse "ca sa fie sigur" diverg de la codul-sablon si blocheaza
|
||||
refolosirea lui in alta parte.
|
||||
- **"zero cazuri in date" nu dovedeste nimic** pe scheme cu date de test; raspunsul vine din
|
||||
cod. Si invers: o potrivire de cifre pe 1-2 documente nu e o regula.
|
||||
- **cere raportul sa separe "testat" de "analizat static"**, si ce n-a putut fi acoperit. Un
|
||||
agent care nu e intrebat explicit va prezenta amandoua la fel.
|
||||
- **spune-i ca poate infirma briefingul.** Altfel implementeaza corectia ceruta chiar cand a
|
||||
descoperit ca nu e nevoie de ea.
|
||||
7. Conventii obligatorii, de citit cand atingi zona respectiva:
|
||||
- editezi fisiere cu octeti cp1252 - `.vc2`/`.sc2`, dar si `.prg` (ex. `programe\ocautare.prg`,
|
||||
unde `s`-urile cu virgula din `masina`/`si contul`/`transa` sunt octetul `0xBA`) ->
|
||||
@@ -60,6 +81,8 @@
|
||||
`0xBA` strica `a`/`t` cu caciula (`0xE3`, `0xFE`) din alte fisiere;
|
||||
- adaugi/rearanjezi controale pe formulare sau coloane in grid -> `conventie_ux_formulare.md`;
|
||||
- grid needitabil pe formular cu 2+ grid-uri -> `capcana_grid_controlsource.md`;
|
||||
- adaugi o coloana intr-un grid deja livrat (ordinea din clasa e neutralizata de
|
||||
preferintele salvate per utilizator) -> `capcana_grid_preferinte_utilizator.md`;
|
||||
- `GO` pe un `Recno()` capturat/primit ca parametru -> `conventie_go_recno.md`;
|
||||
- `ALTER TABLE` pe cursorul intors de `goExecutor.oExecute()` -> `conventie_goexecutor_alter_table.md`;
|
||||
- testare UI / prin MCP -> `testare-ui-vfp.md`, `testare-vfp-mcp.md`;
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
Scripturile de migrare a schemei (si modelele pentru scripturi noi) sunt in
|
||||
`DATABASE\SCRIPTURI_CLAR` de sub radacina suitei ROA (`gcDirMare`/`dirgen` — ex.
|
||||
`D:\ROA\DATABASE\SCRIPTURI_CLAR`). Sursa SVN: `http://svnroa:3001/svn/ROA/DATABASE/Branches/RB-1.00`.
|
||||
Pentru un script nou, urmeaza formatul/conventiile celor recente de acolo.
|
||||
Pentru un script nou, urmeaza formatul/conventiile celor recente de acolo. Publicarea catre clienti
|
||||
(import in `UPD_DATABASE` + arhiva lunara): `publicare-scripturi-db.md`.
|
||||
|
||||
Reguli confirmate de Marius (24.07.2026):
|
||||
|
||||
@@ -15,6 +16,50 @@ Reguli confirmate de Marius (24.07.2026):
|
||||
final (conventia existenta).
|
||||
- Aplicarea prin ODBC/`goExecutor`: sintaxa SQL*Plus `exec pachet.procedura(...)` nu functioneaza
|
||||
— foloseste `begin pachet.procedura(...); end;`.
|
||||
- **Niciun `;` la capat de linie intr-un comentariu `--` din interiorul unei instructiuni.** SQL*Plus
|
||||
termina instructiunea acolo, chiar daca `;`-ul e in comentariu: restul `CREATE VIEW`-ului ajunge sa
|
||||
fie interpretat linie cu linie ca si comenzi, cu zeci de `SP2-0734` si un `ORA-00936` derutant care
|
||||
arata spre comentariu. Pus la sfarsit de fraza, `.` in loc de `;`. Comentariile de **dinaintea**
|
||||
instructiunii nu sunt afectate.
|
||||
- **Fiecare script se incheie cu `exec pack_migrare.UpdateVersiune('<nume_script>');` urmat de
|
||||
`commit;`.** DDL-ul comite implicit, dar `UpdateVersiune` e DML: fara `commit` explicit, un script
|
||||
se poate aplica fara ca versiunea sa se inregistreze, iar `VERSIUNE` ajunge sa minta despre ce s-a
|
||||
aplicat.
|
||||
- **Rularea manuala se face conectat pe schema tinta** (`CONTAFIN_ORACLE` pentru `co_`, schema firmei
|
||||
pentru `ff_`), niciodata cu un user de lucru. DDL-ul neprefixat (`create or replace package ...`)
|
||||
merge pe schema conexiunii: pe alt user iese `PLS-00304` si ramane un obiect orfan, iar pachetul
|
||||
tinta ramane neschimbat. In acelasi script, DML-ul pe tabele cu sinonim public nimereste tabela
|
||||
reala si pare ca totul a mers — verifica intotdeauna iesirea sqlplus si `all_objects`.
|
||||
`PACK_UPDATE` face `CONNECT <schema>/<parola>@ROA` real per schema (`UpdateSchemaSQLPLUS`, parola
|
||||
din `SERVER_INFO`), deci scriptul neprefixat e corect pentru livrare.
|
||||
|
||||
## Sursa de referinta pentru DDL: MARIUSM_AUTO, nu productia
|
||||
|
||||
Regula lui Marius (06.08.2026): **orice modificare de tabela, view, procedura, functie sau pachet se
|
||||
scrie plecand de la sursa din schema de dezvoltare `MARIUSM_AUTO` (`ROA_CENTRAL`), niciodata de la
|
||||
sursa citita dintr-o schema de client** (`VENDING`, `ACN`, ...). Schemele de client raman in urma:
|
||||
pot avea scripturi neaplicate sau variante livrate separat (ex. pachetele `_10G_ROMCONSTRUCT`), iar o
|
||||
modificare scrisa peste o sursa veche sterge corectii deja livrate.
|
||||
|
||||
Schemele de client raman utile doar pentru **masuratori pe date reale**, in citire.
|
||||
|
||||
### Verifica intai ca MARIUSM_AUTO e la zi
|
||||
|
||||
"Ultima versiune din dev" e ultima versiune doar daca toate scripturile din `SCRIPTURI_CLAR` chiar au
|
||||
fost aplicate acolo. `pack_migrare.UpdateVersiune` inregistreaza fiecare script aplicat in tabela
|
||||
`VERSIUNE` (`script_final` = numele fisierului, cu tot cu `.sql`), deci diferenta se vede direct:
|
||||
|
||||
```sql
|
||||
select script_final, data_final from versiune order by data_script desc, seq_script desc;
|
||||
```
|
||||
|
||||
```powershell
|
||||
Get-ChildItem D:\ROA\DATABASE\SCRIPTURI_CLAR -Recurse -Filter *.sql |
|
||||
Select-Object -ExpandProperty Name | Sort-Object
|
||||
```
|
||||
|
||||
Daca lipsesc scripturi din `VERSIUNE`, **nu porni modificarea** pe sursa de acolo — semnaleaza-i lui
|
||||
Marius ce nu e aplicat. Exportul sursei de referinta: `oracle_export.md`.
|
||||
|
||||
## Continutul unui script
|
||||
|
||||
@@ -23,21 +68,46 @@ Reguli confirmate de Marius (24.07.2026):
|
||||
- **Fara `select` de raportare in script** — nu-l citeste nimeni la aplicare si poate da eroare.
|
||||
Verificarile se fac inainte, separat, pe schema de lucru.
|
||||
- **Idempotent**: rulat de doua ori nu mai schimba nimic (`merge`, `where <coloana> is null`).
|
||||
- **Un pachet sta singur in scriptul lui**, fara alt DDL sau DML alaturi: modificarile de tabele si
|
||||
curateniile de date merg in scripturi separate, cu numar propriu.
|
||||
- **Comentarii strict necesare**, ca in cod: antet de 4-5 randuri (data + autor, ce e obiectul, ce
|
||||
contract are), fara referinte la planuri, stories, propuneri, decizii sau erori, fara trimiteri la
|
||||
rapoartele din `docs/`, fara justificarea alegerilor si fara istoricul modificarii. Regula completa
|
||||
si lista de interdictii: `reguli_lucru.md`, punctul 2.
|
||||
|
||||
## Compatibilitate cu serverele clientilor
|
||||
|
||||
Serverul de dezvoltare e mai nou decat serverele clientilor, deci un script care trece local poate
|
||||
pica la client si opri actualizarea. **ROMCONSTRUCT e singurul client ramas pe Oracle 10.2** — el da
|
||||
masura pentru orice se pune in comune.
|
||||
pica la client si opri actualizarea.
|
||||
|
||||
Constructii care merg pe dev si pica pe 10g:
|
||||
Parcul de servere (03.08.2026): **un client pe Oracle 10.2** (ROMCONSTRUCT), cativa pe **XE 11 si
|
||||
11g** standard, restul pe **XE 18/19/21 si 18/21**.
|
||||
|
||||
| Constructie | Ce iese pe 10g |
|
||||
|---|---|
|
||||
| identificator peste 30 de caractere (tabela, index, constrangere, coloana) | `ORA-00972` (12.2+ accepta 128) |
|
||||
| `REGEXP_COUNT` (functie din 11g) | `ORA-00904` in SQL / `PLS-00201` in PL/SQL |
|
||||
| `CONTINUE` (instructiune PL/SQL din 11g) | `PLS-00201: identificatorul 'CONTINUE' trebuie declarat` |
|
||||
| `FORALL` cu campuri de record din colectie (`S(i).camp`) | `PLS-00436` / `PLS-00382` |
|
||||
**Regula: orice script care ajunge in comune se scrie la nivelul Oracle 10.2 si trebuie sa ruleze pe
|
||||
10.2 si pe 11.x.** Numitorul comun e 10.2 — nu se folosesc facilitati 11g si cu atat mai putin 12c+,
|
||||
oricat de comod ar fi pe dev. Proba inainte de publicare se face pe serverul cel mai vechi
|
||||
(ROMCONSTRUCT), nu pe dev.
|
||||
|
||||
Constructii care merg pe dev si pica mai jos:
|
||||
|
||||
| Constructie | Disponibila de la | Ce iese sub ea |
|
||||
|---|---|---|
|
||||
| identificator peste 30 de caractere (tabela, index, constrangere, coloana) | 12.2 | `ORA-00972` |
|
||||
| `REGEXP_COUNT` | 11.1 | `ORA-00904` in SQL / `PLS-00201` in PL/SQL |
|
||||
| `CONTINUE` (instructiune PL/SQL) | 11.1 | `PLS-00201: identificatorul 'CONTINUE' trebuie declarat` |
|
||||
| `LISTAGG` | 11.2 | `ORA-00904` |
|
||||
| `PIVOT` / `UNPIVOT` | 11.1 | eroare de sintaxa |
|
||||
| trigger compus (`COMPOUND TRIGGER`) | 11.1 | eroare de compilare |
|
||||
| `secventa.NEXTVAL` direct intr-o atribuire PL/SQL | 11.1 | `PLS-00357` (pe 10g: `select ... into` din `dual`) |
|
||||
| `FETCH FIRST n ROWS`, `CROSS APPLY`, `LATERAL` | 12.1 | eroare de sintaxa (pe 10g/11g: `rownum`) |
|
||||
| `IDENTITY`, `DEFAULT ON NULL`, coloane invizibile | 12.1 | eroare de sintaxa |
|
||||
| `VALIDATE_CONVERSION`, `CAST ... DEFAULT ON CONVERSION ERROR` | 12.2 | `ORA-00904` |
|
||||
| `FORALL` cu campuri de record din colectie (`S(i).camp`) | 11.1 | `PLS-00436` / `PLS-00382` |
|
||||
|
||||
Editiile **XE** adauga limite proprii, independent de sintaxa: XE 11.2 nu are partitionare, executie
|
||||
paralela si nici masina virtuala Java in baza; XE 18/19/21 au setul de facilitati al editiei mari,
|
||||
dar plafonate pe resurse (12 GB de date, 2 GB RAM, 2 fire de executie). Deci nimic care sa depinda de
|
||||
partitionare sau de Java in baza, si nicio operatie care sa presupuna spatiu/memorie de server mare.
|
||||
|
||||
Plus, independent de versiune: **un obiect nu se poate referi la ceva creat de un script ulterior.**
|
||||
Pe dev obiectul exista deja, deci pachetul compileaza; la client scriptele se aplica in ordine si
|
||||
|
||||
34
docs/scripturi-uzuale.md
Normal file
34
docs/scripturi-uzuale.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Scripturi uzuale (sarcini repetitive)
|
||||
|
||||
**Regula: o sarcina care se repeta se pune intr-un script si de atunci se apeleaza scriptul.**
|
||||
Nu reface lantul de pasi din memorie la fiecare sesiune si nu da unui subagent aceleasi instructiuni
|
||||
a doua oara — daca a doua oara e nevoie de acelasi lucru, scrie scriptul.
|
||||
|
||||
| Cand | Ce rulezi | Ce face |
|
||||
|---|---|---|
|
||||
| inceput de sesiune, si dupa orice `svn update` | `roa_sync.bat` din radacina proiectului (→ `COMUN\scripts\roa_sync.ps1`) | `svn update` → `git_sync` (texte `.??2`) → commit `sync SVN r<rev>` → reconciliere cu `origin` (ff/rebase) → push conditionat → inchide branch-urile `claude/*` terminate |
|
||||
| inainte de un commit | `COMUN\utile\curatenie.ps1` (`-DryRun` doar listeaza) | sterge artefactele de lucru netrackuite: patch-uri de review, `handoff*`/`runda*`/`propuneri_*`, backup-uri `*.pre_runda*.bak`, artefacte de test |
|
||||
| la "commit / push" | `COMUN\utile\livrare.ps1 -Mesaj "..." [-Comun]` | `git_sync` → `curatenie` → verificari de livrare → status/diff pe ambele repo-uri → commit + push. `COMUN` doar cu `-Comun`; `push --force` nu exista |
|
||||
| editare `.vcx`/`.scx` | `D:\ROA\UTIL\foxbin2prg\` : `git_sync.ps1`, `vfp_symbols.ps1`, `txt2vcx.ps1` | reimprospatare text in-arbore, index de simboluri, write-back cu fidelity-check |
|
||||
| actualizare de baza de date blocata | `COMUN\utile\diag_actualizare.ps1 -Alias <TNS>` | `UPD_ISTORIC` → `UPD_LOG` → `script_master.log` → versiuni per schema → job → tablespace → verdict. Vezi `depanare-pack-update.md` |
|
||||
| spatiu plin la un client | `COMUN\utile\diag_spatiu.ps1 -Alias <TNS> [-Disc] [-SysPassword]` | tablespace, audit, ADR, FRA, disc server, top segmente. Vezi `depanare-spatiu-oracle.md` |
|
||||
| publicare scripturi de baza de date | `COMUN\utile\publicare_scripturi.ps1 [-Luna YYYY-MM] [-Fisier ...] [-DryRun]` | import in `UPD_DATABASE` → arhiva lunara `database[n]_*.zip` + indexi in `_UPDATE`, cu verificare octet cu octet. Vezi `publicare-scripturi-db.md` |
|
||||
| teste UI VFP | harness din `COMUN\utile\Teste` | vezi `testare-ui-vfp.md` |
|
||||
| citirea emailurilor de pe conturile romfast | `COMUN\utile\citeste_email.ps1 [-Cauta ...] [-Nr <linie>]` | listeaza/extrage mesaje din mbox-urile Thunderbird Portable (conectorul Gmail nu vede conturile romfast). Vezi `email-thunderbird.md` |
|
||||
|
||||
Documentatia **nu** se genereaza automat si nu exista niciun hook care s-o scrie — `livrare.ps1`
|
||||
doar semnaleaza ce lipseste (changelog neatins, binar VFP fara textul lui sincronizat).
|
||||
|
||||
Candidati inca nescrisi: un helper pentru rulat SQL prin `sqlplus` (fisier ASCII + `@fisier.sql`,
|
||||
refacut manual la fiecare interogare) si un wrapper care ruleaza `diag_spatiu.ps1` peste toti
|
||||
clientii, cu un rezumat pe un rand per server.
|
||||
|
||||
Fluxul SVN ↔ git din spatele lui `roa_sync`: `fluxul_svn_git.md`.
|
||||
|
||||
**Mesaje de commit din PowerShell catre `git`/`svn` (exe native): niciodata `-m $mesaj`.**
|
||||
PowerShell nu escapeaza ghilimele/backtick/`$` cand paseaza argumente catre un exe nativ - un
|
||||
mesaj cu `"..."` sparge comanda. Solutie: scrie mesajul intr-un fisier temporar si foloseste
|
||||
`git commit -F <fisier>` / `svn commit -F <fisier>`, cu textul **UTF-8 fara BOM**
|
||||
(`[IO.File]::WriteAllText($cale, $mesaj, (New-Object Text.UTF8Encoding $false))` - `Out-File
|
||||
-Encoding utf8` in PS 5.1 scrie BOM, care ajunge ca prim caracter in mesajul de commit) si
|
||||
**LF, nu CRLF** (`svn commit -F` refuza fisiere cu linii mixte CRLF/LF: `E135000`).
|
||||
@@ -33,6 +33,56 @@ dialoguri modale), nu pe pasii fluxului testat.
|
||||
5. `powershell -File vfp_ui_harness.ps1 -TestPrg <test.prg> -Steps @('pas0',...)`.
|
||||
PNG-uri in `screenshots\step_<n>_<eticheta>.png`; log in `<test>_log.txt`.
|
||||
|
||||
## Dialoguri modale (`Show(1)`)
|
||||
|
||||
Doua situatii, cu solutii diferite:
|
||||
|
||||
**A. Testul instantiaza el dialogul** — `WindowType = 0` inainte de `Show()` (pasul 3 de mai sus).
|
||||
`Show()` revine imediat si conduci formularul pas cu pas. Prefera intotdeauna varianta asta.
|
||||
|
||||
**B. `Show(1)` e hardcodat in metoda aplicatiei** (ex. `frm_facturare_articole.do_adauga_articol` /
|
||||
`do_modifica`): testul nu are referinta la dialog, deci nu poate seta `WindowType`, iar fluxul real
|
||||
cere sa treaca prin buton. Se conduce dintr-un **Timer pe `_SCREEN`**, pregatit INAINTE de actiunea
|
||||
care deschide dialogul:
|
||||
|
||||
1. `_SCREEN.AddObject('tmrDrv','Timer')`, `Interval = 200`,
|
||||
`BINDEVENT(_SCREEN.tmrDrv, 'Timer', <obiect driver>, 'Executa')`, `Enabled = .T.`
|
||||
2. `Show(1)` **chiar pompeaza mesaje Windows** cat e modal — timerul ticaie normal (masurat: 229
|
||||
tick-uri in 46s). Bucla modala nu e oarba la evenimente externe.
|
||||
3. **Detectia formularului: `_SCREEN.Forms(i)` / `_SCREEN.FormCount`**, potrivit pe `.Class`.
|
||||
**`_SCREEN.ActiveForm` NU merge headless** — a ramas gol la toate cele 229 de tick-uri: depinde
|
||||
de `WM_ACTIVATE`, care nu se declanseaza fara focus real, pe cand colectia `Forms` contine
|
||||
formularul indiferent de activare.
|
||||
4. **Referinta la controale**: `loForm.<nume>` merge normal; iterarea `loForm.Controls(i)` cu
|
||||
potrivire pe `.Name` e alternativa robusta (utila si ca diagnostic, pentru ca listeaza ce EXISTA
|
||||
cu adevarat). **Daca accesul da 1925 "Unknown member" pe un control care sigur e in clasa,
|
||||
suspecteaza mediul de test, nu colectia**: o eroare in constructia unui obiect adaugat mai
|
||||
devreme opreste adaugarea celor de dupa, iar formularul ramane incomplet fara sa se plange (caz
|
||||
real: lipsa cursorului `saft_taxtable`, capcana j, a lasat instanta cu 21 de controale in loc de
|
||||
25, iar controlul urmator din ordinea de adaugare "disparea"). Verifica intai `ControlCount` si
|
||||
lista de nume.
|
||||
5. **Inchiderea**: `do_termin()` (gateaza pe `inainte_de_do_termin()`, seteaza `gnButon = 1` si
|
||||
elibereaza — `_frm_base.vc2:363-371`) sau `do_renunt()`. **Daca validarea respinge, `do_termin()`
|
||||
nu seteaza `gnButon` si NU elibereaza formularul, deci `Show(1)` ramane blocat** — in testele
|
||||
care asteapta o respingere de validare, iesi prin `do_renunt()`.
|
||||
6. **Driverul se instrumenteaza obligatoriu**: log pe fiecare pas, `TRY/CATCH` cu
|
||||
`ErrorNo`/`Message`/`LineNo`, iar steagul "am tratat dialogul" se seteaza **dupa** interactiunea
|
||||
reusita, nu inainte. Altfel prima eroare e invizibila si blocheaza orice reincercare — simptomul
|
||||
e tick-uri la nesfarsit pana la timeout, fara nicio urma in log.
|
||||
|
||||
**Regula de metoda, invatata scump**: mediul unei suite noi se mosteneste din suita care **TRECE**,
|
||||
nu din una care esueaza. Un mediu copiat dintr-un test nevalidat a produs trei defecte succesive
|
||||
(cursor `saft_taxtable` lipsa, mock `poArticol` incomplet, nume de variabila coliziv), fiecare
|
||||
descoperit dupa cate o rulare, si toate aratau ca defecte de aplicatie sau ca "test agatat". Cand
|
||||
doua suite au nevoie de acelasi mediu, **extrage-l intr-un singur loc** (cu grija la capcana l
|
||||
pentru constructia obiectelor).
|
||||
|
||||
Doua non-dovezi, ca sa nu se piarda timp pe ele:
|
||||
- `AMEMBERS(a, o)` **fara flagul 2** intoarce proprietati/metode, **nu** obiectele continute —
|
||||
absenta unui control din acea lista nu inseamna ca lipseste din clasa.
|
||||
- `==` pe doua obiecte da eroare **107** "Operator/operand type mismatch"; pentru identitate se
|
||||
foloseste `COMPOBJ()`.
|
||||
|
||||
## Capcane / deblocari
|
||||
|
||||
a. **`SET SAFETY OFF` + `SET TALK OFF` inaintea primului `STRTOFILE`.** Cu SAFETY ON, scrierea
|
||||
@@ -90,7 +140,10 @@ j. **Mock-urile de date trebuie sa reproduca structura si semantica REALA a surs
|
||||
`saft_taxtable` real (nu doar mock pe `goExecutor` - `update_jtva_coloane` face
|
||||
`USE saft_taxtable` direct pe alias). Fara ele, simptomul e dialog nativ Windows "Open" (cauta
|
||||
`saft_taxtable.dbf`) care blocheaza headless la nesfarsit, fara linie noua in log si CPU 0% -
|
||||
vezi `depanare_testare_vfp.md` pentru diagnostic cu `EnumWindows`/`PrintWindow`.
|
||||
vezi `depanare_testare_vfp.md` pentru diagnostic cu `EnumWindows`/`PrintWindow`. Acelasi
|
||||
simptom apare si FARA `gl406`: un control cu `RowSourceType=3` legat direct in clasa de un SQL
|
||||
pe `saft_taxtable` (ex. combo pe explicatie SAFT) isi evalueaza `RowSource` la constructia
|
||||
formularului indiferent de `gl406` sau de `Visible=.F.` - cursorul mock trebuie creat oricum.
|
||||
k. **`LOCATE FOR camp == 'literal'` pe camp `C(n)` padded nu gaseste nimic** (`==` e exact) -
|
||||
foloseste `ALLTRIM(camp) == 'literal'`.
|
||||
l. **`CREATEOBJECT`/`ADDPROPERTY` se comporta gresit apelate DINTR-O PROCEDURA in acest runtime
|
||||
@@ -115,3 +168,47 @@ o. **Formularul resincronizeaza singur dupa o alegere din grid** (`lSyncPending`
|
||||
realiniaza dupa el). Scrie assert-urile pe starea de DUPA resincronizare, pe un efect pe care
|
||||
resincronizarea NU il repara (acolo: `scc`-ul randului T, atins doar la schimbarea explicatiei)
|
||||
- altfel testul pica fara sa fie ceva gresit in cod.
|
||||
p. **Nu numi variabilele ca functii built-in VFP.** VFP e insensibil la litere mari/mici, iar la
|
||||
coliziune **functia castiga**. Caz real: `LOCAL loCk` pentru referinta la un checkbox se ciocneste
|
||||
cu `LOCK()` — `loCk.Value = 1` da eroarea **1924 "LOCK is not an object"**, iar `VARTYPE(loCk)`
|
||||
evalueaza `LOCK()` si intoarce `'L'`, deci verificarile de tipul `VARTYPE(lo...) == 'O'` ies
|
||||
**tacut false** si par sa spuna ca obiectul nu a fost gasit — masuratoarea e stricata, nu
|
||||
rezultatul. Simptom de recunoscut: mesajul de eroare contine numele **cu majuscule** al unei
|
||||
functii VFP, nu numele variabilei asa cum ai scris-o. Prefixeaza distinctiv (`loBifa`, `loCtrl`).
|
||||
q. **`DO ... WITH` paseaza PRIN REFERINTA, iar variabila devine invizibila sub numele ei propriu in
|
||||
procedura apelata.** Consecinta urata: orice `?variabila` din SQL passthrough de pe lantul
|
||||
apelurilor respective nu se mai poate lega, si VFP deschide dialogul nativ **"View Parameter —
|
||||
Enter the value for `<var>`"**, care blocheaza testul headless la infinit (fara log, fara
|
||||
eroare). Dovedit pe date: o variabila globala era valida in programul principal la fiecare
|
||||
checkpoint, dar `TYPE()` intorcea `'U'` (nedefinita) exact la intrarea in procedurile apelate cu
|
||||
`DO proc WITH gnAn, gnLuna` — si valida in cele apelate fara `DO ... WITH` — corelatie exacta cu
|
||||
**sintaxa apelului**, nu cu ce face procedura. Remediu: paranteze pe fiecare argument forteaza
|
||||
pasarea prin valoare — `DO proc WITH (gnAn), (gnLuna)`.
|
||||
r. **O suita care testeaza o clasa din `COMUN` poate incarca implicit copia ALTUI PRODUS**, daca
|
||||
harnessul de mediu comun (ex. `test_init_env_auto.prg`) face `SET DEFAULT TO`/`SET PATH` pe
|
||||
working copy-ul altui produs (ex. `D:\ROA\ROACONT\...`) inainte de `SET CLASSLIB TO <clasa>
|
||||
ADDITIVE`: `Createobject` gaseste prima clasa cu acel nume pe `PATH`, care poate fi
|
||||
`D:\ROA\ROACONT\COMUN\clase\<clasa>.vcx` in loc de fisierul editat sub test — silentios, fara
|
||||
eroare. Simptom: testul trece curat, dar valideaza cod vechi/alt working copy; orice concluzie
|
||||
trasa asa e nula. Remediu, dupa initializarea mediului comun: `RELEASE CLASSLIB <nume>` +
|
||||
`SET CLASSLIB TO <cale completa a fisierului sub test> ADDITIVE` (`SET CLASSLIB ... ADDITIVE`
|
||||
**singur**, fara `RELEASE` intai, da eroarea 24 "Alias name is already in use" si pastreaza
|
||||
tacut copia veche). Verificare obligatorie dupa instantiere: `loForm.ClassLibrary` trebuie sa
|
||||
arate calea completa asteptata.
|
||||
s. **Dialoguri native care nu apar in log si nu sunt prinse de `ON ERROR`/mock-uri** (ex. "View
|
||||
Parameter", "Open" pe fisier lipsa): nu se depaneaza orbeste, se ruleaza sub
|
||||
`COMUN\utile\Teste\watchdog_vfp.ps1 -Script <test.prg> -AutoDismiss`. Lanseaza `vfp9.exe -A -T`,
|
||||
polleaza ferestrele top-level ale procesului (identificate prin `Process.MainWindowHandle`, nu
|
||||
dupa numele clasei — VFP foloseste clase `vfp9...` si pentru shell-ul principal si pentru
|
||||
dialogurile proprii), captureaza PNG + textul fiecarui control copil (`WM_GETTEXT`) la orice
|
||||
fereastra noua, si omoara procesul la iesire (`finally`, niciodata ramas viu). **Interzis strict:
|
||||
input real** (`keybd_event`/`SetForegroundWindow`/`SendInput`/`mouse_event`) — masina e
|
||||
partajata, un input injectat la nivel de sistem ajunge in orice fereastra are focus in acel
|
||||
moment, nu neaparat in dialogul tintit (patit: un ESCAPE injectat a intrerupt sesiunea IDE a
|
||||
utilizatorului, aflat in lucru in paralel). `-AutoDismiss` foloseste STRICT mesaje Windows
|
||||
tintite pe handle (`BM_CLICK` pe buton Cancel/Anulare, altfel `WM_COMMAND IDCANCEL` ->
|
||||
ESCAPE ca mesaj `WM_KEYDOWN`/`WM_KEYUP` -> `WM_CLOSE`); pe dialogurile proprii VFP owner-drawn
|
||||
(butoane desenate, nu HWND-uri reale) dismiss-ul poate esua cinstit — captura PNG + dump text
|
||||
raman oricum de incredere, indiferent de rezultatul dismiss-ului. Sterge intotdeauna `.fxp`-ul
|
||||
vechi inainte de FIECARE rulare (watchdog-ul o face singur la lansare) — altfel VFP ruleaza
|
||||
tacut codul compilat vechi si rulari "identice" dau rezultate diferite, fara nicio urma in log.
|
||||
|
||||
118
docs/tipuri_documente_facturare.md
Normal file
118
docs/tipuri_documente_facturare.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Tipurile de document din facturare (`VANZARI.TIP`) si seturile de contare (`ID_SET`)
|
||||
|
||||
Referinta pentru toata suita ROA: `PACK_FACTURARE` e in `COMUN`, iar `VANZARI.TIP` e citit de
|
||||
view-urile `FACT_VFACTURI` / `FACT_VFACTURI2`, de gridul principal de listare si de retiparire.
|
||||
|
||||
**Surse** (nu presupuneri):
|
||||
|
||||
- perechile `(lnIdSet, tnTip)` — comentariul din antetul `PACK_FACTURARE` (`:80-125` in exportul
|
||||
`all_source`), singurul loc care le documenteaza impreuna;
|
||||
- eticheta afisata — `CASE a.tip` din coloana `EXPLICATIE` a celor doua view-uri, citit din sursa
|
||||
live de pe `MARIUSM_AUTO` (06.08.2026);
|
||||
- restul — cod, marcat ca atare.
|
||||
|
||||
`ID_SET` e setul de formule contabile (`XSETS.ID_SET`, ajunge in `ACT.ID_SET`), pus in variabila de
|
||||
pachet `pack_facturare.nid_set` din `initializeaza_date_factura` (`:1864`). **Regula generala: setul
|
||||
"cu scadere din gestiune" e cel de baza + 10.**
|
||||
|
||||
## Facturi
|
||||
|
||||
| `ID_SET` | cu scadere | `TIP` | Document | `EXPLICATIE` afisat |
|
||||
|---|---|---|---|---|
|
||||
| 25000 | 25010 | 1 | pe baza de lista de preturi | `POLITICA PRETURI` |
|
||||
| 25001 | 25011 | 2 | pe baza de contracte | `CONTRACT` |
|
||||
| 25002 | 25012 | 3 | pe baza de comenzi | `COMANDA` |
|
||||
| 25003 | 25013 | 4 | pe baza de avize | `FACT. DIN AVIZ` |
|
||||
| 25004 | 25014 | 5 | lista de preturi in valuta | `POLITICA PRETURI - INVOICE` |
|
||||
| 25005 | 25015 | 6 | contract in valuta | `CONTRACT - VALUTA` |
|
||||
| 25006 | — | 7 | credit note | `CREDIT NOTE` |
|
||||
| 25007 | 25017 | 8 | retur factura in lei | `RETUR FACTURA IN LEI` |
|
||||
| 25008 | 25018 | 9 | retur factura in valuta | `RETUR INVOICE` |
|
||||
| 25009 | 25019 | 10 | factura fiscala in valuta | `POLITICA PRETURI - FACTURA VALUTA` |
|
||||
| 25042 | 25052 | 43 | bon fiscal (ROARETAIL, colectate de la magazine) | `BONURI FISCALE MAGAZINE` |
|
||||
| 25043 | — | 44 | factura hotel | `HOTEL` |
|
||||
| 25044 | 25054 | 45 | factura restaurant | `RESTAURANT` |
|
||||
| 25045 | 25055 | **46** | **nota de plata restaurant** | **nicio ramura** |
|
||||
| 25047 | 25057 | 48 | factura marfa custodie **cu** descarcare K | `FACT. CUSTODIE CU DESCARCARE PE BAZA DE K` |
|
||||
| 25048 | 25058 | 49 | factura marfa custodie **fara** descarcare K | `FACT. CUSTODIE FARA DESCARCARE PE BAZA DE K` |
|
||||
| 25051 | 25061 | 52 | pe baza de contract, factura fiscala in valuta | `CONTRACT - FACTURA VALUTA` |
|
||||
| 50100 | 25060 | 51 | factura ROAACNPRO | `COMERCIAL-FACTURARE` |
|
||||
|
||||
## Avize de expeditie
|
||||
|
||||
| `ID_SET` | cu scadere | `TIP` | Document | `EXPLICATIE` afisat |
|
||||
|---|---|---|---|---|
|
||||
| 25020 | 25030 | 21 | catre clienti, **din comanda** | `AVIZ PE BAZA DE COMANDA` |
|
||||
| 25021 | 25031 | 22 | catre clienti, din lista de preturi | `AVIZ DIN POLITICA DE PRETURI` |
|
||||
| 25022 | 25032 | 23 | transfer catre subunitati, din lista | `TRANSFER` |
|
||||
| 25023 | 25033 | 24 | aviz de retur | `AVIZ DE RETUR` |
|
||||
| 25024 | 25034 | 25 | transfer catre subunitati, **din comanda** | `TRANSFER PE BAZA DE COMANDA` |
|
||||
| 25025 | 25035 | 26 | catre clienti, din contract | `AVIZ PE BAZA DE CONTRACT` |
|
||||
| 25026 | 25036 | 27 | transfer catre subunitati, **pe baza de lucrare** | `TRANSFER PE BAZA DE LUCRARE` |
|
||||
| 25027 | 25037 | 28 | catre clienti debitori, **din comanda** | `CLIENTI DEBITORI - COMANDA` |
|
||||
| 25028 | 25038 | 29 | catre clienti debitori, din lista | `CLIENTI DEBITORI - POLITICA PRETURI` |
|
||||
| 25029 | 25039 | 30 | transfer catre subunitati, pe baza de NIR | `AVIZ PE BAZA DE NIR` |
|
||||
| 25040 | 25050 | 41 | retur transfer catre subunitati, lista de pret | `RETUR TRANSFER` |
|
||||
| 25041 | 25051 | 42 | catre clienti **custodie, din comanda** | `CLIENTI IN CUSTODIE - COMANDA` |
|
||||
| 25046 | 25056 | **47** | catre clienti **custodie, din comanda, pentru descarcare cu K** | `CLIENTI IN CUSTODIE - COMANDA (K)` |
|
||||
| 25049 | 25059 | 50 | *in lucru* — retur de la clienti custodie | nicio ramura |
|
||||
|
||||
## Tipuri negative
|
||||
|
||||
Nu apar in comentariul din pachet; luate din `CASE`-ul `EXPLICATIE`. Vin din alte produse sau din
|
||||
fluxuri valorice.
|
||||
|
||||
| `TIP` | `EXPLICATIE` afisat | Observatii |
|
||||
|---|---|---|
|
||||
| -1 | `MATERII PRIME SI MATERIALE` | |
|
||||
| -2 | `PRODUSE` | |
|
||||
| -3 | `MARFURI LA PRET DE ACHIZITIE` | |
|
||||
| -4 | `MARFURI LA PRET DE VANZARE` | |
|
||||
| -6 | `RETUR TRANSFER DIN GESTIUNE VALORICA` | ROAGEST; `ID_SET` 236/240/241/242 |
|
||||
| -7 | `AVIZ DE RETUR - VALORIC` | |
|
||||
| -8 | `FACTURA DE RETUR - VALORICA` | |
|
||||
| -9 | `PROTOCOL CU TVA - AVIZ EXPEDITIE` | |
|
||||
| -10 | `SPONSORIZARE - AVIZ EXPEDITIE` | |
|
||||
| -11 | `MARFURI LA PRET DE ACHIZITIE *` | |
|
||||
| -12 | `DEVIZE AUTO` | **ROAAUTO**, `factureaza_deviz` din `oproceduri_devize.prg` |
|
||||
| -13 | `RETUR MARFA IN CUSTODIE` | |
|
||||
|
||||
## Seturile de tipuri folosite in cod (unde conteaza incadrarea)
|
||||
|
||||
| Set | Unde | Ce face |
|
||||
|---|---|---|
|
||||
| `{3, 21, 28, 42, 47}` | `initializeaza_date_factura` (`:1888-1894`) | populeaza `pack_facturare.nid_comanda` din `clistaid` |
|
||||
| `+ {27}` | `scrie_avize_lucrare:5859` | suprascrie `nid_comanda` prin cursor pe `COMENZI` legat de `ID_LUCRARE` |
|
||||
| `{3, 21, 27, 28, 42, 46}` | `ALTELE` in ambele view-uri | afiseaza **comanda** (`nr_comanda/data`) |
|
||||
| `{4, 24, 8, 9}` | `ALTELE` in ambele view-uri | afiseaza **avizul** |
|
||||
| `{23, 25, 27, 30, 41, -6}` | `CLIENT` in ambele view-uri | afiseaza gestiunea, nu partenerul |
|
||||
| `{23, 25, 27, 30, 41}` si `-6` | `scrie_in_vanzari` (disc `:13530-13540`) | `lnIdGestiune` explicit, nu `min()` din detalii |
|
||||
|
||||
## Capcane confirmate
|
||||
|
||||
1. **`46` vs `47` in `ALTELE`.** Lista din view contine `46` (nota de plata restaurant, document
|
||||
care n-are comanda) si **nu contine** `47` (aviz custodie din comanda, care are). Pachetul
|
||||
populeaza `nid_comanda` pentru `47`, nu pentru `46`. `CASE`-ul `EXPLICATIE` din acelasi view are
|
||||
ramura pentru `47` si **nu** are pentru `46` — deci cele doua `CASE`-uri din acelasi view se
|
||||
contrazic pe aceste doua cifre. Decizia lui Marius (06.08.2026): **se adauga `47`, `46` ramane
|
||||
asa cum a fost scris.**
|
||||
2. **Efect vizibil pe `46`, azi**: ramura fiind luata fara ca documentul sa aiba comanda,
|
||||
`f.nr_comanda || '/' || to_char(f.data_comanda, ...)` da un **`/`** singur in coloana "Altele",
|
||||
nu gol. Nu s-a observat pe date pentru ca niciun client verificat nu foloseste modulul de
|
||||
restaurant (0 documente `tip=46` si pe `MARIUSM_AUTO`, si pe `VENDING`).
|
||||
3. **`ID_SET` 25051 apare de doua ori** in comentariul din pachet: ca set "cu scadere" pentru
|
||||
`tip=42` si ca set de baza pentru `tip=52`. Coliziune in documentatie, neverificata pe
|
||||
`XSETS` — de lamurit inainte de a te baza pe ea.
|
||||
4. **`tip=51`**: comentariul spune "factura ROAACNPRO", eticheta afisata e `COMERCIAL-FACTURARE`.
|
||||
Acelasi lucru, doua denumiri; eticheta din view e cea confirmata de constantele VFP curente
|
||||
(`ofacturare_comun.vc2:3654,3657`).
|
||||
5. **`tip=50`** e marcat "in lucru" in comentariu si n-are ramura de eticheta — de tratat ca
|
||||
neterminat, nu ca tip valid.
|
||||
6. **Comentariul nu e cod.** E singura documentare a perechilor `(ID_SET, TIP)`, dar poate fi ramas
|
||||
in urma. Inainte de a te baza pe o linie din el pentru o modificare, confirm-o pe cod
|
||||
(`initializeaza_date_factura`, `CASE`-urile din view-uri) sau pe `XSETS`.
|
||||
|
||||
## Legaturi
|
||||
|
||||
- `scripturi-migrare-db.md` — sursa de referinta pentru DDL e `MARIUSM_AUTO`, nu o schema de client.
|
||||
- `conventie_null_vfp.md` — `TIP_INCASARE` si celelalte coloane `0` vs `NULL` din view-uri.
|
||||
BIN
docs/todos-articole-preturi-saga.png
Normal file
BIN
docs/todos-articole-preturi-saga.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
@@ -5,20 +5,47 @@ Poate folosesti exact datele de la anaf descarcate pentru verificarea codurilor
|
||||
|
||||
Vreau ca verificarile de coduri fiscale din D406, D394, Registrele de TVA sa foloseasca direct ANAF, si sa actualizeze cache-ul istoricul din baza de date (ISTORIC_CODURI_FISCALE)
|
||||
|
||||
2. ROACONT - Borderou eFactura, checkbox-urile diferente fata de Registrele de TVA sa aiba in caption si numarul de inregistrari cu diferente, astfel incat utilizatorul sa stie daca este cazul sa filtreze pentru afisarea facturilor cu diferente
|
||||
DONE 2. ROACONT - Borderou eFactura, checkbox-urile diferente fata de Registrele de TVA sa aiba in caption si numarul de inregistrari cu diferente, astfel incat utilizatorul sa stie daca este cazul sa filtreze pentru afisarea facturilor cu diferente
|
||||
|
||||
3. ROACONT - modificare nota, explicatia tva sa filtreze dupa procent tva din tabel, ca sa arate o selectie mai mica de explicatii tva. vezi cum ai facut la explicatia tva din ointroduceri.vcx > import_nota.
|
||||
DONE 3. ROACONT - modificare nota, explicatia tva sa filtreze dupa procent tva din tabel, ca sa arate o selectie mai mica de explicatii tva. vezi cum ai facut la explicatia tva din ointroduceri.vcx > import_nota.
|
||||
|
||||
4. ROACONT - overificari.vcx > formularul istoric coduri fiscale are coloane care nu mai au relavanta sau nu mai sunt completate din tabel. in tabelul contafin_oracle.istoric_coduri_fiscale, campul regcom are spatii si nu se afiseaza in formularul istoric. verifica
|
||||
DONE 4. ROACONT - overificari.vcx > formularul istoric coduri fiscale are coloane care nu mai au relavanta sau nu mai sunt completate din tabel. in tabelul contafin_oracle.istoric_coduri_fiscale, campul regcom are spatii si nu se afiseaza in formularul istoric. verifica
|
||||
|
||||
5. ROACONT - VERIFICARE cod fiscal, label-ul de sub grid-ul cu rezultate si detalii F4 sa contina si status "TVA Incasare"
|
||||
DONE 5. ROACONT - VERIFICARE cod fiscal, label-ul de sub grid-ul cu rezultate si detalii F4 sa contina si status "TVA Incasare"
|
||||
|
||||
6. ROAFACTURARE - EDITARE FACTURA EMISA ANTERIOR, CARE NU A FOST TRIMISA INCA IN EFACTURA (anaf_efactura.id_fact). punctul critic este ca notele contabile si eventual rulajele generate se genereaza complicat la emiterea facturii prin pack_facturare, iar editarea este o simpla editare, si nu sincronizeaza si notele contabile si rulajele. si sunt diverse tipuri de facturi sau de avize (pe baza de lista de preturi, pe baza de comanda, pe baza de contract, pe baza de aviz) si fiecare genereaza note contabile sau rulaje si articole de vanzare (vanzari si vanzari_detalii)
|
||||
|
||||
7. ROAFACTURARE - TVA unitar si valoarea TVA pe o linie de articol este calculata si nu salvata in vanzari si vanzari_detalii. din aceasta cauza, daca o factura are valoare totala 99.99 lei, dar utilizatorul doreste 100.00 lei total cu tva (pentru ca politica de preturi are bifat preturi fara TVA si se porneste calculul incepand de la pretul fara TVA al articolului) tva-ul se calculeaza rotunjit si nu se poate edita, ca sa dea factura fix 100.00 lei. implicatiile calculului TVA in loc de salvare sunt foarte mari si adanci in program, la introducerea facturii, listarea facturii initiale, relistarea facturii
|
||||
Sau de fapt este posibil sa poata utilizatorul sa modifice "preturi_cu_tva" la nivel de fiecare articol, la introducerea facturii si ulterior la editare factura, tocmai pentru ca utilizatorul doreste sa ajusteze tva-ul total pentru ca are restrictie sa dea facturii o valoare totala rotunjita, si se poate ajusta exact din pretul cu tva individual. pret_cu_tva se salveaza in vanzari_detalii pe fiecare articol.
|
||||
|
||||
8. ROAFACTURARE - in pack_facturare am salvat in vanzari valori totale denormalizat (fara tva, tva, cu tva, numarul avizului/comanda/contract etc.) ca sa nu le calculez in view din vanzari_detalii pentru ca view-ul de facturi este foarte complex, cu functii si expresii si nu era optimizabil si acceseaza total tabelele vanzari si vanzari_detalii. folosesc un view pe modelul original, si un view cu valorile totale din vanzari. doar ca am observat un bug, la facturile din avize, nu se salveaza corect in vanzari avizul sau numarul/data/suma chitantei daca factura este achitata numerar. trebuie depanat. schema de verificare productie este VENDING@ROA_VENDING
|
||||
DONE 8. ROAFACTURARE - in pack_facturare am salvat in vanzari valori totale denormalizat (fara tva, tva, cu tva, numarul avizului/comanda/contract etc.) ca sa nu le calculez in view din vanzari_detalii pentru ca view-ul de facturi este foarte complex, cu functii si expresii si nu era optimizabil si acceseaza total tabelele vanzari si vanzari_detalii. folosesc un view pe modelul original, si un view cu valorile totale din vanzari. doar ca am observat un bug, la facturile din avize, nu se salveaza corect in vanzari avizul sau numarul/data/suma chitantei daca factura este achitata numerar. trebuie depanat. schema de verificare productie este VENDING@ROA_VENDING
|
||||
|
||||
9. ROAGEST - MODIFICARE REGISTRU JURNAL - SA SE POATA MODIFICA SI "NNIR" in notele contabile si sincronizat in rulajele asociate. nu exista coloana NNIR in formularul de editare.
|
||||
DONE 9. ROAGEST - MODIFICARE REGISTRU JURNAL - SA SE POATA MODIFICA SI "NNIR" in notele contabile si sincronizat in rulajele asociate. nu exista coloana NNIR in formularul de editare.
|
||||
|
||||
10. ROAFACTURARE - Integrare pagina contracte si rapoarte contracte in ROAFACTURARE, similar COMENZI in ROAFACTURARE - facturare pe baza de comenzi/contracte. trebuie comasate si drepturile pe obiectele din roacontracte cu obiectele noi din ROAFACTURARE.
|
||||
10. ROAFACTURARE - Integrare pagina contracte si rapoarte contracte in ROAFACTURARE, similar COMENZI in ROAFACTURARE - facturare pe baza de comenzi/contracte. trebuie comasate si drepturile pe obiectele din roacontracte cu obiectele noi din ROAFACTURARE.
|
||||
|
||||
11. ROAFACTURARE - Integrare politici de preturi in ROAFACTURARE - sunt numai editari de liste de preturi, note contabile, nomenclator articole, drepturi pe liste de preturi, care toate se folosesc numai in programul ROAFACTURARE
|
||||
|
||||
12. ROAFACTURARE - sa pot sa folosesc direct nomenclatorul de articole pe post de lista de preturi, sa nu mai definesc liste de preturi, note contabile asociate. Acum am un echivalent (lista de articole din stoc ca o lista de preturi virtuala)
|
||||
|
||||
Ca sa vand un articol, trebuie sa il introduc in nomenclatorul de articole obligatoriu. Acum trebuie sa il introduc si intr-o lista de preturi, ca sa am valuta, nota contabila de vanzare si daca are pret_cu_tva sau nu, procentul de tva vanzare, si bineinteles, pretul.
|
||||
|
||||
Am vazut la SAGA (alt ERP popular) ca in nomenclatorul de articole au cateva coloane de multe preturi, probabil pentru mai multe liste de preturi (todos-articole-preturi-saga.png)
|
||||
|
||||
Ideea este sa se poata face configurarea mult mai repede, eficient, dintr-un singur loc, ca sa se poata face factura mai rapid. Acum este nevoie de mult suport tehnic/instructaj si configurari pana se ajunge la facturare, si daca apare un articol diferit (ex: vanzare auto, in loc de marfa in mod normal), trebuie creata o politica noua de preturi, ca sa ii spun ce nota contabila de vanzare (4111 = 7xx) sa aiba aiba articolul respectiv.
|
||||
|
||||
13. ROAFACTURARE - FORMULARUL DE FACTURARE SA INCLUDA SI FORMULARUL DATE_FACTURA/DATE_AVIZ ETC. SI SA NU MAI INCARCE DE PE SERVER TOATE ARTICOLELE DIN TOATE POLITICELE DE PRETURI - INTRUCAT ESTE POSIBIL SA FIE SI MII DE ARTICOLE SI DUREAZA MULT SA LE ADUCA DE PE SERVER. AM INCEPUT DEJA MAI DEMULT UN FORMULAR UNIFICAT frm_facturare_articole2, DAR ERA MULT DE INTEGRAT DIN FORMULARUL VECHI.
|
||||
FRONTEND SIMILAR PE CARE IL DORESC ESTE IN ROAACPRO > FACTURA, SAU IN IMPORTUL DE EFACTURA, IN CARE AM INTEGRAT DATELE FACTURI, DOAR CA FACTURAREA DIN ROAFACTURARE ESTE MAI COMPLEXA - ESTE FOLOSITA SI PENTRU POLITICI DE PRETURI SI PENTRU CONTRACT/COMANDA/AVIZ/RETUR ETC.
|
||||
INTERESUL MEU ESTE SA SIMPLIFIC INTERFATA, SA FIE MAI EFICIENTA, SA NU FIE 2 FORMULARE PENTRU FACTURA, SA FAC MAI RAPID.
|
||||
|
||||
14. ROACONT - efactura se salveaza xml detaliat si xml zip efactura si ocupa mult spatiu. vreau sa stiu cand nu mai este nevoie de xml detaliat si daca se poate curata tabelul ca sa nu mai ocupe spatiu, cel putin pentru facturi mai vechi. este important zip pentru ca este factura originala anaf.
|
||||
|
||||
15. ROACONT - ce locuri din program mai folosesc frm_modific2007 in loc de frm_modific2024. trebuie migrat la formularul mai nou.
|
||||
|
||||
16. ROAFACTURARE - in date_factura/date_aviz etc, la finalizare se verifica cursul valutar necesar pentru politicile de preturi care se factureaza. la revenire din formularul de curs valutar, focusul revine inainte de numar document, cred ca pe TIP DOCUMENT, si la iesire din serie se regenereaza numar act, ceea ce este periculos daca utilizatorul l-a schimbat si se modifica automat.
|
||||
|
||||
17. ROAFACTURARE - daca o nota contabile de vanzare nu are configurat tip de venit/cheltuiala, si nici articolele din lista de preturi, si nici nu se completeaza tip venit/cheltuiala la facturare, la finalizarea facturii apare o eroare oracle ORA ca id_venchelt nu are voie sa fie null. eroarea nu este user friendly si nu se poate recupera usor, pentru ca trebuie sa se dea renunt la toata factura si sa se reia tot porcesul, cu completarea tip venit cheltuiala. si nici nu stiu de ce este obligatoriu tip venit/cheltuiala.
|
||||
|
||||
18. ROAFACTURARE - EMITERE FACTURA DIN PROFORMA
|
||||
|
||||
19. ROAFACTURARE - EDITARE PROFORMA
|
||||
@@ -197,6 +197,9 @@ Procedure ANAF_StarePartener
|
||||
Addproperty(loOut, "dSfarsitScpTVA", Iif(Pemstatus(loRezANAF, 'dSfarsitScpTVA', 5), Nvl(loRezANAF.dSfarsitScpTVA, {}), {}))
|
||||
Addproperty(loOut, "dAnulareScpTVA", Iif(Pemstatus(loRezANAF, 'dAnulareScpTVA', 5), Nvl(loRezANAF.dAnulareScpTVA, {}), {}))
|
||||
Addproperty(loOut, "cMesajScpTVA", Iif(Pemstatus(loRezANAF, 'cMesajScpTVA', 5), Alltrim(Nvl(loRezANAF.cMesajScpTVA, '')), ''))
|
||||
Addproperty(loOut, "lTvaIncasareANAF", Iif(Pemstatus(loRezANAF, 'lTvaIncasare', 5), Nvl(loRezANAF.lTvaIncasare, .F.), .F.))
|
||||
Addproperty(loOut, "dInceputTvaInc", Iif(Pemstatus(loRezANAF, 'dInceputTvaInc', 5), Nvl(loRezANAF.dInceputTvaInc, {}), {}))
|
||||
Addproperty(loOut, "dSfarsitTvaInc", Iif(Pemstatus(loRezANAF, 'dSfarsitTvaInc', 5), Nvl(loRezANAF.dSfarsitTvaInc, {}), {}))
|
||||
Addproperty(loOut, "dData", m.ldData)
|
||||
Addproperty(loOut, "cSursa", Iif(Pemstatus(loRezANAF, 'cSursa', 5), loRezANAF.cSursa, 'ANAF'))
|
||||
Addproperty(loOut, "dDataSursa", Iif(Pemstatus(loRezANAF, 'dDataSursa', 5), Nvl(loRezANAF.dDataSursa, {}), {}))
|
||||
@@ -233,6 +236,9 @@ Procedure ANAF_CitesteDinIstoric
|
||||
Addproperty(loRez, "dSfarsitScpTVA", Nvl(data_sfarsit_ScpTVA, {}))
|
||||
Addproperty(loRez, "dAnulareScpTVA", Nvl(data_anul_imp_ScpTVA, {}))
|
||||
Addproperty(loRez, "cMesajScpTVA", Nvl(mesaj_ScpTVA, ""))
|
||||
Addproperty(loRez, "lTvaIncasare", Nvl(statusTvaIncasare, .F.))
|
||||
Addproperty(loRez, "dInceputTvaInc", Nvl(dataInceputTvaInc, {}))
|
||||
Addproperty(loRez, "dSfarsitTvaInc", Nvl(dataSfarsitTvaInc, {}))
|
||||
Addproperty(loRez, "cSursa", m.tcSursa)
|
||||
Addproperty(loRez, "dDataSursa", Nvl(data_sursa, {}))
|
||||
Endif
|
||||
@@ -844,7 +850,7 @@ DEFINE CLASS anaf_verif_cautare AS Custom
|
||||
|
||||
PROCEDURE TextStare
|
||||
Lparameters toStare, tcPerioada
|
||||
Return Iif(toStare.lPlatitorANAF, 'Platitor TVA', 'Neplatitor TVA') + Nvl(m.tcPerioada, '') + Iif(toStare.lInactivANAF, ', Inactiv', '')
|
||||
Return Iif(toStare.lPlatitorANAF, 'Platitor TVA', 'Neplatitor TVA') + Nvl(m.tcPerioada, '') + Iif(toStare.lInactivANAF, ', Inactiv', '') + Iif(toStare.lTvaIncasareANAF, ', TVA la incasare', '')
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE SufixPerioadaTVA
|
||||
@@ -913,6 +919,11 @@ DEFINE CLASS anaf_verif_cautare AS Custom
|
||||
If !Empty(toStare.cMesajScpTVA)
|
||||
lcTxt = m.lcTxt + 'Mesaj ANAF: ' + Alltrim(toStare.cMesajScpTVA) + Chr(13)
|
||||
Endif
|
||||
If toStare.lTvaIncasareANAF
|
||||
lcTxt = m.lcTxt + 'TVA la incasare' + ;
|
||||
Iif(!Empty(toStare.dInceputTvaInc), ' din ' + Dtoc(toStare.dInceputTvaInc), '') + ;
|
||||
Iif(!Empty(toStare.dSfarsitTvaInc), ' pana la ' + Dtoc(toStare.dSfarsitTvaInc), '') + Chr(13)
|
||||
Endif
|
||||
If !Empty(m.lcTxt)
|
||||
lcTxt = m.lcTxt + Chr(13)
|
||||
Endif
|
||||
@@ -3161,7 +3172,7 @@ Endproc && caut_politici_curente_util
|
||||
************************************** SFARSIT: caut_politici_curente_util **************************************
|
||||
***************************************** INCEPUT:caut_explicatie_tva *******************************************
|
||||
Function caut_explicatie_tva
|
||||
Parameters tnIdJtva, tnPornire, tlDesktop, tlTipEx
|
||||
Parameters tnIdJtva, tnPornire, tlDesktop, tlTipEx, tnCotaTva
|
||||
*!* tlTipEx = 0 - toate
|
||||
*!* = 1 - doar TVA exigibil din JC
|
||||
*!* = 2 - doar TVA neexigibil din JC
|
||||
@@ -3207,6 +3218,10 @@ Function caut_explicatie_tva
|
||||
lcFiltruOriginal = [id_jtva_coloana in (select id_tva from vjtva_coloane where ] + ;
|
||||
[id_jtva_ex is not null)]
|
||||
Endcase
|
||||
*** filtru suplimentar pe cota TVA a liniei curente; fara procent (0/gol) se pastreaza lista completa
|
||||
If Vartype(tnCotaTva) = 'N' And tnCotaTva > 0
|
||||
lcFiltruOriginal = lcFiltruOriginal + [ and cota_tva = ] + Alltrim(Str(tnCotaTva, 10, 2))
|
||||
Endif
|
||||
*!* *!* If tnIdJtva > 0
|
||||
*!* *!* lcFiltruOriginal = [jc * 4 + jv * 2 + decode(afisat,0,0,1) in ] + ;
|
||||
*!* *!* [(select jc * 4 + jv * 2 + decode(afisat,0,0,1) from ] + gcS + [.vjtva_coloane ] + ;
|
||||
|
||||
296
programe/ofacturare_editare.prg
Normal file
296
programe/ofacturare_editare.prg
Normal file
@@ -0,0 +1,296 @@
|
||||
*** ofacturare_editare
|
||||
|
||||
*!* 08.08.2026
|
||||
*!* marius.mutu
|
||||
*!* helpere comune pentru editarea unei facturi emise: garda eFactura, cursoarele notei si ale rulajelor,
|
||||
*!* randul de vanzare corespunzator notei si liniile de articole pentru pagina de articole factura
|
||||
|
||||
|
||||
*!* parametru: id_fact
|
||||
*!* verifica daca factura cu id_fact dat a fost deja trimisa in eFactura (anaf_efactura)
|
||||
FUNCTION EsteInEFactura
|
||||
LPARAMETERS tnIdFact
|
||||
|
||||
LOCAL lcSql, lnEFactura, llSucces
|
||||
lnEFactura = 0
|
||||
lcSql = [select count(*) as lneFactura from anaf_efactura where id_fact = ] + Alltrim(Str(Nvl(m.tnIdFact,0)))
|
||||
llSucces = goExecutor.oSelecteaza2Value(m.lcSql, @lnEFactura)
|
||||
|
||||
RETURN (Nvl(m.lnEFactura,0) > 0)
|
||||
ENDFUNC && EsteInEFactura
|
||||
|
||||
|
||||
*!* parametri: cod, an, luna, arata si randurile sterse (implicit .F.)
|
||||
*!* incarca cursoarele notei (tact) si ale rulajelor (trul, trul_obinv), cu recalculul de
|
||||
*!* valoare/valtva/valoarev/valtvav pe randurile goale; raman deschise READWRITE pe seama apelantului
|
||||
*!* pe eroare Oracle intoarce .F. si inchide ce a deschis pana atunci
|
||||
FUNCTION IncarcaCursoareModificareNota
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tlAratasterse
|
||||
|
||||
LOCAL lcConditieSters, lcSql, lcCursor, lnSucces
|
||||
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
Use In rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
Use In trul
|
||||
ENDIF
|
||||
IF Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
ENDIF
|
||||
IF Used('trul_obinv')
|
||||
Use In trul_obinv
|
||||
ENDIF
|
||||
|
||||
lcConditieSters = IIF(m.tlAratasterse, [ ], [ STERS = 0 AND ])
|
||||
|
||||
lcSql = [select * from vact_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_act]
|
||||
lcCursor = [v_act]
|
||||
lnSucces = goExecutor.oExecute(lcSql,lcCursor)
|
||||
goExecutor.oReset()
|
||||
|
||||
IF lnSucces < 0
|
||||
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
SELECT * FROM v_act INTO CURSOR actactan
|
||||
SELECT .F. AS ales, T.*, CAST(0 AS N(2)) AS tipnota FROM actactan T INTO CURSOR tact READWRITE
|
||||
USE IN v_act
|
||||
|
||||
IF lnSucces > 0
|
||||
lcSql = [select * from vrul_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul]
|
||||
lcCursor = [v_rul]
|
||||
|
||||
lnSucces = goExecutor.oExecute(lcSql,lcCursor)
|
||||
goExecutor.oReset()
|
||||
IF lnSucces < 0
|
||||
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
IF lnSucces > 0
|
||||
UPDATE v_rul SET valoare = ROUND(IIF(cant<>0, cant, cante)*pret,m.gnPC) WHERE EMPTY(NVL(valoare,0))
|
||||
UPDATE v_rul SET valtva = ROUND(IIF(cant<>0, cant, cante)*pret * (IIF(!EMPTY(NVL(proc_tva,0)), proc_tva, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtva,0))
|
||||
UPDATE v_rul SET valoarev = ROUND(IIF(cant<>0, cant, cante)*pretv,m.gnPC) WHERE EMPTY(NVL(valoarev,0))
|
||||
UPDATE v_rul SET valtvav = ROUND(IIF(cant<>0, cant, cante)*pretv * (IIF(!EMPTY(NVL(proc_tvav,0)), proc_tvav, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtvav,0))
|
||||
|
||||
SELECT *, ;
|
||||
valoare + valtva AS valoarectva, ;
|
||||
valoarev + valtvav AS valoarevctva ;
|
||||
FROM v_rul ;
|
||||
INTO CURSOR RUL_TEMP READWRITE
|
||||
|
||||
SELECT * FROM RUL_TEMP INTO CURSOR trul READWRITE
|
||||
USE IN v_rul
|
||||
|
||||
lcSql = [select * from vrul_obinv_tot where ] + lcConditieSters + [ an = ] + Transform(m.tnAn) + [ and luna = ] + Transform(m.tnLuna) + [ and cod = ] + Alltrim(Str(m.tnCod)) + [ order by id_rul_obinv]
|
||||
lcCursor = [v_rul_obinv]
|
||||
|
||||
lnSucces = goExecutor.oExecute(lcSql,lcCursor)
|
||||
goExecutor.oReset()
|
||||
IF lnSucces < 0
|
||||
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
Use In rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
Use In trul
|
||||
ENDIF
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
IF lnSucces > 0
|
||||
UPDATE v_rul_obinv SET valoare = ROUND(IIF(cant<>0, cant, cante)*pret,m.gnPC) WHERE EMPTY(NVL(valoare,0))
|
||||
UPDATE v_rul_obinv SET valtva = ROUND(IIF(cant<>0, cant, cante)*pret * (IIF(!EMPTY(NVL(proc_tva,0)), proc_tva, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtva,0))
|
||||
UPDATE v_rul_obinv SET valoarev = ROUND(IIF(cant<>0, cant, cante)*pretv,m.gnPC) WHERE EMPTY(NVL(valoarev,0))
|
||||
UPDATE v_rul_obinv SET valtvav = ROUND(IIF(cant<>0, cant, cante)*pretv * (IIF(!EMPTY(NVL(proc_tvav,0)), proc_tvav, 1)-1), m.gnPC) WHERE EMPTY(NVL(valtvav,0))
|
||||
|
||||
SELECT *, ;
|
||||
valoare + valtva AS valoarectva, ;
|
||||
valoarev + valtvav AS valoarevctva ;
|
||||
FROM v_rul_obinv ;
|
||||
INTO CURSOR RUL_TEMP_OBINV READWRITE
|
||||
|
||||
SELECT * FROM RUL_TEMP_OBINV INTO CURSOR trul_obinv READWRITE
|
||||
USE IN v_rul_obinv
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
RETURN .T.
|
||||
ENDFUNC && IncarcaCursoareModificareNota
|
||||
|
||||
|
||||
*!* creeaza cursorul tvanz gol (structura VANZARI redusa) - fallback la eroare Oracle sau cod/data lipsa
|
||||
FUNCTION CreeazaCursorTvanzGol
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
CREATE CURSOR tvanz (id_vanzare I, tip I, discount N(12,2), total_fara_tva N(14,2), total_tva N(14,2), total_cu_tva N(14,2))
|
||||
ENDFUNC && CreeazaCursorTvanzGol
|
||||
|
||||
|
||||
*!* parametri: cod, nract, serie_act, dataact (din cursorul notei, ex. tact)
|
||||
*!* incarca in tvanz randul din VANZARI al notei; cod singur nu e unic, de aceea filtrul cere tot setul
|
||||
*!* tvanz ramane deschis READWRITE, cu 0 randuri daca nu s-a gasit sau la eroare Oracle
|
||||
FUNCTION IncarcaVanzareNota
|
||||
LPARAMETERS tnCod, tnNract, tcSerieAct, tdDataAct
|
||||
|
||||
LOCAL lcSql, lnSucces, lcSerieAct
|
||||
|
||||
IF Used('v_vanz')
|
||||
Use In v_vanz
|
||||
ENDIF
|
||||
|
||||
IF Empty(m.tnCod) OR Empty(m.tdDataAct)
|
||||
CreeazaCursorTvanzGol()
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
|
||||
lcSerieAct = Alltrim(Nvl(m.tcSerieAct,""))
|
||||
|
||||
lcSql = [select id_vanzare, tip, discount, total_fara_tva, total_tva, total_cu_tva from vanzari where cod = ] + Transform(m.tnCod) + ;
|
||||
[ and Nvl(numar_act,-1) = ] + Transform(Nvl(m.tnNract,-1)) + ;
|
||||
[ and Nvl(serie_act,'') = '] + m.lcSerieAct + [' and trunc(data_act) = to_date('] + Dtoc(m.tdDataAct,1) + [','YYYYMMDD') and sters = 0]
|
||||
|
||||
lnSucces = goExecutor.oExecute(lcSql,[v_vanz])
|
||||
goExecutor.oReset()
|
||||
|
||||
IF lnSucces < 0
|
||||
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
|
||||
CreeazaCursorTvanzGol()
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
SELECT * FROM v_vanz INTO CURSOR tvanz READWRITE
|
||||
USE IN v_vanz
|
||||
|
||||
RETURN .T.
|
||||
ENDFUNC && IncarcaVanzareNota
|
||||
|
||||
|
||||
*!* parametru: alias cu randurile notei (tact), cu campurile cod/nract/serie_act/dataact/sters
|
||||
*!* incearca toate combinatiile distincte (cod, nract, serie_act, dataact) din alias (sters=0) pana
|
||||
*!* gaseste un rand in VANZARI; lasa workarea si pozitia curenta neschimbate, .F. cu tvanz gol daca nu gaseste
|
||||
FUNCTION IncarcaVanzareDinNota
|
||||
LPARAMETERS tcAliasAct
|
||||
|
||||
LOCAL lnAreaOrigine, lnRecnoOrigine, llGasit
|
||||
|
||||
lnAreaOrigine = Select()
|
||||
llGasit = .F.
|
||||
|
||||
IF Empty(m.tcAliasAct) OR !Used(m.tcAliasAct) OR Reccount(m.tcAliasAct) = 0
|
||||
CreeazaCursorTvanzGol()
|
||||
IF m.lnAreaOrigine > 0
|
||||
SELECT (m.lnAreaOrigine)
|
||||
ENDIF
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
lnRecnoOrigine = Recno(m.tcAliasAct)
|
||||
|
||||
IF Used('tmp_triplete_pozvanz')
|
||||
Use In tmp_triplete_pozvanz
|
||||
ENDIF
|
||||
*!* cod se ia tot din cursor, nu de pe randul curent - acesta poate fi la EOF dupa CalculeazaTotal
|
||||
SELECT DISTINCT cod, nract, serie_act, dataact FROM (m.tcAliasAct) WHERE sters = 0 INTO CURSOR tmp_triplete_pozvanz READWRITE
|
||||
|
||||
SELECT tmp_triplete_pozvanz
|
||||
SCAN
|
||||
IncarcaVanzareNota(cod, nract, serie_act, dataact)
|
||||
IF Reccount('tvanz') = 1
|
||||
llGasit = .T.
|
||||
EXIT
|
||||
ENDIF
|
||||
ENDSCAN
|
||||
|
||||
IF Used('tmp_triplete_pozvanz')
|
||||
Use In tmp_triplete_pozvanz
|
||||
ENDIF
|
||||
|
||||
IF !m.llGasit
|
||||
CreeazaCursorTvanzGol()
|
||||
ENDIF
|
||||
|
||||
IF Used(m.tcAliasAct)
|
||||
IF m.lnRecnoOrigine > 0 AND m.lnRecnoOrigine <= Reccount(m.tcAliasAct)
|
||||
Go (m.lnRecnoOrigine) In (m.tcAliasAct)
|
||||
ELSE
|
||||
*!* pozitia initiala era EOF (Recno() peste Reccount()) - se restaureaza tot la EOF
|
||||
Go Bottom In (m.tcAliasAct)
|
||||
Skip In (m.tcAliasAct)
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF m.lnAreaOrigine > 0
|
||||
SELECT (m.lnAreaOrigine)
|
||||
ENDIF
|
||||
|
||||
RETURN m.llGasit
|
||||
ENDFUNC && IncarcaVanzareDinNota
|
||||
|
||||
|
||||
*!* creeaza cursorul tvd gol, cu structura view-ului VVANZARI_ARTICOLE
|
||||
FUNCTION CreeazaCursorTvdGol
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
CREATE CURSOR tvd (id_vanzare I, id_vanzare_det I, id_articol I, cantitate N(12,3), pret N(14,4), pret_cu_tva N(14,4), proc_tvav N(6,4), ;
|
||||
discount_unitar N(14,4), id_gestiune I, cont C(20), id_valuta I, id_jtva_coloana I, serie C(20), explicatie C(60), ;
|
||||
taxcode I, lot C(20), sters I, denumire C(100), codmat C(30), nume_gestiune C(60), nume_val C(20))
|
||||
ENDFUNC && CreeazaCursorTvdGol
|
||||
|
||||
|
||||
*!* parametru: id_vanzare
|
||||
*!* incarca in tvd liniile active (sters=0) ale vanzarii, din VVANZARI_ARTICOLE
|
||||
*!* tvd ramane deschis READWRITE, cu 0 randuri la eroare Oracle
|
||||
FUNCTION IncarcaArticoleFactura
|
||||
LPARAMETERS tnIdVanzare
|
||||
|
||||
LOCAL lcSql, lnSucces
|
||||
|
||||
IF Used('v_vd')
|
||||
Use In v_vd
|
||||
ENDIF
|
||||
|
||||
lcSql = [select * from vvanzari_articole where id_vanzare = ] + Transform(Nvl(m.tnIdVanzare,0)) + [ and sters = 0 order by id_vanzare_det]
|
||||
|
||||
lnSucces = goExecutor.oExecute(lcSql,[v_vd])
|
||||
goExecutor.oReset()
|
||||
|
||||
IF lnSucces < 0
|
||||
AMESSAGEBOX(goExecutor.cEroare,0+16,"Eroare")
|
||||
CreeazaCursorTvdGol()
|
||||
RETURN .T.
|
||||
ENDIF
|
||||
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
SELECT * FROM v_vd INTO CURSOR tvd READWRITE
|
||||
USE IN v_vd
|
||||
|
||||
RETURN .T.
|
||||
ENDFUNC && IncarcaArticoleFactura
|
||||
@@ -4618,7 +4618,9 @@ Procedure verificare_parteneri_istoric
|
||||
Endif
|
||||
|
||||
Text To lcSql Noshow
|
||||
select id, dataora, id_util, dataorav, id_utilv, cod_fiscal, firma, adresa, judet, regcom, codpostal, telefon, fax, datatvamfin, platitortvamfin, stare, platitortvavies, util, utilv
|
||||
select id, dataora, id_util, dataorav, id_utilv, cod_fiscal, firma, adresa, judet, regcom, codpostal, telefon, fax, datatvamfin, platitortvamfin, stare, platitortvavies,
|
||||
dataorav_anaf, tvaincasare, splittva, inactiv, data_inceput_scptva, data_sfarsit_scptva, data_anul_imp_scptva, data_inceput_tvainc, data_sfarsit_tvainc, data_inactivare, data_reactivare,
|
||||
util, utilv
|
||||
from vistoric_coduri_fiscale
|
||||
where cod_fiscal = ?pcCodFiscal
|
||||
Endtext
|
||||
|
||||
@@ -1741,6 +1741,9 @@ Function ANAF_VerdictDinCursor
|
||||
Addproperty(loResult, "dSfarsitScpTVA", Nvl(data_sfarsit_ScpTVA, {}))
|
||||
Addproperty(loResult, "dAnulareScpTVA", Nvl(data_anul_imp_ScpTVA, {}))
|
||||
Addproperty(loResult, "cMesajScpTVA", Nvl(mesaj_ScpTVA, ""))
|
||||
Addproperty(loResult, "lTvaIncasare", Nvl(tvaincasare, .F.))
|
||||
Addproperty(loResult, "dInceputTvaInc", Nvl(dataInceputTvaInc, {}))
|
||||
Addproperty(loResult, "dSfarsitTvaInc", Nvl(dataSfarsitTvaInc, {}))
|
||||
Else
|
||||
If m.lnReccountTemp = 1 And Empty(denumire) And Nvl(cui, 0) = m.tnCuiCautat
|
||||
tlNegasit = .T.
|
||||
@@ -2669,10 +2672,10 @@ Define Class VerificareANAF As Custom
|
||||
lnRecnoInit = Recno()
|
||||
Scan For cui <> 0 And Left(Nvl(sursa, ''), 5) <> 'CACHE'
|
||||
pcCodFiscal = Transform(cui)
|
||||
pcFirma = Nvl(firma, '')
|
||||
pcAdresa = Nvl(adresa, '')
|
||||
pcJudet = Nvl(judet, '')
|
||||
pcRegCom = Nvl(nrRegCom, '')
|
||||
pcFirma = Alltrim(Nvl(firma, ''))
|
||||
pcAdresa = Alltrim(Nvl(adresa, ''))
|
||||
pcJudet = Alltrim(Nvl(judet, ''))
|
||||
pcRegCom = Alltrim(Nvl(nrRegCom, ''))
|
||||
pcCodPostal = ''
|
||||
pcTelefon = ''
|
||||
pcFax = ''
|
||||
|
||||
@@ -371,7 +371,7 @@ Define Class ExportEFactura As Custom
|
||||
lcTextAditional = m.lcTextAditional + Iif(!Empty(m.lcTextAditional), ' # ', '') + "Taxare inversa"
|
||||
ENDIF
|
||||
|
||||
IF !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
|
||||
IF loDate.in_valuta = 1 AND !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
|
||||
lcTextAditional = m.lcTextAditional + Iif(!Empty(m.lcTextAditional), ' # ', '') + "Curs: " + ALLTRIM(STR(loDate.curs, 10,4)) + " RON/" + STRTRAN(ALLTRIM(Nvl(loDate.cValuta, '')),'EURO', 'EUR',1,1,1)
|
||||
ENDIF
|
||||
|
||||
|
||||
@@ -2434,7 +2434,7 @@ DEFINE CLASS gridutils AS form
|
||||
PROCEDURE copytoexcel
|
||||
*!* LPARAMETERS tcXLSFile, tcSheet, tvWorkArea, tcExcelFieldList, tcTableFieldList, tcTableForExpr
|
||||
#DEFINE ALPHANUMERICCHR "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz1234567890"
|
||||
LOCAL lnCounter, loColumn, lcXLSFile, lcSheetName, lcAliasWas, lcGridAlias, ;
|
||||
LOCAL lnCounter, lnOrder, laOrder, loColumn, lcXLSFile, lcSheetName, lcAliasWas, lcGridAlias, ;
|
||||
lcExcelFieldList, lcTableFieldList, lcTableForExpression, loHeaderObject, ;
|
||||
lcFileName, lcAction, lcPath, loExcelApp, loWorkBook, lcKeyName
|
||||
m.lcXLSFile = "C:\" + SYS(2015) + ".xls"
|
||||
@@ -2445,8 +2445,15 @@ DEFINE CLASS gridutils AS form
|
||||
*!* m.lcTableForExpression = FILTER(this.gridobject.recordsource)
|
||||
m.lcSheetName = "Sheet1"
|
||||
STORE "" TO m.lcExcelFieldList, m.lcTableFieldList
|
||||
*!* coloanele se exporta in ordinea de afisare din grid (ColumnOrder), nu in ordinea de creare
|
||||
DIMENSION laOrder[MAX(THIS.gridobject.COLUMNCOUNT, 1), 2]
|
||||
FOR m.lnCounter = 1 TO THIS.gridobject.COLUMNCOUNT
|
||||
m.loColumn = THIS.gridobject.COLUMNS(m.lnCounter)
|
||||
laOrder[m.lnCounter, 1] = THIS.gridobject.COLUMNS(m.lnCounter).COLUMNORDER
|
||||
laOrder[m.lnCounter, 2] = m.lnCounter
|
||||
ENDFOR
|
||||
=ASORT(laOrder)
|
||||
FOR m.lnOrder = 1 TO THIS.gridobject.COLUMNCOUNT
|
||||
m.loColumn = THIS.gridobject.COLUMNS(laOrder[m.lnOrder, 2])
|
||||
IF m.loColumn.VISIBLE AND m.loColumn.WIDTH > 0
|
||||
m.loHeaderObject = m.loColumn.CONTROLS(1)
|
||||
m.lcExcelFieldList = m.lcExcelFieldList + IIF(!EMPTY(m.lcExcelFieldList), ',', '') ;
|
||||
|
||||
@@ -245,11 +245,11 @@ TRY
|
||||
DO CreeazaIntrodc WITH 'introdc'
|
||||
DO CreeazaIntrodc WITH 'introdc_sablon'
|
||||
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
|
||||
id_jtva_coloana, ptva, explicatie_tva) ;
|
||||
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
|
||||
id_jtva_coloana, ptva, explicatie_tva, taxcode) ;
|
||||
VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%', 301204)
|
||||
INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
|
||||
id_jtva_coloana, ptva, explicatie_tva) ;
|
||||
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
|
||||
id_jtva_coloana, ptva, explicatie_tva, taxcode) ;
|
||||
VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%', 301204)
|
||||
GO TOP IN introdc_sablon
|
||||
|
||||
DO CreeazaRulTemp
|
||||
@@ -735,6 +735,34 @@ PROCEDURE VerificaRandD
|
||||
lcMsg = 'FAIL ' + tcLabel + '-randD: nu exista rand tip_rand=D in introdc dupa sincronizeaza() (diferenta asteptata=' + TRANSFORM(lnSumaAsteptata) + ')'
|
||||
ENDIF
|
||||
DO R7Log WITH lcMsg
|
||||
DO VerificaTaxCodeRandD WITH tcLabel
|
||||
SELECT (lnSel)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE VerificaTaxCodeRandD
|
||||
*-- randul D (diferenta 6xx) nu are cod de taxa SAFT; randurile de baza si TVA il pastreaza.
|
||||
LPARAMETERS tcLabel
|
||||
LOCAL lnSel, lcMsg, lnTaxD, lnFaraTax
|
||||
lnSel = SELECT()
|
||||
SELECT introdc
|
||||
LOCATE FOR tip_rand == 'D'
|
||||
IF !FOUND()
|
||||
DO R7Log WITH 'FAIL ' + tcLabel + '-randD-taxcode: nu exista rand tip_rand=D'
|
||||
SELECT (lnSel)
|
||||
RETURN
|
||||
ENDIF
|
||||
lnTaxD = NVL(taxcode, 0)
|
||||
lnFaraTax = 0
|
||||
SCAN FOR INLIST(tip_rand, 'B', 'S', 'T', 'G') AND EMPTY(NVL(taxcode, 0))
|
||||
lnFaraTax = lnFaraTax + 1
|
||||
ENDSCAN
|
||||
IF EMPTY(lnTaxD) AND lnFaraTax = 0
|
||||
lcMsg = 'PASS ' + tcLabel + '-randD-taxcode: randul D are taxcode gol, iar randurile B/S/T/G il pastreaza'
|
||||
ELSE
|
||||
lcMsg = 'FAIL ' + tcLabel + '-randD-taxcode: taxcode pe randul D=' + TRANSFORM(lnTaxD) + ;
|
||||
' (astept 0), randuri B/S/T/G fara taxcode=' + TRANSFORM(lnFaraTax) + ' (astept 0)'
|
||||
ENDIF
|
||||
DO R7Log WITH lcMsg
|
||||
SELECT (lnSel)
|
||||
ENDPROC
|
||||
|
||||
|
||||
72
utile/Teste/editare_factura/test_incarca_articole_view.prg
Normal file
72
utile/Teste/editare_factura/test_incarca_articole_view.prg
Normal file
@@ -0,0 +1,72 @@
|
||||
* test_incarca_articole_view.prg
|
||||
* Smoke test izolat pentru IncarcaArticoleFactura pe vvanzari_articole (runda 2), inainte de a atinge omodificari.vc2.
|
||||
* Regresie: id_vanzare=1050 (cod=1140888) -> 4 randuri, id_vanzare=1047 (cod=1140885) -> 2 randuri,
|
||||
* coincide cu baza din rec_view_articole_vanzare.md. Verifica si coloana noua tvd.id_vanzare.
|
||||
* Nu atinge Oracle in scriere. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_incarca_articole_view_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
DO verifica WITH 1050, 'cod=1140888', lcLog, 4
|
||||
DO verifica WITH 1047, 'cod=1140885', lcLog, 2
|
||||
|
||||
*!* cursorul gol - structura cu 21 de campuri, inclusiv id_vanzare (nou)
|
||||
CreeazaCursorTvdGol()
|
||||
STRTOFILE('--- CreeazaCursorTvdGol ---' + CHR(13) + CHR(10) + ;
|
||||
' Fcount(tvd) = ' + TRANSFORM(FCOUNT('tvd')) + ' (asteptat 21)' + CHR(13) + CHR(10) + ;
|
||||
' are id_vanzare: ' + TRANSFORM(TYPE('tvd.id_vanzare') <> 'U') + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(FCOUNT('tvd') == 21, 'PASS', 'FAIL') + CHR(13) + CHR(10), lcLog, 1)
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE verifica
|
||||
LPARAMETERS tnIdVanzare, tcEticheta, tcLog, tnLiniiAsteptate
|
||||
|
||||
LOCAL lnLinii, lnIdVanzareCol
|
||||
|
||||
IncarcaArticoleFactura(tnIdVanzare)
|
||||
lnLinii = Reccount('tvd')
|
||||
lnIdVanzareCol = -1
|
||||
IF lnLinii > 0
|
||||
SELECT tvd
|
||||
GO TOP
|
||||
lnIdVanzareCol = tvd.id_vanzare
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- id_vanzare=' + TRANSFORM(tnIdVanzare) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' Reccount(tvd) = ' + TRANSFORM(lnLinii) + ' (asteptat ' + TRANSFORM(tnLiniiAsteptate) + ')' + CHR(13) + CHR(10) + ;
|
||||
' tvd.id_vanzare pe primul rand = ' + TRANSFORM(lnIdVanzareCol) + ' (asteptat ' + TRANSFORM(tnIdVanzare) + ')' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(lnLinii == tnLiniiAsteptate AND (lnLinii == 0 OR lnIdVanzareCol == tnIdVanzare), 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
PROCEDURE test_error_handler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
141
utile/Teste/editare_factura/test_incarca_cursoare.prg
Normal file
141
utile/Teste/editare_factura/test_incarca_cursoare.prg
Normal file
@@ -0,0 +1,141 @@
|
||||
* test_incarca_cursoare.prg
|
||||
* Verifica IncarcaCursoareModificareNota (COMUN\programe\ofacturare_editare.prg) pe date reale:
|
||||
* cod=1140888 - nota cu rulaje (non-regresie)
|
||||
* cod=1140885 - nota FARA randuri in rul (productie/manopera, fara miscare de stoc)
|
||||
* si pozitionarea in actactan din do_editare_factura (ofacturare_comun.vc2), pe cursoare sintetice.
|
||||
* Nu atinge Oracle in scriere - doar SELECT-uri prin goExecutor. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_incarca_cursoare_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
STRTOFILE('gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
DO verifica_cod WITH 1140888, 'A (regresie, cu rulaje)', lcLog
|
||||
DO verifica_cod WITH 1140885, 'B (fara randuri in rul)', lcLog
|
||||
DO verifica_pozitionare_actactan WITH 9999995, 'a) nota normala, un singur id_fact pe toate randurile', lcLog, 5000, 5000, 25010, 100, .T.
|
||||
DO verifica_pozitionare_actactan WITH 9999996, 'b) prim rand INCASARE cu id_fact-1, Locate il sare', lcLog, 5000, 5000, 25010, 200, .T.
|
||||
DO verifica_pozitionare_actactan WITH 9999997, 'c) nota fara randul cu id_fact cerut, cade pe Go Top', lcLog, 9999, 7000, 25011, 50, .F.
|
||||
DO verifica_pozitionare_actactan WITH 9999998, 'd) lnIdFact=0 (aviz/transfer), direct Go Top', lcLog, 0, 8000, 25012, 10, .F.
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
* reproduce mecanica pozitionarii din do_editare_factura (ofacturare_comun.vc2): cauta in actactan
|
||||
* randul cu id_fact = lnIdFact (cel citit din crsfacturi/VANZARI.ID_FACT); daca nu-l gaseste (sau
|
||||
* lnIdFact e 0 - avize, transferuri), cade pe Go Top si preia id_fact de acolo. lnIdSet si
|
||||
* lnIdFactD se citesc mereu de pe randul gasit (Locate sau Go Top).
|
||||
PROCEDURE verifica_pozitionare_actactan
|
||||
LPARAMETERS tnCod, tcEticheta, tcLog, tnIdFactIntrare, tnIdFactAsteptat, tnIdSetAsteptat, tnIdFactDAsteptat, tlGasitAsteptat
|
||||
|
||||
LOCAL lnIdFact, lnIdSet, lnIdFactD, llGasitRand, llOk
|
||||
|
||||
CREATE CURSOR actactan (id_fact N(9), id_factd N(9), id_set N(9))
|
||||
DO CASE
|
||||
CASE tnCod = 9999995
|
||||
&& a) nota normala: toate randurile cu acelasi id_fact
|
||||
INSERT INTO actactan VALUES (5000, 100, 25010)
|
||||
INSERT INTO actactan VALUES (5000, 101, 25010)
|
||||
CASE tnCod = 9999996
|
||||
&& b) prim rand INCASARE, id_fact = id_fact-ul facturii - 1
|
||||
INSERT INTO actactan VALUES (4999, 0, 25010)
|
||||
INSERT INTO actactan VALUES (5000, 200, 25010)
|
||||
CASE tnCod = 9999997
|
||||
&& c) nota nu contine id_fact-ul cerut (document vechi)
|
||||
INSERT INTO actactan VALUES (7000, 50, 25011)
|
||||
CASE tnCod = 9999998
|
||||
&& d) aviz/transfer, fara id_fact la intrare
|
||||
INSERT INTO actactan VALUES (8000, 10, 25012)
|
||||
ENDCASE
|
||||
|
||||
lnIdFact = tnIdFactIntrare
|
||||
|
||||
SELECT actactan
|
||||
llGasitRand = .F.
|
||||
IF lnIdFact > 0
|
||||
LOCATE FOR NVL(id_fact, 0) = lnIdFact
|
||||
llGasitRand = FOUND()
|
||||
ENDIF
|
||||
IF !llGasitRand
|
||||
GO TOP
|
||||
lnIdFact = id_fact
|
||||
ENDIF
|
||||
lnIdSet = id_set
|
||||
lnIdFactD = id_factd
|
||||
USE IN actactan
|
||||
|
||||
llOk = (lnIdFact == tnIdFactAsteptat AND lnIdSet == tnIdSetAsteptat AND ;
|
||||
lnIdFactD == tnIdFactDAsteptat AND llGasitRand == tlGasitAsteptat)
|
||||
|
||||
STRTOFILE('--- pozitionare actactan, cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' gasit rand = ' + TRANSFORM(llGasitRand) + ' (asteptat ' + TRANSFORM(tlGasitAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_fact = ' + TRANSFORM(lnIdFact) + ' (asteptat ' + TRANSFORM(tnIdFactAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_set = ' + TRANSFORM(lnIdSet) + ' (asteptat ' + TRANSFORM(tnIdSetAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_factd = ' + TRANSFORM(lnIdFactD) + ' (asteptat ' + TRANSFORM(tnIdFactDAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llOk, 'OK', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE verifica_cod
|
||||
LPARAMETERS tnCod, tcEticheta, tcLog
|
||||
|
||||
LOCAL llOk, lcMsg, lnIdSetDistinct
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, gnAn, gnLuna, .F.)
|
||||
|
||||
lnIdSetDistinct = -1
|
||||
IF Used('actactan') AND Reccount('actactan') > 0
|
||||
SELECT Distinct id_set FROM actactan INTO CURSOR csr_idset_verif_test
|
||||
lnIdSetDistinct = Reccount('csr_idset_verif_test')
|
||||
USE IN csr_idset_verif_test
|
||||
ENDIF
|
||||
|
||||
lcMsg = '--- cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' IncarcaCursoareModificareNota => ' + TRANSFORM(llOk) + CHR(13) + CHR(10) + ;
|
||||
' Reccount(actactan) = ' + TRANSFORM(IIF(Used('actactan'), Reccount('actactan'), -1)) + CHR(13) + CHR(10) + ;
|
||||
' Reccount(tact) = ' + TRANSFORM(IIF(Used('tact'), Reccount('tact'), -1)) + CHR(13) + CHR(10) + ;
|
||||
' id_set distincte in actactan = ' + TRANSFORM(lnIdSetDistinct) + CHR(13) + CHR(10) + ;
|
||||
' Used(trul) = ' + TRANSFORM(Used('trul')) + ' Reccount(trul) = ' + TRANSFORM(IIF(Used('trul'), Reccount('trul'), -1)) + CHR(13) + CHR(10) + ;
|
||||
' Used(trul_obinv) = ' + TRANSFORM(Used('trul_obinv')) + ' Reccount(trul_obinv) = ' + TRANSFORM(IIF(Used('trul_obinv'), Reccount('trul_obinv'), -1)) + CHR(13) + CHR(10)
|
||||
|
||||
STRTOFILE(lcMsg, tcLog, 1)
|
||||
|
||||
IF Used('actactan')
|
||||
USE IN actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
USE IN tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
USE IN rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
USE IN trul
|
||||
ENDIF
|
||||
IF Used('rul_temp_obinv')
|
||||
USE IN rul_temp_obinv
|
||||
ENDIF
|
||||
IF Used('trul_obinv')
|
||||
USE IN trul_obinv
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE test_error_handler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
154
utile/Teste/editare_factura/test_incarca_vanzare_din_nota.prg
Normal file
154
utile/Teste/editare_factura/test_incarca_vanzare_din_nota.prg
Normal file
@@ -0,0 +1,154 @@
|
||||
* test_incarca_vanzare_din_nota.prg
|
||||
* Smoke test izolat pentru IncarcaVanzareDinNota (ofacturare_editare.prg), inainte de a atinge
|
||||
* omodificari.vc2 runda 2. Verifica pe cazurile de regresie ale bugului "Go Top orb pe tact":
|
||||
* cod=1137874/an=2009/luna=8 -> trebuie sa gaseasca id_vanzare=506 (azi, cu Go Top orb, da 0 randuri)
|
||||
* cod=1139934/an=2021/luna=12 -> id_vanzare=882 (coliziune VANZARI.COD deja cunoscuta)
|
||||
* plus regresie pe cazurile vechi: cod=1140888 -> id_vanzare=1050; cod=1125486 -> nu gaseste (tact fara VANZARI)
|
||||
* plus cazul EOF: tact pozitionat deliberat la EOF (ca dupa CalculeazaTotal() din Show()) inainte de
|
||||
* apel - dovedeste ca "cod" se ia din cursorul de triplete (SELECT DISTINCT), nu de pe randul curent
|
||||
* Nu atinge Oracle in scriere - doar SELECT-uri prin goExecutor. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_incarca_vanzare_din_nota_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
DO verifica WITH 1137874, 2009, 8, 'blocant Go Top - prim rand INCASARE', lcLog, .T., 506
|
||||
DO verifica WITH 1139934, 2021, 12, 'coliziune VANZARI.COD', lcLog, .T., 882
|
||||
DO verifica WITH 1140888, (gnAn), (gnLuna), 'regresie runda 1 - factura normala', lcLog, .T., 1050
|
||||
DO verifica WITH 1125486, 2008, 2, 'regresie runda 1 - fara VANZARI', lcLog, .F., 0
|
||||
DO verifica_eof WITH 1137874, 2009, 8, lcLog, 506
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
* pozitioneaza tact deliberat la EOF (Go Bottom + Skip) inainte de IncarcaVanzareDinNota - dovedeste
|
||||
* ca "cod" nu se mai citeste de pe randul curent al aliasului (corectia care a inlocuit Evaluate(alias.cod))
|
||||
PROCEDURE verifica_eof
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcLog, tnIdVanzareAsteptat
|
||||
|
||||
LOCAL llOk, llGasit, lnIdVanzare, llEofInainte, llEofDupa
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
llGasit = .F.
|
||||
lnIdVanzare = 0
|
||||
llEofInainte = .F.
|
||||
llEofDupa = .F.
|
||||
|
||||
IF llOk AND Used('tact')
|
||||
SELECT tact
|
||||
Go Bottom In tact
|
||||
Skip In tact
|
||||
llEofInainte = Eof('tact')
|
||||
llGasit = IncarcaVanzareDinNota('tact')
|
||||
llEofDupa = Eof('tact')
|
||||
IF llGasit
|
||||
lnIdVanzare = tvanz.id_vanzare
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- EOF pe tact, cod=' + TRANSFORM(tnCod) + ' [pozitionare la EOF inainte de apel] ---' + CHR(13) + CHR(10) + ;
|
||||
' Eof(tact) inainte de apel = ' + TRANSFORM(llEofInainte) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' gasit = ' + TRANSFORM(llGasit) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' Eof(tact) dupa apel (pozitia restaurata) = ' + TRANSFORM(llEofDupa) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llEofInainte AND llGasit AND lnIdVanzare == tnIdVanzareAsteptat AND llEofDupa, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
Use In rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
Use In trul
|
||||
ENDIF
|
||||
IF Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
ENDIF
|
||||
IF Used('trul_obinv')
|
||||
Use In trul_obinv
|
||||
ENDIF
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
PROCEDURE verifica
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcEticheta, tcLog, tlAsteptatGasit, tnIdVanzareAsteptat
|
||||
|
||||
LOCAL llOk, llGasit, lnIdVanzare, lcMsg, lnAreaOrigineTest, lcAliasOrigineTest
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
llGasit = .F.
|
||||
lnIdVanzare = 0
|
||||
lnAreaOrigineTest = 0
|
||||
lcAliasOrigineTest = ''
|
||||
|
||||
IF llOk AND Used('tact')
|
||||
SELECT tact
|
||||
lnAreaOrigineTest = Select()
|
||||
lcAliasOrigineTest = Alias()
|
||||
llGasit = IncarcaVanzareDinNota('tact')
|
||||
IF llGasit
|
||||
lnIdVanzare = tvanz.id_vanzare
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
lcMsg = '--- cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' IncarcaCursoareModificareNota => ' + TRANSFORM(llOk) + CHR(13) + CHR(10) + ;
|
||||
' gasit = ' + TRANSFORM(llGasit) + ' (asteptat ' + TRANSFORM(tlAsteptatGasit) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' workarea restaurata la ' + TRANSFORM(lnAreaOrigineTest) + ': ' + TRANSFORM(Select() == lnAreaOrigineTest) + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llGasit == tlAsteptatGasit AND lnIdVanzare == tnIdVanzareAsteptat AND Select() == lnAreaOrigineTest, 'PASS', 'FAIL') + CHR(13) + CHR(10)
|
||||
|
||||
STRTOFILE(lcMsg, tcLog, 1)
|
||||
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
Use In rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
Use In trul
|
||||
ENDIF
|
||||
IF Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
ENDIF
|
||||
IF Used('trul_obinv')
|
||||
Use In trul_obinv
|
||||
ENDIF
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
PROCEDURE test_error_handler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
305
utile/Teste/editare_factura/test_page3_articole.prg
Normal file
305
utile/Teste/editare_factura/test_page3_articole.prg
Normal file
@@ -0,0 +1,305 @@
|
||||
* test_page3_articole.prg
|
||||
* Verifica S4 runda 1+2 (PAGE3, view VVANZARI_ARTICOLE, pozitionare in tact, garda ROACONT/ROAGEST) pe date reale:
|
||||
* - IncarcaVanzareNota/IncarcaArticoleFactura (ofacturare_editare.prg) direct, pe cod=1140888,
|
||||
* cod=1140885 (au rand in VANZARI) si cod=1125486 (nota fara rand in VANZARI)
|
||||
* - cazul de coliziune pe cod: cod=1139934 are 4 randuri VANZARI cu acelasi cod - verifica ca
|
||||
* filtrul compus (cod+nract+serie_act+data_act) gaseste exact randul corect si NU gaseste
|
||||
* nimic pentru un nract fara corespondent (evitarea unei potriviri gresite)
|
||||
* - frm_modific2024 instantiat ca in do_editare_factura (Createobject+Show): PageCount ajunge 3
|
||||
* pe documente cu rand in VANZARI, ramane 2 pe o nota fara VANZARI
|
||||
* - regresie runda 2: cod=1137874/an=2009/luna=8 si cod=1139934/an=2021/luna=12, unde primul
|
||||
* rand din tact e o INCASARE - Go Top orb (runda 1) rata id_vanzare, IncarcaVanzareDinNota il
|
||||
* gaseste prin toate tripletele distincte (nract,serie_act,dataact) din tact
|
||||
* - garda ROACONT/ROAGEST: cu ofacturare_editare.prg eliberat din SET PROCEDURE, Show() degradeaza
|
||||
* curat la PageCount=2, fara eroare
|
||||
* Nu atinge Oracle in scriere - doar SELECT-uri prin goExecutor. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_page3_articole_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
*!* OBLIGATORIU: test_init_env_auto:139 face "Set Classlib To omodificari Additive", iar SET PATH
|
||||
*!* e pe D:\ROA\ROACONT\..., deci se incarca copia ROACONT a clasei (alt working copy, fara
|
||||
*!* modificarile noastre). O eliberam si o reincarcam pe cea DE SUB TEST, cu cale completa -
|
||||
*!* altfel Createobject valideaza cu totul alt fisier decat cel editat.
|
||||
RELEASE CLASSLIB omodificari
|
||||
SET CLASSLIB TO D:\ROA\ROAFACTURARE\COMUN\clase\omodificari.vcx ADDITIVE
|
||||
|
||||
*!* 1) IncarcaVanzareNota / IncarcaArticoleFactura direct, pe documente reale
|
||||
*!* (gnAn)/(gnLuna) in paranteze = pasare PRIN VALOARE: DO ... WITH paseaza prin REFERINTA, iar o
|
||||
*!* variabila pasata prin referinta devine invizibila sub numele ei propriu in procedura apelata -
|
||||
*!* de acolo venea dialogul nativ "View Parameter: Enter the value for gnAn" (?gnAn din SQL passthrough)
|
||||
DO verifica_vanzare_nota WITH 1140888, (gnAn), (gnLuna), 'A (factura, cu articole)', lcLog, .T., 1050, 1, 4
|
||||
DO verifica_vanzare_nota WITH 1140885, (gnAn), (gnLuna), 'B (aviz/tip -12, cu rand in VANZARI)', lcLog, .T., 1047, -12, -1
|
||||
DO verifica_vanzare_nota WITH 1125486, 2008, 2, 'C (nota fara rand in VANZARI)', lcLog, .F., 0, 0, -1
|
||||
|
||||
*!* 2) cazul de coliziune pe cod=1139934 (4 randuri VANZARI cu acelasi cod) - filtrul compus
|
||||
DO verifica_coliziune_cod WITH lcLog
|
||||
|
||||
*!* 3) frm_modific2024 - PageCount pe factura reala (cod=1140888) si pe nota fara VANZARI (cod=1125486)
|
||||
DO verifica_pagecount_form WITH 1140888, (gnAn), (gnLuna), 'A (factura reala)', lcLog, 3, .T., 1050
|
||||
DO verifica_pagecount_form WITH 1125486, 2008, 2, 'C (nota fara VANZARI)', lcLog, 2, .F., 0
|
||||
|
||||
*!* 4) regresie runda 2 - blocantul "Go Top orb pe tact": prim rand din tact e o INCASARE, cu
|
||||
*!* nract/serie_act/dataact diferite de randul facturii - Go Top orb (runda 1) rata id_vanzare
|
||||
DO verifica_pagecount_form WITH 1137874, 2009, 8, 'D (Go Top orb - blocant runda 2)', lcLog, 3, .T., 506
|
||||
DO verifica_pagecount_form WITH 1139934, 2021, 12, 'E (coliziune cod + Go Top orb)', lcLog, 3, .T., 882
|
||||
|
||||
*!* 5) garda ROACONT/ROAGEST: cu ofacturare_editare.prg eliberat, Show() nu mai gaseste garda si
|
||||
*!* degradeaza curat la PageCount=2 - ultimul test, elibereaza procedura definitiv pentru restul rularii
|
||||
DO verifica_garda_procedura_lipsa WITH 1140888, (gnAn), (gnLuna), lcLog
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE verifica_vanzare_nota
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcEticheta, tcLog, tlAsteptatGasit, tnIdVanzareAsteptat, tnTipAsteptat, tnLiniiAsteptate
|
||||
|
||||
LOCAL llOk, lcMsg, llGasit, lnIdVanzare, lnTip, lnLinii, llIdOk, llTipOk, llLiniiOk
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
|
||||
llGasit = .F.
|
||||
lnIdVanzare = 0
|
||||
lnTip = 0
|
||||
lnLinii = -1
|
||||
|
||||
IF llOk AND Used('tact') AND Reccount('tact') > 0
|
||||
Go Top In tact
|
||||
IncarcaVanzareNota(tact.cod, tact.nract, tact.serie_act, tact.dataact)
|
||||
IF Reccount('tvanz') = 1
|
||||
llGasit = .T.
|
||||
lnIdVanzare = tvanz.id_vanzare
|
||||
lnTip = tvanz.tip
|
||||
IncarcaArticoleFactura(lnIdVanzare)
|
||||
lnLinii = Reccount('tvd')
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
llIdOk = IIF(tlAsteptatGasit, lnIdVanzare == tnIdVanzareAsteptat, .T.)
|
||||
llTipOk = IIF(tlAsteptatGasit, lnTip == tnTipAsteptat, .T.)
|
||||
llLiniiOk = IIF(tlAsteptatGasit AND tnLiniiAsteptate >= 0, lnLinii == tnLiniiAsteptate, .T.)
|
||||
|
||||
lcMsg = '--- cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' IncarcaCursoareModificareNota => ' + TRANSFORM(llOk) + CHR(13) + CHR(10) + ;
|
||||
' gasit in vanzari = ' + TRANSFORM(llGasit) + ' (asteptat ' + TRANSFORM(tlAsteptatGasit) + ')' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' tip = ' + TRANSFORM(lnTip) + ' (asteptat ' + TRANSFORM(tnTipAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' Reccount(tvd) = ' + TRANSFORM(lnLinii) + ' (asteptat ' + TRANSFORM(tnLiniiAsteptate) + ')' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llGasit == tlAsteptatGasit AND llIdOk AND llTipOk AND llLiniiOk, 'PASS', 'FAIL') + CHR(13) + CHR(10)
|
||||
|
||||
STRTOFILE(lcMsg, tcLog, 1)
|
||||
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
Use In rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
Use In trul
|
||||
ENDIF
|
||||
IF Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
ENDIF
|
||||
IF Used('trul_obinv')
|
||||
Use In trul_obinv
|
||||
ENDIF
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
* cod=1139934 are 4 randuri active in VANZARI cu acelasi cod (verificat pe MARIUSM_AUTO):
|
||||
* id_vanzare=882 numar_act=375/SSS, 883=24/PF, 884=25/PF, 885=26/PF - filtrul pe cod singur
|
||||
* ar fi ambiguu; filtrul compus (cod+nract+serie_act+data_act) trebuie sa gaseasca exact
|
||||
* randul cerut si sa NU gaseasca nimic pentru un nract fara corespondent in VANZARI (ACT are
|
||||
* randuri cu nract=13 pe acelasi cod, fara VANZARI corespunzator)
|
||||
PROCEDURE verifica_coliziune_cod
|
||||
LPARAMETERS tcLog
|
||||
|
||||
LOCAL ldDataAct, llOk1, llOk2
|
||||
|
||||
ldDataAct = DATE(2021,12,31)
|
||||
|
||||
IncarcaVanzareNota(1139934, 375, 'SSS', ldDataAct)
|
||||
llOk1 = (Reccount('tvanz') = 1 AND tvanz.id_vanzare == 882)
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
|
||||
IncarcaVanzareNota(1139934, 13, '', ldDataAct)
|
||||
llOk2 = (Reccount('tvanz') = 0)
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- coliziune cod=1139934 (4 randuri VANZARI cu acelasi cod) ---' + CHR(13) + CHR(10) + ;
|
||||
' nract=375/SSS => gaseste id_vanzare=882: ' + IIF(llOk1, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
||||
' nract=13 (fara corespondent) => 0 randuri: ' + IIF(llOk2, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDPROC
|
||||
|
||||
|
||||
* instantiaza frm_modific2024 exact ca in do_editare_factura (ofacturare_comun.vc2:3781-3803):
|
||||
* IncarcaCursoareModificareNota, rebuild tact cu coloana cu_Tva, Createobject+Show; verifica
|
||||
* pgfArticole.PageCount si proprietatile de detectie dupa Show()
|
||||
PROCEDURE verifica_pagecount_form
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcEticheta, tcLog, tnPageCountAsteptat, tlAreArticoleAsteptat, tnIdVanzareAsteptat
|
||||
|
||||
LOCAL llOk, lnIdSet, lnPageCount, llAreArticole, lnIdVanzare, loForm, llIdVanzareOk
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
lnPageCount = -1
|
||||
llAreArticole = .F.
|
||||
lnIdVanzare = 0
|
||||
|
||||
IF llOk AND Used('tact') AND Reccount('tact') > 0
|
||||
Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
|
||||
Go Top In tact
|
||||
lnIdSet = tact.id_set
|
||||
|
||||
IF !Used('crsJtvaTemp')
|
||||
update_jtva_coloane("", "crsJtvaTemp", 6)
|
||||
ENDIF
|
||||
|
||||
Select tact
|
||||
loForm = Createobject([frm_modific2024], lnIdSet)
|
||||
loForm.WindowType = 0
|
||||
loForm.Show()
|
||||
|
||||
lnPageCount = loForm.pgfArticole.PageCount
|
||||
llAreArticole = loForm.lAreArticoleVanzari
|
||||
lnIdVanzare = loForm.nIdVanzare
|
||||
|
||||
loForm.Release()
|
||||
ENDIF
|
||||
|
||||
llIdVanzareOk = IIF(PCOUNT() >= 9, lnIdVanzare == tnIdVanzareAsteptat, .T.)
|
||||
|
||||
STRTOFILE('--- frm_modific2024, cod=' + TRANSFORM(tnCod) + ' [' + tcEticheta + '] ---' + CHR(13) + CHR(10) + ;
|
||||
' PageCount = ' + TRANSFORM(lnPageCount) + ' (asteptat ' + TRANSFORM(tnPageCountAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' lAreArticoleVanzari = ' + TRANSFORM(llAreArticole) + ' (asteptat ' + TRANSFORM(tlAreArticoleAsteptat) + ')' + CHR(13) + CHR(10) + ;
|
||||
' nIdVanzare = ' + TRANSFORM(lnIdVanzare) + IIF(PCOUNT() >= 9, ' (asteptat ' + TRANSFORM(tnIdVanzareAsteptat) + ')', '') + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(lnPageCount == tnPageCountAsteptat AND llAreArticole == tlAreArticoleAsteptat AND llIdVanzareOk, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
Use In rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
Use In trul
|
||||
ENDIF
|
||||
IF Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
ENDIF
|
||||
IF Used('trul_obinv')
|
||||
Use In trul_obinv
|
||||
ENDIF
|
||||
IF Used('tvanz')
|
||||
Use In tvanz
|
||||
ENDIF
|
||||
IF Used('tvd')
|
||||
Use In tvd
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
* verifica garda ROACONT/ROAGEST: cu ofacturare_editare.prg eliberat din SET PROCEDURE, Show()
|
||||
* trebuie sa degradeze curat la PageCount=2, fara eroare - ultimul test din suita, procedura
|
||||
* ramane eliberata pentru restul rularii (QUIT urmeaza imediat)
|
||||
PROCEDURE verifica_garda_procedura_lipsa
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tcLog
|
||||
|
||||
LOCAL llOk, lnIdSet, lnPageCount, loForm, lcProcList, lnI, lcFile
|
||||
|
||||
llOk = IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, .F.)
|
||||
lnPageCount = -1
|
||||
|
||||
IF llOk AND Used('tact') AND Reccount('tact') > 0
|
||||
Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
|
||||
Go Top In tact
|
||||
lnIdSet = tact.id_set
|
||||
|
||||
IF !Used('crsJtvaTemp')
|
||||
update_jtva_coloane("", "crsJtvaTemp", 6)
|
||||
ENDIF
|
||||
|
||||
*!* simuleaza ROACONT/ROAGEST: reconstruieste lista de proceduri incarcate, fara ofacturare_editare.prg
|
||||
*!* (VFP nu are un "release" pe un singur fisier din SET PROCEDURE - se inchid toate si se redeschid restul)
|
||||
lcProcList = Set('Procedure')
|
||||
SET PROCEDURE TO
|
||||
FOR lnI = 1 TO GETWORDCOUNT(lcProcList, ',')
|
||||
lcFile = ALLTRIM(GETWORDNUM(lcProcList, lnI, ','))
|
||||
IF !EMPTY(lcFile) AND !("OFACTURARE_EDITARE" $ UPPER(lcFile))
|
||||
SET PROCEDURE TO (lcFile) ADDITIVE
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
Select tact
|
||||
loForm = Createobject([frm_modific2024], lnIdSet)
|
||||
loForm.WindowType = 0
|
||||
loForm.Show()
|
||||
|
||||
lnPageCount = loForm.pgfArticole.PageCount
|
||||
|
||||
loForm.Release()
|
||||
ENDIF
|
||||
|
||||
STRTOFILE('--- garda ofacturare_editare.prg lipsa, cod=' + TRANSFORM(tnCod) + ' ---' + CHR(13) + CHR(10) + ;
|
||||
' PageCount = ' + TRANSFORM(lnPageCount) + ' (asteptat 2, ca pe ROACONT/ROAGEST)' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(lnPageCount == 2, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
IF Used('actactan')
|
||||
Use In actactan
|
||||
ENDIF
|
||||
IF Used('tact')
|
||||
Use In tact
|
||||
ENDIF
|
||||
IF Used('rul_temp')
|
||||
Use In rul_temp
|
||||
ENDIF
|
||||
IF Used('trul')
|
||||
Use In trul
|
||||
ENDIF
|
||||
IF Used('rul_temp_obinv')
|
||||
Use In rul_temp_obinv
|
||||
ENDIF
|
||||
IF Used('trul_obinv')
|
||||
Use In trul_obinv
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
|
||||
PROCEDURE test_error_handler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
40
utile/Teste/editare_factura/test_repro_izolat_gnan.prg
Normal file
40
utile/Teste/editare_factura/test_repro_izolat_gnan.prg
Normal file
@@ -0,0 +1,40 @@
|
||||
* test_repro_izolat_gnan.prg
|
||||
* Experimentul B (cerut de team-lead): reproduce izolat, FARA nimic din S4 - fara
|
||||
* IncarcaCursoareModificareNota, fara frm_modific2024, fara PAGE3. Doar init mediu +
|
||||
* update_jtva_coloane singura. Daca dialogul "View Parameter" apare si aici, blocajul nu are
|
||||
* nicio legatura cu modificarea S4 - e o capcana preexistenta a harness-ului/mediului.
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_repro_izolat_gnan_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_repro_izolat_gnan_errhandler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
STRTOFILE(' TYPE(gnAn)=' + TYPE('gnAn') + ' TRANSFORM(gnAn)=' + TRANSFORM(gnAn) + ;
|
||||
' TYPE(gnLuna)=' + TYPE('gnLuna') + ' TRANSFORM(gnLuna)=' + TRANSFORM(gnLuna) + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\updateserver.prg ADDITIVE
|
||||
|
||||
update_jtva_coloane("", "crsJtvaTemp", 6)
|
||||
|
||||
STRTOFILE(' dupa update_jtva_coloane: Used(crsJtvaTemp)=' + TRANSFORM(Used('crsJtvaTemp')) + ;
|
||||
' Reccount=' + IIF(Used('crsJtvaTemp'), TRANSFORM(Reccount('crsJtvaTemp')), '(n/a)') + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE test_repro_izolat_gnan_errhandler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
55
utile/Teste/editare_factura/test_scan_workarea.prg
Normal file
55
utile/Teste/editare_factura/test_scan_workarea.prg
Normal file
@@ -0,0 +1,55 @@
|
||||
* test_scan_workarea.prg
|
||||
* Verificare punctuala: IncarcaVanzareDinNota foloseste SCAN...ENDSCAN pe tmp_triplete_pozvanz, iar
|
||||
* corpul buclei (IncarcaVanzareNota) schimba workarea curenta (creeaza/selecteaza tvanz). SCAN in VFP
|
||||
* poate sa nu tolereze schimbarea workareai curente in interiorul buclei (SKIP/EOF() implicit la
|
||||
* ENDSCAN se aplica pe workarea CURENTA, nu neaparat pe cea de la inceputul SCAN). Testul forteaza
|
||||
* explicit cazul cu 2+ triplete unde primul NU se potriveste, ca sa verifice daca a doua iteratie
|
||||
* chiar se executa (nu doar "a mers din intamplare" pe cod=1137874 unde ordinea DISTINCT ar fi putut
|
||||
* pune din start tripletul corect primul).
|
||||
* Nu atinge Oracle in scriere. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_scan_workarea_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
|
||||
*!* construieste un cursor "tact" sintetic cu 2 triplete, ordonate explicit ca primul (INCASARE,
|
||||
*!* nract=99999 fara corespondent in VANZARI) sa iasa PRIMUL din SELECT DISTINCT (fara ORDER BY,
|
||||
*!* dar inserat primul si numeric mai mic), iar al doilea sa fie tripletul real (cod=1137874,
|
||||
*!* nract=5, serie=FFFFF, data=27.08.2009) care CHIAR exista in VANZARI (id_vanzare=506)
|
||||
CREATE CURSOR tact (cod I, nract I, serie_act C(20), dataact D, sters I)
|
||||
INSERT INTO tact (cod, nract, serie_act, dataact, sters) VALUES (1137874, 1, '', {}, 0)
|
||||
INSERT INTO tact (cod, nract, serie_act, dataact, sters) VALUES (1137874, 5, 'FFFFF', DATE(2009,8,27), 0)
|
||||
|
||||
LOCAL llGasit, lnIdVanzare
|
||||
llGasit = IncarcaVanzareDinNota('tact')
|
||||
lnIdVanzare = IIF(llGasit, tvanz.id_vanzare, -1)
|
||||
|
||||
STRTOFILE('--- SCAN cu workarea schimbata in corp: 2 triplete, primul fara corespondent ---' + CHR(13) + CHR(10) + ;
|
||||
' gasit = ' + TRANSFORM(llGasit) + ' (asteptat .T.)' + CHR(13) + CHR(10) + ;
|
||||
' id_vanzare = ' + TRANSFORM(lnIdVanzare) + ' (asteptat 506)' + CHR(13) + CHR(10) + ;
|
||||
' ' + IIF(llGasit AND lnIdVanzare == 506, 'PASS', 'FAIL') + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
PROCEDURE test_error_handler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
27
utile/Teste/editare_factura/test_set_procedure.prg
Normal file
27
utile/Teste/editare_factura/test_set_procedure.prg
Normal file
@@ -0,0 +1,27 @@
|
||||
* test_set_procedure.prg
|
||||
* Verifica strict formatul intors de SET("PROCEDURE") in VFP9, dupa mai multe
|
||||
* SET PROCEDURE TO ... ADDITIVE succesive, ca sa se stabileasca garda din omodificari.vc2 Show().
|
||||
* Nu atinge Oracle, nu deschide formulare. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_set_procedure_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
STRTOFILE('dupa 1 SET PROCEDURE: [' + SET('PROCEDURE') + ']' + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\oproceduri_facturare.prg ADDITIVE
|
||||
STRTOFILE('dupa 2 SET PROCEDURE (alt fisier ADDITIVE): [' + SET('PROCEDURE') + ']' + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_stoc.prg ADDITIVE
|
||||
STRTOFILE('dupa 3 SET PROCEDURE (al treilea fisier ADDITIVE): [' + SET('PROCEDURE') + ']' + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
LOCAL llGasit
|
||||
llGasit = "OFACTURARE_EDITARE" $ UPPER(SET('PROCEDURE'))
|
||||
STRTOFILE('contine OFACTURARE_EDITARE dupa 3 seturi: ' + TRANSFORM(llGasit) + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
523
utile/Teste/editare_factura/test_writeback_buton1.prg
Normal file
523
utile/Teste/editare_factura/test_writeback_buton1.prg
Normal file
@@ -0,0 +1,523 @@
|
||||
* test_writeback_buton1.prg
|
||||
* Test REAL de write-back pentru ramura buton=1 a lui frm_facturi.do_editare_factura
|
||||
* (COMUN\clase\ofacturare_comun.vc2:3805-3840) - APROBAT explicit de Marius pe 08.08.2026 sa
|
||||
* scrie in schema de dev MARIUSM_AUTO@ROA_CENTRAL (nu doar sa citeasca).
|
||||
*
|
||||
* Document consumat: cod=1140886, id_vanzare=1048 (factura tip 1, 07-AUG-26, total_cu_tva=302.51,
|
||||
* 1 linie in VANZARI_DETALII, 5 randuri in ACT, id_set=25010, id_fact=8009658, 1 rand in RUL).
|
||||
* NU foloseste cod=1140888/1140885 (baze de regresie ale test_incarca_cursoare.prg).
|
||||
*
|
||||
* Harness, nu apel direct al metodei: nu instantiaza frm_facturi si NU mai instantiaza
|
||||
* frm_modific2024 deloc (incercarea initiala s-a blocat la Createobject/Show pe un dialog nativ
|
||||
* Windows "Open" - cursor/tabela lipsa in acest mediu minimal, capcana j din testare-ui-vfp.md -
|
||||
* fara legatura cu calea de scriere care se testeaza aici). In loc, harnessul:
|
||||
* 1) reproduce exact starea de cursoare pe care do_editare_factura o lasa inainte de
|
||||
* Createobject('frm_modific2024',...) (IncarcaCursoareModificareNota, functia reala din
|
||||
* ofacturare_editare.prg);
|
||||
* 2) seteaza buton=1 direct (SARE peste inainte_de_do_termin - vezi ATENTIE mai jos);
|
||||
* 3) ruleaza LITERAL codul ramurii buton=1 (copiat din ofacturare_comun.vc2:3805-3840).
|
||||
* Thisform.do_deschide_tranzactie/do_inchide_tranzactie (mostenite nemodificate din _frm_base,
|
||||
* fara dependinta de vreo clasa de formular anume) sunt reproduse local, INLINE, dupa codul din
|
||||
* _frm_base.vc2:252-302 - ocolesc si instantierea unui _frmbase generic, ca sa nu riste acelasi
|
||||
* fel de blocaj vazut la frm_modific2024.
|
||||
*
|
||||
* ATENTIE - ce NU acopera acest test: validarea din inainte_de_do_termin
|
||||
* (omodificari.vc2:13357-13549 - verificare_note_contabile, echilibru 4426-4428,
|
||||
* VerificaAvertizareExigibilizareTVA) si comportamentul real al formularului la butonul
|
||||
* "Terminat". Testul demonstreaza ca LANTUL DE SCRIERE merge, nu ca utilizatorul ajunge la el
|
||||
* prin UI - cele doua nu trebuie confundate la interpretarea rezultatului.
|
||||
*
|
||||
* Mediu: test_init_env_auto.prg (bootstrap ROACONT, conexiune reala MARIUSM_AUTO) - acelasi mediu
|
||||
* folosit deja cu succes de test_incarca_cursoare.prg si test_page3_articole.prg. oscrie_in_fisiere.prg
|
||||
* e incarcat explicit din COMUN-ul ROAFACTURARE (nu cel auto-rezolvat din calea ROACONT) ca sa
|
||||
* ruleze exact fisierul pe care il ruleaza aplicatia.
|
||||
*
|
||||
* Ruleaza 2 treceri pe acelasi document (cod-ul se schimba dupa fiecare salvare, se recitesc din
|
||||
* VANZARI la fiecare trecere):
|
||||
* TEST 1 - salvare "goala" (fara nicio modificare in tact) - proba ca lantul chiar scrie.
|
||||
* TEST 2 - modifica explicatia unui rand ACT inainte de salvare - proba ca modificarea ajunge.
|
||||
*
|
||||
* Nu atinge .PJX/.PJT/.exe, nu modifica cod aplicatie. QUIT la final.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_writeback_buton1_log.txt'
|
||||
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
PUBLIC gcErrLog
|
||||
gcErrLog = lcLog
|
||||
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
|
||||
*-- mock amessagebox INCARCAT PRIMUL (inaintea lantului din test_init_env_auto, care incarca
|
||||
*-- amessagebox real) - la nume duplicat de procedura, castiga fisierul cautat PRIMUL (testare-ui-vfp.md, capcana g)
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
|
||||
|
||||
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
*-- verificare ca mock-ul chiar umbreste amessebox real (altfel un dialog real ar bloca headless)
|
||||
LOCAL lnVerifMock
|
||||
lnVerifMock = amessagebox('verificare mock', 4+32, 'test')
|
||||
STRTOFILE('verificare mock amessagebox = ' + TRANSFORM(lnVerifMock) + ;
|
||||
IIF(lnVerifMock = 6, ' (OK, mock activ)', ' (ATENTIE: real amessagebox activ, risc de blocaj)') + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\oscrie_in_fisiere.prg ADDITIVE
|
||||
|
||||
IF TYPE('gnPC') <> 'N'
|
||||
PUBLIC gnPC
|
||||
gnPC = 2
|
||||
ENDIF
|
||||
|
||||
*-- capteaza textul ultimului amessagebox mocked (mock_amessagebox.prg, liniile 13-14/23-26) -
|
||||
*-- necesar ca sa vedem CE mesaj de eroare arunca oscrie_in_fisiere.prg pe caile de esec
|
||||
PUBLIC gcMockUltimMesaj, gnMockUltimTip
|
||||
gcMockUltimMesaj = ''
|
||||
gnMockUltimTip = 0
|
||||
|
||||
STRTOFILE('gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + ' gcS=' + gcS + CHR(13) + CHR(10), lcLog, 1)
|
||||
|
||||
DO test_editare_writeback WITH 1048, .F., 'TEST 1: salvare fara nicio modificare', lcLog
|
||||
DO test_editare_writeback WITH 1048, .T., 'TEST 2: modificare explicatie pe un rand ACT', lcLog
|
||||
|
||||
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
|
||||
|
||||
*-- executa SELECT-ul agregat prin goExecutor si intoarce lnSucces; NU citi campurile cursorului
|
||||
*-- decat dupa ce ai verificat lnSucces > 0 (IIF() evalueaza ambele ramuri, ar da eroare pe alias lipsa)
|
||||
PROCEDURE ExecAgg
|
||||
LPARAMETERS tcSql, tcCursor
|
||||
LOCAL lnQ
|
||||
IF USED(tcCursor)
|
||||
USE IN (tcCursor)
|
||||
ENDIF
|
||||
lnQ = goExecutor.oExecute(tcSql, tcCursor)
|
||||
RETURN lnQ
|
||||
ENDPROC
|
||||
|
||||
|
||||
*-- logheaza si RESETEAZA gcMockUltimMesaj/goExecutor.cEroare - reseteaza ca sa nu se confunde
|
||||
*-- mesajul de la un pas cu mesajul (sau lipsa lui) de la pasul urmator
|
||||
PROCEDURE LogMockSiEroare
|
||||
LPARAMETERS tcEticheta, tcLog
|
||||
STRTOFILE(' [' + tcEticheta + '] gcMockUltimMesaj=[' + ALLTRIM(gcMockUltimMesaj) + '] ' + ;
|
||||
'goExecutor.cEroare=[' + ALLTRIM(TRANSFORM(NVL(goExecutor.cEroare, ''))) + ']' + CHR(13) + CHR(10), tcLog, 1)
|
||||
gcMockUltimMesaj = ''
|
||||
ENDPROC
|
||||
|
||||
|
||||
*-- reproduce _frm_base.vc2:252-265 (do_deschide_tranzactie) fara sa instantieze niciun formular
|
||||
PROCEDURE MyDeschideTranzactie
|
||||
LOCAL llReturn, lnSuccesLocal
|
||||
IF TYPE('goExecutor') = 'O'
|
||||
goExecutor.oExecuta([select * from dual])
|
||||
ENDIF
|
||||
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 2)
|
||||
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
|
||||
RETURN llReturn
|
||||
ENDPROC
|
||||
|
||||
|
||||
*-- reproduce _frm_base.vc2:279-302 (do_inchide_tranzactie) fara sa instantieze niciun formular
|
||||
PROCEDURE MyInchideTranzactie
|
||||
LPARAMETERS tnTip
|
||||
LOCAL llReturn, lnSuccesLocal
|
||||
IF tnTip = 1
|
||||
lnSuccesLocal = SQLCOMMIT(gnHandle)
|
||||
ELSE
|
||||
lnSuccesLocal = SQLROLLBACK(gnHandle)
|
||||
ENDIF
|
||||
IF lnSuccesLocal < 0
|
||||
llReturn = .F.
|
||||
ELSE
|
||||
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 1)
|
||||
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
|
||||
ENDIF
|
||||
RETURN llReturn
|
||||
ENDPROC
|
||||
|
||||
|
||||
PROCEDURE test_editare_writeback
|
||||
LPARAMETERS tnIdVanzare, tlModificaLinie, tcEticheta, tcLog
|
||||
|
||||
*-- pnAn/pnLuna/lnCod/lnIdFact PRIVATE (nu LOCAL), identic cu declararea reala
|
||||
*-- (ofacturare_comun.vc2:3742) - finalizeaza_modificare_nota le foloseste ca bind-variabile
|
||||
*-- ?pnLuna/?pnAn in interiorul lui goExecutor.oExecuta, care le cere vizibile PRIVATE pe stiva
|
||||
PRIVATE pnAn, pnLuna, lnCod, lnIdFact
|
||||
LOCAL lnSters, llEProforma
|
||||
LOCAL lnIdSet, lnIdFactD, lnSucces, llGasitRand
|
||||
LOCAL lcSql, lnQ
|
||||
LOCAL lnActBeforeCnt, lnActBeforeSuma, lnRulBeforeCnt, lnRulObinvBeforeCnt
|
||||
LOCAL lnVdCnt, lnVdSumaPret, lnVdSumaPretCuTva
|
||||
LOCAL lcExplicatieVeche, lcExplicatieNoua
|
||||
LOCAL lnVzCodBefore, lnVzStersBefore, lnVzTotalFaraTvaBefore, lnVzTotalTvaBefore, lnVzTotalCuTvaBefore, lnVzDiscountBefore
|
||||
|
||||
STRTOFILE(CHR(13) + CHR(10) + '========== ' + tcEticheta + ' (id_vanzare=' + TRANSFORM(tnIdVanzare) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- 1) starea curenta din VANZARI (cod-ul se poate schimba fata de trecerea anterioara)
|
||||
lcSql = [select cod, sters, id_fact, eproforma, total_fara_tva, total_tva, total_cu_tva, discount, ] + ;
|
||||
[extract(year from data_act) as anact, extract(month from data_act) as lunaact from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||
lnQ = ExecAgg(lcSql, 'v_vanzare_curenta')
|
||||
IF lnQ <= 0 OR RECCOUNT('v_vanzare_curenta') <> 1
|
||||
STRTOFILE('FAIL: VANZARI id_vanzare=' + TRANSFORM(tnIdVanzare) + ' - lnQ=' + TRANSFORM(lnQ) + ;
|
||||
' reccount=' + IIF(lnQ > 0, TRANSFORM(RECCOUNT('v_vanzare_curenta')), '?') + ;
|
||||
' cEroare=[' + ALLTRIM(TRANSFORM(NVL(goExecutor.cEroare, ''))) + ']' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
SELECT v_vanzare_curenta
|
||||
lnCod = cod
|
||||
lnSters = sters
|
||||
lnIdFact = id_fact
|
||||
llEProforma = (eproforma = 1)
|
||||
pnAn = anact
|
||||
pnLuna = lunaact
|
||||
lnVzCodBefore = cod
|
||||
lnVzStersBefore = sters
|
||||
lnVzTotalFaraTvaBefore = total_fara_tva
|
||||
lnVzTotalTvaBefore = total_tva
|
||||
lnVzTotalCuTvaBefore = total_cu_tva
|
||||
lnVzDiscountBefore = discount
|
||||
USE IN v_vanzare_curenta
|
||||
|
||||
STRTOFILE(' VANZARI inainte: cod=' + TRANSFORM(lnCod) + ' sters=' + TRANSFORM(lnSters) + ' id_fact=' + TRANSFORM(lnIdFact) + ;
|
||||
' an/luna=' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ' total_cu_tva=' + TRANSFORM(lnVzTotalCuTvaBefore) + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- 2) garzi (replica do_editare_factura, fara UI)
|
||||
IF lnSters = 1
|
||||
STRTOFILE(' SKIP: document deja sters' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
IF llEProforma
|
||||
STRTOFILE(' SKIP: proforma' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
IF (pnAn*12) + pnLuna <> (gnAn*12) + gnLuna
|
||||
STRTOFILE(' SKIP: nu e luna curenta (document ' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ', curenta ' + TRANSFORM(gnAn) + '/' + TRANSFORM(gnLuna) + ')' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
IF EsteInEFactura(lnIdFact)
|
||||
STRTOFILE(' SKIP: trimis in eFactura' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
*-- 3) instantaneu INAINTE: ACT / RUL / RUL_OBINV (pe cod-ul curent) + VANZARI_DETALII
|
||||
lcSql = [select count(*) as cnt, sum(suma) as totsuma from vact_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCod)
|
||||
lnQ = ExecAgg(lcSql, 'v_act_before')
|
||||
IF lnQ > 0
|
||||
lnActBeforeCnt = v_act_before.cnt
|
||||
lnActBeforeSuma = NVL(v_act_before.totsuma, 0)
|
||||
USE IN v_act_before
|
||||
ELSE
|
||||
lnActBeforeCnt = -1
|
||||
lnActBeforeSuma = -1
|
||||
ENDIF
|
||||
|
||||
lcSql = [select count(*) as cnt from vrul_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCod)
|
||||
lnQ = ExecAgg(lcSql, 'v_rul_before')
|
||||
IF lnQ > 0
|
||||
lnRulBeforeCnt = v_rul_before.cnt
|
||||
USE IN v_rul_before
|
||||
ELSE
|
||||
lnRulBeforeCnt = -1
|
||||
ENDIF
|
||||
|
||||
lcSql = [select count(*) as cnt from vrul_obinv_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCod)
|
||||
lnQ = ExecAgg(lcSql, 'v_rulobinv_before')
|
||||
IF lnQ > 0
|
||||
lnRulObinvBeforeCnt = v_rulobinv_before.cnt
|
||||
USE IN v_rulobinv_before
|
||||
ELSE
|
||||
lnRulObinvBeforeCnt = -1
|
||||
ENDIF
|
||||
|
||||
lcSql = [select count(*) as cnt, sum(cantitate) as sumcant, sum(pret) as sumpret, sum(pret_cu_tva) as sumpretcutva ] + ;
|
||||
[from vanzari_detalii where sters = 0 and id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||
lnQ = ExecAgg(lcSql, 'v_vd_before')
|
||||
IF lnQ > 0
|
||||
lnVdCnt = v_vd_before.cnt
|
||||
lnVdSumaPret = NVL(v_vd_before.sumpret, 0)
|
||||
lnVdSumaPretCuTva = NVL(v_vd_before.sumpretcutva, 0)
|
||||
USE IN v_vd_before
|
||||
ELSE
|
||||
lnVdCnt = -1
|
||||
lnVdSumaPret = -1
|
||||
lnVdSumaPretCuTva = -1
|
||||
ENDIF
|
||||
|
||||
STRTOFILE(' INAINTE: ACT cnt=' + TRANSFORM(lnActBeforeCnt) + ' suma=' + TRANSFORM(lnActBeforeSuma) + ;
|
||||
' RUL cnt=' + TRANSFORM(lnRulBeforeCnt) + ' RUL_OBINV cnt=' + TRANSFORM(lnRulObinvBeforeCnt) + ;
|
||||
' VANZARI_DETALII cnt=' + TRANSFORM(lnVdCnt) + ' sum(pret)=' + TRANSFORM(lnVdSumaPret) + ' sum(pret_cu_tva)=' + TRANSFORM(lnVdSumaPretCuTva) + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- 4) IncarcaCursoareModificareNota (functia reala, ofacturare_editare.prg)
|
||||
IF !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.)
|
||||
STRTOFILE(' FAIL: IncarcaCursoareModificareNota a esuat (eroare Oracle)' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
IF RECCOUNT('actactan') = 0
|
||||
STRTOFILE(' FAIL: nu exista nota contabila (Reccount(actactan)=0)' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
*-- 5) pozitionare id_fact/id_set/id_factd - copiat identic din do_editare_factura
|
||||
*-- (ofacturare_comun.vc2:3785-3797; garda id_set scoasa - decizia 24, cod curent nu o mai are)
|
||||
SELECT actactan
|
||||
llGasitRand = .F.
|
||||
IF lnIdFact > 0
|
||||
LOCATE FOR NVL(id_fact, 0) = lnIdFact
|
||||
llGasitRand = FOUND()
|
||||
ENDIF
|
||||
IF !llGasitRand
|
||||
GO TOP
|
||||
lnIdFact = id_fact
|
||||
ENDIF
|
||||
lnIdSet = id_set
|
||||
lnIdFactD = NVL(id_factd, 0)
|
||||
|
||||
STRTOFILE(' pozitionare actactan: gasit=' + TRANSFORM(llGasitRand) + ' id_fact=' + TRANSFORM(lnIdFact) + ;
|
||||
' id_set=' + TRANSFORM(lnIdSet) + ' id_factd=' + TRANSFORM(lnIdFactD) + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
SELECT a.*, IIF(NVL(id_jtva_coloana, 0) = 0, 0, 1) AS cu_Tva FROM tact a INTO CURSOR tact READWRITE
|
||||
|
||||
*-- 6) TEST 2: modifica un camp simplu si verificabil (explicatia) INAINTE de salvare
|
||||
lcExplicatieVeche = ''
|
||||
lcExplicatieNoua = ''
|
||||
IF tlModificaLinie
|
||||
SELECT tact
|
||||
LOCATE FOR !EMPTY(ALLTRIM(NVL(explicatia, '')))
|
||||
IF FOUND()
|
||||
lcExplicatieVeche = ALLTRIM(explicatia)
|
||||
lcExplicatieNoua = lcExplicatieVeche + ' (test writeback)'
|
||||
REPLACE explicatia WITH lcExplicatieNoua
|
||||
STRTOFILE(' modific tact.explicatia: [' + lcExplicatieVeche + '] -> [' + lcExplicatieNoua + ']' + CHR(13) + CHR(10), tcLog, 1)
|
||||
ELSE
|
||||
STRTOFILE(' ATENTIE: nu am gasit niciun rand cu explicatia completata, testul nu modifica nimic real' + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
*-- 7) frm_modific2024 OCOLIT COMPLET (a blocat Createobject/Show pe dialog nativ "Open" -
|
||||
*-- vezi antetul fisierului). buton=1 fortat direct - inainte_de_do_termin NU se executa.
|
||||
buton = 1
|
||||
STRTOFILE(' frm_modific2024 ocolit: buton=1 fortat direct, inainte_de_do_termin SARIT' + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- 8) ramura buton=1 din do_editare_factura (ofacturare_comun.vc2:3805-3840), copiata identic;
|
||||
*-- Thisform.do_deschide_tranzactie/do_inchide_tranzactie sunt reproduse INLINE mai jos
|
||||
*-- (MyDeschideTranzactie/MyInchideTranzactie, dupa _frm_base.vc2:252-302) - fara sa instantieze
|
||||
*-- niciun formular, ca sa nu riste acelasi blocaj vazut la frm_modific2024
|
||||
lnSucces = 0
|
||||
TRY
|
||||
STRTOFILE(' [chk] inainte de MyDeschideTranzactie()' + CHR(13) + CHR(10), tcLog, 1)
|
||||
IF MyDeschideTranzactie()
|
||||
STRTOFILE(' [chk] MyDeschideTranzactie() => .T., inainte de OSCRIE_IN_FISIERE(2,...)' + CHR(13) + CHR(10), tcLog, 1)
|
||||
SELECT actactan
|
||||
lnSucces = OSCRIE_IN_FISIERE(2, .T., .T.)
|
||||
STRTOFILE(' [chk] OSCRIE_IN_FISIERE(2,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||
LogMockSiEroare('dupa OSCRIE_IN_FISIERE(2,...)', tcLog)
|
||||
IF lnSucces > 0
|
||||
IF USED('actactan')
|
||||
USE IN actactan
|
||||
ENDIF
|
||||
SELECT tact
|
||||
REPLACE id_jtva_coloana WITH NULL, proc_tva WITH 0 FOR cu_Tva = 0
|
||||
SELECT * FROM tact INTO CURSOR actactan READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
|
||||
IF USED('rul_temp')
|
||||
USE IN rul_temp
|
||||
ENDIF
|
||||
SELECT * FROM trul INTO CURSOR RUL_TEMP READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
|
||||
IF USED('rul_temp_obinv')
|
||||
USE IN rul_temp_obinv
|
||||
ENDIF
|
||||
SELECT * FROM trul_obinv INTO CURSOR RUL_TEMP_OBINV READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
|
||||
STRTOFILE(' [chk] cursoare rebuild OK, inainte de OSCRIE_IN_FISIERE(0,...)' + CHR(13) + CHR(10), tcLog, 1)
|
||||
lnSucces = OSCRIE_IN_FISIERE(0, .T., .T.)
|
||||
STRTOFILE(' [chk] OSCRIE_IN_FISIERE(0,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||
LogMockSiEroare('dupa OSCRIE_IN_FISIERE(0,...)', tcLog)
|
||||
ENDIF
|
||||
IF lnSucces > 0
|
||||
STRTOFILE(' [chk] inainte de pack_contafin.finalizeaza_modificare_nota' + CHR(13) + CHR(10), tcLog, 1)
|
||||
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,Null,] + ALLTRIM(STR(lnIdSet)) + [,] + ;
|
||||
ALLTRIM(STR(lnCod)) + [,] + ALLTRIM(STR(lnIdFact)) + [,] + ALLTRIM(STR(lnIdFactD)) + [,?gnIdUtil); end;]
|
||||
STRTOFILE(' [chk] SQL finalizeaza_modificare_nota = [' + lcSql + ']' + CHR(13) + CHR(10), tcLog, 1)
|
||||
lnSucces = IIF(goExecutor.oExecuta(lcSql), 1, -1)
|
||||
STRTOFILE(' [chk] finalizeaza_modificare_nota => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||
LogMockSiEroare('dupa finalizeaza_modificare_nota', tcLog)
|
||||
ENDIF
|
||||
STRTOFILE(' lnSucces dupa lant scriere = ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||
STRTOFILE(' [chk] inainte de MyInchideTranzactie' + CHR(13) + CHR(10), tcLog, 1)
|
||||
IF MyInchideTranzactie(IIF(lnSucces < 0, 2, 1))
|
||||
STRTOFILE(' tranzactie inchisa cu ' + IIF(lnSucces < 0, 'ROLLBACK', 'COMMIT') + CHR(13) + CHR(10), tcLog, 1)
|
||||
ELSE
|
||||
STRTOFILE(' FAIL la do_inchide_tranzactie' + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDIF
|
||||
ELSE
|
||||
STRTOFILE(' FAIL: do_deschide_tranzactie a esuat' + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDIF
|
||||
CATCH TO loExc
|
||||
STRTOFILE(' EXCEPTIE in lantul de scriere: ' + TRANSFORM(loExc.ErrorNo) + ' [' + loExc.Message + '] ' + ;
|
||||
loExc.Procedure + ':' + TRANSFORM(loExc.LineNo) + ' -> ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
|
||||
lnSucces = -99
|
||||
MyInchideTranzactie(2)
|
||||
ENDTRY
|
||||
|
||||
IF USED('actactan')
|
||||
USE IN actactan
|
||||
ENDIF
|
||||
IF USED('tact')
|
||||
USE IN tact
|
||||
ENDIF
|
||||
IF USED('rul_temp')
|
||||
USE IN rul_temp
|
||||
ENDIF
|
||||
IF USED('trul')
|
||||
USE IN trul
|
||||
ENDIF
|
||||
IF USED('rul_temp_obinv')
|
||||
USE IN rul_temp_obinv
|
||||
ENDIF
|
||||
IF USED('trul_obinv')
|
||||
USE IN trul_obinv
|
||||
ENDIF
|
||||
|
||||
IF lnSucces <= 0
|
||||
STRTOFILE(' TEST FAIL - scrierea nu s-a produs (lnSucces=' + TRANSFORM(lnSucces) + '), fara verificari after' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
*-- 9) instantaneu DUPA + verificarile 1-5 cerute
|
||||
LOCAL lnCodNou, lnVzStersAfter, llV3ok
|
||||
lcSql = [select cod, sters, id_fact, total_fara_tva, total_tva, total_cu_tva, discount from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||
lnQ = ExecAgg(lcSql, 'v_vanzare_dupa')
|
||||
IF lnQ <= 0 OR RECCOUNT('v_vanzare_dupa') <> 1
|
||||
STRTOFILE(' FAIL: VANZARI dupa - nu am gasit exact 1 rand' + CHR(13) + CHR(10), tcLog, 1)
|
||||
RETURN
|
||||
ENDIF
|
||||
SELECT v_vanzare_dupa
|
||||
lnCodNou = cod
|
||||
lnVzStersAfter = sters
|
||||
llV3ok = (lnCodNou <> lnVzCodBefore) AND (lnVzStersAfter = 0) AND (id_fact == lnIdFact) AND ;
|
||||
(ABS(total_fara_tva - lnVzTotalFaraTvaBefore) < 0.01) AND (ABS(total_tva - lnVzTotalTvaBefore) < 0.01) AND ;
|
||||
(ABS(total_cu_tva - lnVzTotalCuTvaBefore) < 0.01) AND (ABS(discount - lnVzDiscountBefore) < 0.01)
|
||||
STRTOFILE(' [3] VANZARI dupa: cod=' + TRANSFORM(lnCodNou) + ' (era ' + TRANSFORM(lnVzCodBefore) + ') sters=' + TRANSFORM(lnVzStersAfter) + ;
|
||||
' id_fact=' + TRANSFORM(id_fact) + ' total_cu_tva=' + TRANSFORM(total_cu_tva) + ' -> ' + IIF(llV3ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
USE IN v_vanzare_dupa
|
||||
|
||||
*-- [1] ACT: randurile vechi STERS=1 pe cod vechi; randuri noi pe cod nou, acelasi id_fact, aceeasi suma (daca nemodificat)
|
||||
LOCAL lnActVechiCnt, lnActVechiSumSters, lnActNouCnt, lnActNouSuma, llV1ok
|
||||
|
||||
lcSql = [select count(*) as cnt, sum(sters) as sumsters from vact_tot where an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnVzCodBefore)
|
||||
lnQ = ExecAgg(lcSql, 'v_act_vechi_dupa')
|
||||
IF lnQ > 0
|
||||
lnActVechiCnt = v_act_vechi_dupa.cnt
|
||||
lnActVechiSumSters = NVL(v_act_vechi_dupa.sumsters, 0)
|
||||
USE IN v_act_vechi_dupa
|
||||
ELSE
|
||||
lnActVechiCnt = -1
|
||||
lnActVechiSumSters = -1
|
||||
ENDIF
|
||||
|
||||
lcSql = [select count(*) as cnt, sum(suma) as totsuma from vact_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCodNou)
|
||||
lnQ = ExecAgg(lcSql, 'v_act_nou_dupa')
|
||||
IF lnQ > 0
|
||||
lnActNouCnt = v_act_nou_dupa.cnt
|
||||
lnActNouSuma = NVL(v_act_nou_dupa.totsuma, 0)
|
||||
USE IN v_act_nou_dupa
|
||||
ELSE
|
||||
lnActNouCnt = -1
|
||||
lnActNouSuma = -1
|
||||
ENDIF
|
||||
|
||||
llV1ok = (lnActVechiCnt = lnActBeforeCnt) AND (lnActVechiSumSters = lnActVechiCnt) AND (lnActNouCnt = lnActBeforeCnt) AND ;
|
||||
(IIF(tlModificaLinie, .T., ABS(lnActNouSuma - lnActBeforeSuma) < 0.01))
|
||||
STRTOFILE(' [1] ACT: vechi(cod=' + TRANSFORM(lnVzCodBefore) + ') cnt=' + TRANSFORM(lnActVechiCnt) + ' toate sters=' + TRANSFORM(lnActVechiSumSters = lnActVechiCnt) + ;
|
||||
'; nou(cod=' + TRANSFORM(lnCodNou) + ') cnt=' + TRANSFORM(lnActNouCnt) + ' suma=' + TRANSFORM(lnActNouSuma) + ;
|
||||
' (era ' + TRANSFORM(lnActBeforeSuma) + ') -> ' + IIF(llV1ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- [2] RUL: acelasi tipar (daca documentul are randuri RUL)
|
||||
LOCAL lnRulVechiCnt, lnRulVechiSumSters, lnRulNouCnt, llV2ok
|
||||
|
||||
lcSql = [select count(*) as cnt, sum(sters) as sumsters from vrul_tot where an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnVzCodBefore)
|
||||
lnQ = ExecAgg(lcSql, 'v_rul_vechi_dupa')
|
||||
IF lnQ > 0
|
||||
lnRulVechiCnt = v_rul_vechi_dupa.cnt
|
||||
lnRulVechiSumSters = NVL(v_rul_vechi_dupa.sumsters, 0)
|
||||
USE IN v_rul_vechi_dupa
|
||||
ELSE
|
||||
lnRulVechiCnt = -1
|
||||
lnRulVechiSumSters = -1
|
||||
ENDIF
|
||||
|
||||
lcSql = [select count(*) as cnt from vrul_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCodNou)
|
||||
lnQ = ExecAgg(lcSql, 'v_rul_nou_dupa')
|
||||
IF lnQ > 0
|
||||
lnRulNouCnt = v_rul_nou_dupa.cnt
|
||||
USE IN v_rul_nou_dupa
|
||||
ELSE
|
||||
lnRulNouCnt = -1
|
||||
ENDIF
|
||||
|
||||
llV2ok = (lnRulVechiCnt = lnRulBeforeCnt) AND (lnRulVechiSumSters = lnRulVechiCnt) AND (lnRulNouCnt = lnRulBeforeCnt)
|
||||
STRTOFILE(' [2] RUL: vechi cnt=' + TRANSFORM(lnRulVechiCnt) + ' toate sters=' + TRANSFORM(lnRulVechiSumSters = lnRulVechiCnt) + ;
|
||||
'; nou cnt=' + TRANSFORM(lnRulNouCnt) + ' (era ' + TRANSFORM(lnRulBeforeCnt) + ') -> ' + IIF(llV2ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- [4] VANZARI_DETALII: neatins de aceasta cale
|
||||
LOCAL lnVdCntDupa, lnVdSumaPretDupa, lnVdSumaPretCuTvaDupa, llV4ok
|
||||
lcSql = [select count(*) as cnt, sum(cantitate) as sumcant, sum(pret) as sumpret, sum(pret_cu_tva) as sumpretcutva ] + ;
|
||||
[from vanzari_detalii where sters = 0 and id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||
lnQ = ExecAgg(lcSql, 'v_vd_dupa')
|
||||
IF lnQ > 0
|
||||
lnVdCntDupa = v_vd_dupa.cnt
|
||||
lnVdSumaPretDupa = NVL(v_vd_dupa.sumpret, 0)
|
||||
lnVdSumaPretCuTvaDupa = NVL(v_vd_dupa.sumpretcutva, 0)
|
||||
USE IN v_vd_dupa
|
||||
ELSE
|
||||
lnVdCntDupa = -1
|
||||
lnVdSumaPretDupa = -1
|
||||
lnVdSumaPretCuTvaDupa = -1
|
||||
ENDIF
|
||||
|
||||
llV4ok = (lnVdCntDupa = lnVdCnt) AND (ABS(lnVdSumaPretDupa - lnVdSumaPret) < 0.01) AND (ABS(lnVdSumaPretCuTvaDupa - lnVdSumaPretCuTva) < 0.01)
|
||||
STRTOFILE(' [4] VANZARI_DETALII: cnt=' + TRANSFORM(lnVdCntDupa) + ' (era ' + TRANSFORM(lnVdCnt) + ') sum(pret)=' + TRANSFORM(lnVdSumaPretDupa) + ;
|
||||
' (era ' + TRANSFORM(lnVdSumaPret) + ') -> ' + IIF(llV4ok, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- [5] lnSucces>0 pe tot lantul + tranzactia inchisa cu commit (deja logat mai sus, sintetizat aici)
|
||||
STRTOFILE(' [5] lnSucces final = ' + TRANSFORM(lnSucces) + ' -> ' + IIF(lnSucces > 0, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
|
||||
*-- verificare suplimentara TEST 2: explicatia modificata ajunge efectiv in ACT pe randul nou
|
||||
IF tlModificaLinie AND !EMPTY(lcExplicatieNoua)
|
||||
LOCAL lnExplicatieCnt
|
||||
lcSql = [select count(*) as cnt from vact_tot where sters = 0 and an = ] + TRANSFORM(pnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(pnLuna) + [ and cod = ] + TRANSFORM(lnCodNou) + ;
|
||||
[ and explicatia = '] + STRTRAN(lcExplicatieNoua, "'", "''") + [']
|
||||
lnQ = ExecAgg(lcSql, 'v_act_explicatie')
|
||||
IF lnQ > 0
|
||||
lnExplicatieCnt = v_act_explicatie.cnt
|
||||
USE IN v_act_explicatie
|
||||
ELSE
|
||||
lnExplicatieCnt = -1
|
||||
ENDIF
|
||||
STRTOFILE(' [2b] explicatia modificata ajunge in ACT: cnt=' + TRANSFORM(lnExplicatieCnt) + ' -> ' + IIF(lnExplicatieCnt = 1, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDIF
|
||||
|
||||
STRTOFILE(' REZUMAT ' + tcEticheta + ': cod ' + TRANSFORM(lnVzCodBefore) + ' -> ' + TRANSFORM(lnCodNou) + CHR(13) + CHR(10), tcLog, 1)
|
||||
ENDPROC
|
||||
|
||||
|
||||
PROCEDURE test_error_handler
|
||||
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
|
||||
ENDPROC
|
||||
663
utile/Teste/facturare_pret_cu_tva/test_pret_cu_tva_dialog.prg
Normal file
663
utile/Teste/facturare_pret_cu_tva/test_pret_cu_tva_dialog.prg
Normal file
@@ -0,0 +1,663 @@
|
||||
* test_pret_cu_tva_dialog.prg
|
||||
* Test UI Nivel 1 (S5, plan #7) pentru dialogul PER-ARTICOL real, clasa frm_articol_factura din
|
||||
* COMUN\clase\ofacturare.vc2. Instantiaza clasa exact cum o instantiaza aplicatia in
|
||||
* frm_facturare_articole.do_adauga_articol (ofacturare.vc2:12869):
|
||||
* Createobject("frm_articol_factura", lnCantitate, tlImplicit)
|
||||
* apoi exerseaza handlerele REALE (ck_pret_cu_tva.InteractiveChange, Clb_pretctva.tx_suma_nat.
|
||||
* InteractiveChange, Clb_discountctva.tx_suma_nat.Valid) - nu populeaza direct poArticol cu
|
||||
* rezultate calculate manual, doar cu DATELE DE INTRARE (pretul tastat, bifa), exact ce ar
|
||||
* introduce utilizatorul. poArticol se construieste ca obiect liber (CREATEOBJECT+ADDPROPERTY),
|
||||
* echivalent cu Scatter Name poArticol MEMO din crsarticole (acelasi shape de date), pentru ca
|
||||
* testul sa ramana independent de Oracle si de celelalte doua griduri ale formularului parinte.
|
||||
*
|
||||
* Nivel 2 (flux complet prin frm_facturare_articole, propagare in crsfactura, buton
|
||||
* but_modificare din S2b) NU e acoperit aici - vezi docs\cercetare\rec_s5_teste.md pentru motiv.
|
||||
*
|
||||
* Pasi (vezi vfp_ui_harness.ps1 -Steps):
|
||||
* 0 mediu pregatit
|
||||
* 1 cazul tinta: bifa=1, pret tastat 100.00 cu TVA, cantitate 1 -> total exact 100.00
|
||||
* 2 comutare bifa OFF->ON: pretul fara TVA tastat nu se pierde
|
||||
* 3 comutare bifa ON->OFF: pretul cu TVA tastat nu se pierde
|
||||
* 4 cota standard 21%
|
||||
* 5 cota redusa 11%
|
||||
* 6 discount unitar cu TVA (ramura discountctva)
|
||||
* 7 bifa activa pe tip de document din lista (Inlist 1,5,10,22,23,25,29,41)
|
||||
* 8 bifa dezactivata pe tip din afara listei, cu pret nenul
|
||||
* 9 final
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
SET DELETED ON
|
||||
SET EXACT ON
|
||||
SET CENTURY ON
|
||||
SET DATE DMY
|
||||
SET DECIMALS TO 4
|
||||
SET NULLDISPLAY TO ''
|
||||
CLOSE DATABASES
|
||||
|
||||
PUBLIC gcUILog, gcSyncDir
|
||||
gcUILog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\test_pret_cu_tva_dialog_log.txt"
|
||||
gcSyncDir = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\uisync\"
|
||||
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
|
||||
|
||||
ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
ON SHUTDOWN QUIT
|
||||
|
||||
TRY
|
||||
LOCAL gcAppPath, lcPath
|
||||
gcAppPath = "D:\ROA\ROAFACTURARE\"
|
||||
SET DEFAULT TO (gcAppPath)
|
||||
|
||||
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
|
||||
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
|
||||
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
|
||||
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
|
||||
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\CALENDAR;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EMAIL;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\NFJSON;' + gcAppPath + 'COMUN\UTILE\NFXML;' + ;
|
||||
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
|
||||
SET PATH TO &lcPath ADDITIVE
|
||||
DO AfLog WITH 'SET PATH OK'
|
||||
|
||||
*----- CLASE (lista din Programe\roafacturare.prg, scopul minim pentru ofacturare.vcx) -----
|
||||
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
|
||||
SET CLASSLIB TO registry ADDITIVE
|
||||
SET CLASSLIB TO cauta_alfa_forms ADDITIVE
|
||||
SET CLASSLIB TO ofacturare.vcx ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_comun.vcx ADDITIVE
|
||||
SET CLASSLIB TO accessibility.vcx ADDITIVE
|
||||
SET CLASSLIB TO ocriterii.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_statusbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO DECABAZA ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare2 ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_rapoarte ADDITIVE
|
||||
SET CLASSLIB TO orapoarte ADDITIVE
|
||||
SET CLASSLIB TO ferestre_oracle ADDITIVE
|
||||
SET CLASSLIB TO messagebox ADDITIVE
|
||||
SET CLASSLIB TO otoolbar ADDITIVE
|
||||
SET CLASSLIB TO onom_curs ADDITIVE
|
||||
SET CLASSLIB TO comun ADDITIVE
|
||||
SET CLASSLIB TO ferestre_cere_date ADDITIVE
|
||||
SET CLASSLIB TO baza ADDITIVE
|
||||
SET CLASSLIB TO caut ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri ADDITIVE
|
||||
SET CLASSLIB TO serii_numere ADDITIVE
|
||||
SET CLASSLIB TO caut_ora ADDITIVE
|
||||
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
|
||||
SET CLASSLIB TO _calendar.vcx ADDITIVE
|
||||
SET CLASSLIB TO locale ADDITIVE
|
||||
SET CLASSLIB TO overificari ADDITIVE
|
||||
SET CLASSLIB TO ocomenzi ADDITIVE
|
||||
DO AfLog WITH 'SET CLASSLIB OK'
|
||||
|
||||
*----- PROCEDURI (mock amessagebox PRIMUL, ui_harness la final) -----
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg"
|
||||
SET PROCEDURE TO proceduri_comune ADDITIVE
|
||||
SET PROCEDURE TO quitapp ADDITIVE
|
||||
SET PROCEDURE TO init_program ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare.prg ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare2.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_rapoarte_fact.prg ADDITIVE
|
||||
SET PROCEDURE TO email.prg ADDITIVE
|
||||
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
|
||||
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
|
||||
SET PROCEDURE TO updateserver.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
|
||||
SET PROCEDURE TO ocautare ADDITIVE
|
||||
SET PROCEDURE TO odocumente ADDITIVE
|
||||
SET PROCEDURE TO osecurity ADDITIVE
|
||||
SET PROCEDURE TO acces_meniu ADDITIVE
|
||||
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO ini.prg ADDITIVE
|
||||
SET PROCEDURE TO cauta_alfa.prg ADDITIVE
|
||||
SET PROCEDURE TO oHeader.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_curs.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare.prg ADDITIVE
|
||||
SET PROCEDURE TO oserii_numere.prg ADDITIVE
|
||||
SET PROCEDURE TO wwutils.prg ADDITIVE
|
||||
SET PROCEDURE TO wwConfig.prg ADDITIVE
|
||||
SET PROCEDURE TO wwApi.prg ADDITIVE
|
||||
SET PROCEDURE TO oexport.prg ADDITIVE
|
||||
SET PROCEDURE TO validare.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_comun.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_stoc.prg ADDITIVE
|
||||
SET PROCEDURE TO pmenu.prg ADDITIVE
|
||||
SET PROCEDURE TO ointroduceri.prg ADDITIVE
|
||||
SET PROCEDURE TO ovariabile_globale.prg ADDITIVE
|
||||
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
|
||||
SET PROCEDURE TO filebringer.prg ADDITIVE
|
||||
SET PROCEDURE TO iniacces.prg ADDITIVE
|
||||
SET PROCEDURE TO oupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO procese.prg ADDITIVE
|
||||
SET PROCEDURE TO version.prg ADDITIVE
|
||||
SET PROCEDURE TO wwhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlaccess.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlparser.prg ADDITIVE
|
||||
SET PROCEDURE TO xdate.prg ADDITIVE
|
||||
SET PROCEDURE TO suma_in_vorbe.prg ADDITIVE
|
||||
SET PROCEDURE TO controllerecr ADDITIVE
|
||||
SET PROCEDURE TO regex.prg ADDITIVE
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
|
||||
DO AfLog WITH 'SET PROCEDURE OK'
|
||||
|
||||
*----- Globale aplicatie cerute de frm_articol_factura / calculeaza_totaluri -----
|
||||
PUBLIC gnPc, gnPVal, gnPcant, gnPPretV, gnScadereStoc, gnMemProcDisc, gl406, gcAcces
|
||||
gnPc = 2 && precizie sume lei
|
||||
gnPVal = 2 && precizie sume valuta
|
||||
gnPcant = 3 && precizie cantitate (doar pt. InputMask)
|
||||
gnPPretV = 4 && precizie unitara pret/tva/discount
|
||||
gnScadereStoc = 0 && ocoleste ramura serie/lot needitabila si clb_procent_adaos
|
||||
gnMemProcDisc = 0 && ocoleste memorarea procentului de discount intre articole
|
||||
gl406 = .F. && SAFT dezactivat - flagul pret_cu_tva nu are legatura cu taxcode
|
||||
gcAcces = "1;2;3;4;5;6;7;8;"
|
||||
PUBLIC nror(65000)
|
||||
|
||||
PUBLIC goApp
|
||||
goApp = CREATEOBJECT('dummyapp')
|
||||
|
||||
*----- jtva_coloane: cotele curente (regim post 01.08.2025) - 21% standard, 11% redusa -----
|
||||
IF USED('jtva_coloane')
|
||||
USE IN ('jtva_coloane')
|
||||
ENDIF
|
||||
CREATE CURSOR jtva_coloane (id_jtva_coloana N(14), denumire C(50), cota_tva N(6,2))
|
||||
INSERT INTO jtva_coloane VALUES (1, 'TVA 21%', 21)
|
||||
INSERT INTO jtva_coloane VALUES (2, 'TVA 11%', 11)
|
||||
GO TOP IN jtva_coloane
|
||||
|
||||
*----- saft_taxtable: desi gl406=.F. (codul aplicatiei nu-l cere explicit), cb_explicatie_saft
|
||||
* din frm_articol_factura are RowSource="select ... from saft_taxtable ..." legat direct
|
||||
* pe control (RowSourceType=3) - fara cursorul cu acest alias, SELECT-ul cauta un fisier
|
||||
* saft_taxtable.dbf inexistent si scoate dialogul nativ Windows "Open" care blocheaza
|
||||
* headless la nesfarsit, fara nicio linie noua in log (capcana j, testare-ui-vfp.md). -----
|
||||
IF USED('saft_taxtable')
|
||||
USE IN ('saft_taxtable')
|
||||
ENDIF
|
||||
CREATE CURSOR saft_taxtable (taxname C(250), procent_taxa N(7,2), taxcode N(6), tva_livrari N(1))
|
||||
INSERT INTO saft_taxtable VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%', 21, 301104, 1)
|
||||
INSERT INTO saft_taxtable VALUES ('3011XX-Achizitii de bunuri si servicii taxabile cu cota de 11%', 11, 301108, 1)
|
||||
|
||||
*----- tablourile cu campurile poArticol: constructie poArticol INLINE in main la fiecare
|
||||
* scenariu (nu intr-o PROCEDURA - vezi capcana ADDPROPERTY apelat dintr-o procedura,
|
||||
* testare-ui-vfp.md litera l), dar bucla de ADDPROPERTY ramane in corpul principal, deci
|
||||
* e sigura; reduce field-urile "neutre" (0 / '') la doua tablouri reutilizate. -----
|
||||
LOCAL lnI
|
||||
LOCAL ARRAY laPropN(49)
|
||||
laPropN( 1)='id_articol' && identificatori si asociatii
|
||||
laPropN( 2)='Id_Pol'
|
||||
laPropN( 3)='id_gestiune'
|
||||
laPropN( 4)='id_c'
|
||||
laPropN( 5)='id_ctr'
|
||||
laPropN( 6)='id_valuta'
|
||||
laPropN( 7)='id_valuta_d'
|
||||
laPropN( 8)='id_lucrare_rez'
|
||||
laPropN( 9)='id_part_rez'
|
||||
laPropN(10)='id_jtva_coloana'
|
||||
laPropN(11)='taxcode'
|
||||
laPropN(12)='opt_facturare'
|
||||
laPropN(13)='gestionabil' && cantitate / pret / valuta
|
||||
laPropN(14)='tip_valuta'
|
||||
laPropN(15)='cantitate'
|
||||
laPropN(16)='Curs'
|
||||
laPropN(17)='multiplicator'
|
||||
laPropN(18)='pret_achizitie'
|
||||
laPropN(19)='pretv_orig'
|
||||
laPropN(20)='pretd'
|
||||
laPropN(21)='proc_tvav'
|
||||
laPropN(22)='preturi_cu_tva' && preturi
|
||||
laPropN(23)='pretftva'
|
||||
laPropN(24)='pretftva_val'
|
||||
laPropN(25)='pretctva'
|
||||
laPropN(26)='pretctva_val'
|
||||
laPropN(27)='tva'
|
||||
laPropN(28)='tva_val'
|
||||
laPropN(29)='discount_unitar' && discount unitar
|
||||
laPropN(30)='discount_unitar_val'
|
||||
laPropN(31)='discount_unitar_ctva'
|
||||
laPropN(32)='discount_unitar_ctva_val'
|
||||
laPropN(33)='valftva' && totaluri lei (calculate de calculeaza_totaluri)
|
||||
laPropN(34)='valtva'
|
||||
laPropN(35)='valctva'
|
||||
laPropN(36)='valdiscountftva'
|
||||
laPropN(37)='valdiscounttva'
|
||||
laPropN(38)='valdiscountctva'
|
||||
laPropN(39)='valdiminuatftva'
|
||||
laPropN(40)='valdiminuattva'
|
||||
laPropN(41)='valdiminuatctva'
|
||||
laPropN(42)='vvalftva' && totaluri valuta (calculate de calculeaza_totaluri)
|
||||
laPropN(43)='vvaltva'
|
||||
laPropN(44)='vvalctva'
|
||||
laPropN(45)='vvaldiscountftva'
|
||||
laPropN(46)='vvaldiscounttva'
|
||||
laPropN(47)='vvaldiscountctva'
|
||||
laPropN(48)='vvaldiminuatftva'
|
||||
laPropN(49)='vvaldiminuattva'
|
||||
*-- (vvaldiminuatctva se adauga separat mai jos, ALEN a ramas 49 din motive de numarare initiala)
|
||||
LOCAL ARRAY laPropC(11)
|
||||
laPropC( 1)='codmat'
|
||||
laPropC( 2)='codmatf'
|
||||
laPropC( 3)='denumire'
|
||||
laPropC( 4)='um'
|
||||
laPropC( 5)='serie'
|
||||
laPropC( 6)='lot'
|
||||
laPropC( 7)='explicatie'
|
||||
laPropC( 8)='numar_contract'
|
||||
laPropC( 9)='codbare'
|
||||
laPropC(10)='nume_val'
|
||||
laPropC(11)='Cont'
|
||||
|
||||
PRIVATE poArticol, poDate
|
||||
DO AfLog WITH 'mediu pregatit, incep scenariile'
|
||||
|
||||
*========================= PAS 0: mediu pregatit =========================
|
||||
DO HarnessStep WITH 0, 'mediu pregatit, jtva_coloane cu ' + TRANSFORM(RECCOUNT('jtva_coloane')) + ' cote'
|
||||
|
||||
*========================= SCENARIU 1 (cazul tinta): bifa=1, 100.00 cu TVA, cant 1 =========
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnI = 1 TO ALEN(laPropN)
|
||||
=ADDPROPERTY(poArticol, laPropN(lnI), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnI = 1 TO ALEN(laPropC)
|
||||
=ADDPROPERTY(poArticol, laPropC(lnI), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 1001
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '707'
|
||||
poArticol.id_gestiune = 1
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 1
|
||||
poArticol.codmat = 'ART001'
|
||||
poArticol.denumire = 'ARTICOL TEST 100 CU TVA'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.21 && cota standard 21%
|
||||
poArticol.preturi_cu_tva = 1 && bifa PORNITA - politica implicita cu TVA inclus
|
||||
|
||||
poDate = CREATEOBJECT('Empty')
|
||||
=ADDPROPERTY(poDate, 'tip', 1) && 1 = lista de preturi, in Inlist activator bifa
|
||||
=ADDPROPERTY(poDate, 'in_valuta', 0)
|
||||
|
||||
PUBLIC goDlg
|
||||
goDlg = CREATEOBJECT('frm_articol_factura', 1, .F.)
|
||||
IF VARTYPE(goDlg) <> 'O'
|
||||
DO AfLog WITH 'FAIL: instantiere frm_articol_factura (scenariul 1)'
|
||||
DO HarnessDone WITH 'done-error'
|
||||
QUIT
|
||||
ENDIF
|
||||
goDlg.WindowType = 0
|
||||
goDlg.Visible = .T.
|
||||
goDlg.Show()
|
||||
DOEVENTS FORCE
|
||||
|
||||
DO AfLog WITH 'S1 dupa Init: preturi_cu_tva=' + TRANSFORM(poArticol.preturi_cu_tva) + ;
|
||||
' ck_pret_cu_tva.Value=' + TRANSFORM(goDlg.ck_pret_cu_tva.Value) + ;
|
||||
' Enabled=' + TRANSFORM(goDlg.ck_pret_cu_tva.Enabled)
|
||||
|
||||
*-- utilizatorul tasteaza 100.00 in campul "Pret cu TVA" (bifa deja pornita)
|
||||
goDlg.Clb_pretctva.tx_suma_nat.Value = 100
|
||||
goDlg.Clb_pretctva.tx_suma_nat.InteractiveChange()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 1, 'cazul tinta: pretctva tastat 100.00, cantitate 1'
|
||||
|
||||
DO VerificaNumeric WITH 'S1 pretctva pastrat', poArticol.pretctva, 100, 0.005
|
||||
DO VerificaNumeric WITH 'S1 CAZUL TINTA totalul facturii (valctva)', poArticol.valctva, 100, 0.005
|
||||
*-- cifrele complete ale cazului tinta, indiferent de PASS/FAIL - de citat in raport ca atare
|
||||
DO AfLog WITH 'S1 CIFRE CAZ TINTA: pretftva=' + TRANSFORM(poArticol.pretftva) + ;
|
||||
' pretctva=' + TRANSFORM(poArticol.pretctva) + ' tva=' + TRANSFORM(poArticol.tva) + ;
|
||||
' valftva=' + TRANSFORM(poArticol.valftva) + ' valtva=' + TRANSFORM(poArticol.valtva) + ;
|
||||
' valctva=' + TRANSFORM(poArticol.valctva)
|
||||
|
||||
*-- butonul OK (inainte_de_do_termin): parte din fluxul real, dar poate cere ActiveControl
|
||||
*-- (focus real de fereastra), nesigur headless. Daca arunca eroare, pasul e NEACOPERIT -
|
||||
*-- nu se raporteaza PASS/FAIL pe o executie care nu s-a confirmat.
|
||||
LOCAL llOkS1
|
||||
TRY
|
||||
llOkS1 = goDlg.inainte_de_do_termin()
|
||||
DO VerificaLogic WITH 'S1 buton OK (inainte_de_do_termin)', llOkS1, .T.
|
||||
CATCH TO loExcOk
|
||||
DO AfLog WITH 'NEACOPERIT S1 buton OK (inainte_de_do_termin): eroare ' + ;
|
||||
TRANSFORM(loExcOk.ErrorNo) + ' [' + loExcOk.Message + '] in ' + loExcOk.Procedure + ;
|
||||
':' + TRANSFORM(loExcOk.LineNo) + ' - pasul nu s-a putut executa headless, nu e nici PASS nici FAIL'
|
||||
ENDTRY
|
||||
goDlg.Hide()
|
||||
DOEVENTS FORCE
|
||||
|
||||
*========================= SCENARIU 2: comutare bifa, valoarea tastata nu se pierde =========
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnI = 1 TO ALEN(laPropN)
|
||||
=ADDPROPERTY(poArticol, laPropN(lnI), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnI = 1 TO ALEN(laPropC)
|
||||
=ADDPROPERTY(poArticol, laPropC(lnI), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 1002
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '707'
|
||||
poArticol.id_gestiune = 1
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 2
|
||||
poArticol.codmat = 'ART002'
|
||||
poArticol.denumire = 'ARTICOL TEST COMUTARE BIFA'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.21
|
||||
poArticol.preturi_cu_tva = 0 && bifa OPRITA - pretul fara TVA e cel editabil
|
||||
|
||||
poDate = CREATEOBJECT('Empty')
|
||||
=ADDPROPERTY(poDate, 'tip', 1)
|
||||
=ADDPROPERTY(poDate, 'in_valuta', 0)
|
||||
|
||||
goDlg = CREATEOBJECT('frm_articol_factura', 2, .F.)
|
||||
goDlg.WindowType = 0
|
||||
goDlg.Visible = .T.
|
||||
goDlg.Show()
|
||||
DOEVENTS FORCE
|
||||
|
||||
*-- utilizatorul tasteaza 50.00 fara TVA (bifa oprita)
|
||||
goDlg.Clb_pretftva.tx_suma_nat.Value = 50
|
||||
goDlg.Clb_pretftva.tx_suma_nat.InteractiveChange()
|
||||
DOEVENTS FORCE
|
||||
DO AfLog WITH 'S2 dupa tastare pretftva=50: pretftva=' + TRANSFORM(poArticol.pretftva) + ;
|
||||
' pretctva=' + TRANSFORM(poArticol.pretctva)
|
||||
|
||||
*-- bifeaza (OFF -> ON): pretul fara TVA tastat (50) nu trebuie sa se piarda
|
||||
goDlg.ck_pret_cu_tva.Value = 1
|
||||
goDlg.ck_pret_cu_tva.InteractiveChange()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 2, 'bifa OFF->ON: pretftva tastat=50 trebuie pastrat'
|
||||
DO VerificaNumeric WITH 'S2 comutare OFF->ON: pretftva NEPIERDUT', poArticol.pretftva, 50, 0.005
|
||||
DO VerificaNumeric WITH 'S2 comutare OFF->ON: pretctva derivat', poArticol.pretctva, 60.5, 0.005
|
||||
|
||||
*-- debifeaza (ON -> OFF): pretul (acum cu TVA, derivat) trebuie sa duca inapoi la acelasi pretftva=50
|
||||
goDlg.ck_pret_cu_tva.Value = 0
|
||||
goDlg.ck_pret_cu_tva.InteractiveChange()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 3, 'bifa ON->OFF: pretftva trebuie sa ramana 50 (roundtrip)'
|
||||
DO VerificaNumeric WITH 'S2 comutare ON->OFF: pretftva NEPIERDUT (roundtrip)', poArticol.pretftva, 50, 0.005
|
||||
goDlg.Hide()
|
||||
DOEVENTS FORCE
|
||||
|
||||
*========================= SCENARIU 3: cota standard 21% vs cota redusa 11% =========
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnI = 1 TO ALEN(laPropN)
|
||||
=ADDPROPERTY(poArticol, laPropN(lnI), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnI = 1 TO ALEN(laPropC)
|
||||
=ADDPROPERTY(poArticol, laPropC(lnI), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 1003
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '707'
|
||||
poArticol.id_gestiune = 1
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 1
|
||||
poArticol.codmat = 'ART003A'
|
||||
poArticol.denumire = 'ARTICOL TEST COTA STANDARD'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.21 && cota standard 21%
|
||||
poArticol.preturi_cu_tva = 0
|
||||
|
||||
poDate = CREATEOBJECT('Empty')
|
||||
=ADDPROPERTY(poDate, 'tip', 1)
|
||||
=ADDPROPERTY(poDate, 'in_valuta', 0)
|
||||
|
||||
goDlg = CREATEOBJECT('frm_articol_factura', 1, .F.)
|
||||
goDlg.WindowType = 0
|
||||
goDlg.Visible = .T.
|
||||
goDlg.Show()
|
||||
DOEVENTS FORCE
|
||||
goDlg.Clb_pretftva.tx_suma_nat.Value = 100
|
||||
goDlg.Clb_pretftva.tx_suma_nat.InteractiveChange()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 4, 'cota standard 21%: pretftva=100 -> tva/pretctva'
|
||||
DO VerificaNumeric WITH 'S3a cota 21%: tva', poArticol.tva, 21, 0.005
|
||||
DO VerificaNumeric WITH 'S3a cota 21%: pretctva', poArticol.pretctva, 121, 0.005
|
||||
goDlg.Hide()
|
||||
DOEVENTS FORCE
|
||||
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnI = 1 TO ALEN(laPropN)
|
||||
=ADDPROPERTY(poArticol, laPropN(lnI), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnI = 1 TO ALEN(laPropC)
|
||||
=ADDPROPERTY(poArticol, laPropC(lnI), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 1004
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '707'
|
||||
poArticol.id_gestiune = 1
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 1
|
||||
poArticol.codmat = 'ART003B'
|
||||
poArticol.denumire = 'ARTICOL TEST COTA REDUSA'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.11 && cota redusa 11%
|
||||
poArticol.preturi_cu_tva = 0
|
||||
|
||||
poDate = CREATEOBJECT('Empty')
|
||||
=ADDPROPERTY(poDate, 'tip', 1)
|
||||
=ADDPROPERTY(poDate, 'in_valuta', 0)
|
||||
|
||||
goDlg = CREATEOBJECT('frm_articol_factura', 1, .F.)
|
||||
goDlg.WindowType = 0
|
||||
goDlg.Visible = .T.
|
||||
goDlg.Show()
|
||||
DOEVENTS FORCE
|
||||
goDlg.Clb_pretftva.tx_suma_nat.Value = 100
|
||||
goDlg.Clb_pretftva.tx_suma_nat.InteractiveChange()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 5, 'cota redusa 11%: pretftva=100 -> tva/pretctva'
|
||||
DO VerificaNumeric WITH 'S3b cota 11%: tva', poArticol.tva, 11, 0.005
|
||||
DO VerificaNumeric WITH 'S3b cota 11%: pretctva', poArticol.pretctva, 111, 0.005
|
||||
goDlg.Hide()
|
||||
DOEVENTS FORCE
|
||||
|
||||
*========================= SCENARIU 4: discount unitar cu TVA (ramura discountctva) =========
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnI = 1 TO ALEN(laPropN)
|
||||
=ADDPROPERTY(poArticol, laPropN(lnI), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnI = 1 TO ALEN(laPropC)
|
||||
=ADDPROPERTY(poArticol, laPropC(lnI), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 1005
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '707'
|
||||
poArticol.id_gestiune = 1
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 1
|
||||
poArticol.codmat = 'ART004'
|
||||
poArticol.denumire = 'ARTICOL TEST DISCOUNT CU TVA'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.21
|
||||
poArticol.preturi_cu_tva = 1 && bifa pornita - ramura discountctva e cea activa
|
||||
|
||||
poDate = CREATEOBJECT('Empty')
|
||||
=ADDPROPERTY(poDate, 'tip', 1)
|
||||
=ADDPROPERTY(poDate, 'in_valuta', 0)
|
||||
|
||||
goDlg = CREATEOBJECT('frm_articol_factura', 1, .F.)
|
||||
goDlg.WindowType = 0
|
||||
goDlg.Visible = .T.
|
||||
goDlg.Show()
|
||||
DOEVENTS FORCE
|
||||
goDlg.Clb_pretctva.tx_suma_nat.Value = 100
|
||||
goDlg.Clb_pretctva.tx_suma_nat.InteractiveChange()
|
||||
DOEVENTS FORCE
|
||||
|
||||
*-- utilizatorul tasteaza 10.00 discount unitar cu TVA (Valid, cu When intai - ca la focus real)
|
||||
goDlg.Clb_discountctva.tx_suma_nat.When()
|
||||
goDlg.Clb_discountctva.tx_suma_nat.Value = 10
|
||||
goDlg.Clb_discountctva.tx_suma_nat.Valid()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 6, 'discount unitar cu TVA = 10, pret 100, cant 1'
|
||||
DO VerificaNumeric WITH 'S4 discount_unitar_ctva pastrat', poArticol.discount_unitar_ctva, 10, 0.005
|
||||
DO VerificaNumeric WITH 'S4 total diminuat cu TVA (valdiminuatctva)', poArticol.valdiminuatctva, 90, 0.005
|
||||
DO AfLog WITH 'S4 comparatie: fara discount (scenariul 1) valctva=100.00, cu discount 10 -> valdiminuatctva=' + TRANSFORM(poArticol.valdiminuatctva)
|
||||
goDlg.Hide()
|
||||
DOEVENTS FORCE
|
||||
|
||||
*========================= SCENARIU 5: bifa ACTIVA pe tip din Inlist =========================
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnI = 1 TO ALEN(laPropN)
|
||||
=ADDPROPERTY(poArticol, laPropN(lnI), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnI = 1 TO ALEN(laPropC)
|
||||
=ADDPROPERTY(poArticol, laPropC(lnI), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 1006
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '707'
|
||||
poArticol.id_gestiune = 1
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 1
|
||||
poArticol.codmat = 'ART005'
|
||||
poArticol.denumire = 'ARTICOL TEST BIFA ACTIVA'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.21
|
||||
poArticol.preturi_cu_tva = 0
|
||||
poArticol.pretftva = 0 && pret zero - irelevant, tip 1 activeaza bifa oricum
|
||||
|
||||
poDate = CREATEOBJECT('Empty')
|
||||
=ADDPROPERTY(poDate, 'tip', 1) && 1 = lista de preturi, IN Inlist(1,5,10,22,23,25,29,41)
|
||||
=ADDPROPERTY(poDate, 'in_valuta', 0)
|
||||
|
||||
goDlg = CREATEOBJECT('frm_articol_factura', 1, .F.)
|
||||
goDlg.WindowType = 0
|
||||
goDlg.Visible = .T.
|
||||
goDlg.Show()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 7, 'tip=1 (Inlist) -> bifa trebuie activa (Enabled=.T.)'
|
||||
DO VerificaLogic WITH 'S5 bifa ACTIVA pe tip din Inlist', goDlg.ck_pret_cu_tva.Enabled, .T.
|
||||
goDlg.Hide()
|
||||
DOEVENTS FORCE
|
||||
|
||||
*========================= SCENARIU 6: bifa DEZACTIVATA pe tip din afara listei =========
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnI = 1 TO ALEN(laPropN)
|
||||
=ADDPROPERTY(poArticol, laPropN(lnI), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnI = 1 TO ALEN(laPropC)
|
||||
=ADDPROPERTY(poArticol, laPropC(lnI), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 1007
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '707'
|
||||
poArticol.id_gestiune = 1
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 1
|
||||
poArticol.codmat = 'ART006'
|
||||
poArticol.denumire = 'ARTICOL TEST BIFA DEZACTIVATA'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.21
|
||||
poArticol.preturi_cu_tva = 0
|
||||
poArticol.pretftva = 50 && pret NENUL - conditie ceruta ca bifa sa ramana dezactivata
|
||||
|
||||
poDate = CREATEOBJECT('Empty')
|
||||
=ADDPROPERTY(poDate, 'tip', 3) && 3 = comanda, NU e in Inlist(1,5,10,22,23,25,29,41)
|
||||
=ADDPROPERTY(poDate, 'in_valuta', 0)
|
||||
|
||||
goDlg = CREATEOBJECT('frm_articol_factura', 1, .F.)
|
||||
goDlg.WindowType = 0
|
||||
goDlg.Visible = .T.
|
||||
goDlg.Show()
|
||||
DOEVENTS FORCE
|
||||
DO HarnessStep WITH 8, 'tip=3 (afara Inlist), pret nenul -> bifa trebuie dezactivata'
|
||||
DO VerificaLogic WITH 'S6 bifa DEZACTIVATA pe tip din afara listei, pret nenul', goDlg.ck_pret_cu_tva.Enabled, .F.
|
||||
goDlg.Hide()
|
||||
DOEVENTS FORCE
|
||||
|
||||
DO AfLog WITH 'GATA - toate scenariile Nivel 1 executate'
|
||||
DO HarnessStep WITH 9, 'final'
|
||||
DO HarnessDone WITH 'done'
|
||||
|
||||
CATCH TO loExc
|
||||
DO AfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
|
||||
DO HarnessDone WITH 'done-error'
|
||||
ENDTRY
|
||||
|
||||
QUIT
|
||||
|
||||
*==================================================================================
|
||||
PROCEDURE VerificaNumeric
|
||||
LPARAMETERS tcEticheta, tnObtinut, tnAsteptat, tnToleranta
|
||||
LOCAL lcMsg
|
||||
IF ABS(NVL(tnObtinut,-999999) - tnAsteptat) < tnToleranta
|
||||
lcMsg = 'PASS ' + tcEticheta + ': ' + TRANSFORM(tnObtinut) + ' (asteptat ' + TRANSFORM(tnAsteptat) + ')'
|
||||
ELSE
|
||||
lcMsg = 'FAIL ' + tcEticheta + ': obtinut=' + TRANSFORM(tnObtinut) + ' asteptat=' + TRANSFORM(tnAsteptat)
|
||||
ENDIF
|
||||
DO AfLog WITH lcMsg
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE VerificaLogic
|
||||
LPARAMETERS tcEticheta, tlObtinut, tlAsteptat
|
||||
LOCAL lcMsg
|
||||
IF tlObtinut = tlAsteptat
|
||||
lcMsg = 'PASS ' + tcEticheta + ': ' + TRANSFORM(tlObtinut) + ' (asteptat ' + TRANSFORM(tlAsteptat) + ')'
|
||||
ELSE
|
||||
lcMsg = 'FAIL ' + tcEticheta + ': obtinut=' + TRANSFORM(tlObtinut) + ' asteptat=' + TRANSFORM(tlAsteptat)
|
||||
ENDIF
|
||||
DO AfLog WITH lcMsg
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE AfErr
|
||||
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
|
||||
DO AfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE AfLog
|
||||
LPARAMETERS tcMsg
|
||||
SET SAFETY OFF
|
||||
LOCAL lcL
|
||||
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
|
||||
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
|
||||
ENDPROC
|
||||
|
||||
DEFINE CLASS dummyapp AS Custom
|
||||
PROCEDURE ReadIni
|
||||
LPARAMETERS tcSection, tcKey
|
||||
RETURN ''
|
||||
ENDPROC
|
||||
PROCEDURE WriteIni
|
||||
LPARAMETERS tcSection, tcKey, tcValue
|
||||
RETURN .T.
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
@@ -0,0 +1,10 @@
|
||||
# test_pret_cu_tva_dialog.ps1 - wrapper peste harness-ul generic pentru testul frm_articol_factura
|
||||
# (S5, plan #7 - pret_cu_tva). Rulare: powershell -ExecutionPolicy Bypass -File test_pret_cu_tva_dialog.ps1
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Teste = $PSScriptRoot
|
||||
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
|
||||
-TestPrg (Join-Path $Teste 'test_pret_cu_tva_dialog.prg') `
|
||||
-Steps @('mediu','tinta_100', 'comutare_on', 'comutare_off', 'cota_21', 'cota_11', 'discount', 'bifa_activa', 'bifa_dezactivata', 'final') `
|
||||
-ShotsDir (Join-Path $Teste 'screenshots') `
|
||||
-SyncDir (Join-Path $Teste 'uisync') `
|
||||
-StepTimeoutSec 60
|
||||
630
utile/Teste/facturare_pret_cu_tva/test_pret_cu_tva_nivel2.prg
Normal file
630
utile/Teste/facturare_pret_cu_tva/test_pret_cu_tva_nivel2.prg
Normal file
@@ -0,0 +1,630 @@
|
||||
* test_pret_cu_tva_nivel2.prg
|
||||
* Test UI Nivel 2 (S5, plan #7) pentru fluxul COMPLET prin frm_facturare_articole - cazurile 6 si 8
|
||||
* din task. Foloseste mecanismul validat in test_modal_unlock_smoketest2.prg (Timer pe _SCREEN +
|
||||
* _SCREEN.Forms + Controls(i)) ca sa conduca dialogul frm_articol_factura, deschis cu Show(1)
|
||||
* hardcodat in do_adauga_articol/do_modifica (frm_facturare_articole, ofacturare.vc2).
|
||||
*
|
||||
* Flux REAL, nu populare directa: articolul intra in crsfactura prin But_urmator1.Click() ->
|
||||
* do_urmator() -> do_adauga_articol() (cazul 6); modificarea trece prin But_modifica1.Click() /
|
||||
* grd_factura.DblClick() -> do_modifica() (cazul 8). crsarticole si crsfactura au structura REALA
|
||||
* (creeaza_facturacrs, aceleasi campuri ca in productie), fara Oracle.
|
||||
*
|
||||
* Cazuri:
|
||||
* PAS 0: grid gol - But_modifica1.Click() si grd_factura.DblClick() nu fac nimic, fara eroare.
|
||||
* PAS 1 (caz 6): adaugare cu bifa schimbata fata de politica (policy=0, user seteaza 1, pret cu
|
||||
* TVA=100) -> crsfactura.cu_tva=1, valctva=100.00 exact.
|
||||
* PAS 2 (caz 8a): modificare - But_modifica1 redeschide dialogul pe randul adaugat, comuta bifa
|
||||
* OFF, tasteaza pret fara TVA=60 -> acelasi rand actualizat (cu_tva=0, valctva=72.60).
|
||||
* PAS 3 (caz 8b): modificare prin grd_factura.DblClick() (al doilea canal, acelasi rezultat) -
|
||||
* schimba pretul cu TVA la 200, bifa ramane ON dupa pasul anterior... de fapt pasul 2 a
|
||||
* lasat bifa OFF, deci verifica ramura fara TVA din nou, cu alta valoare.
|
||||
* PAS 4 (caz 8c): Renunta - deschide dialogul, schimba o valoare, apasa Renunta -> randul ramane
|
||||
* BIT-IDENTIC (comparat camp cu camp fata de starea dinainte).
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
SET DELETED ON
|
||||
SET EXACT ON
|
||||
SET CENTURY ON
|
||||
SET DATE DMY
|
||||
SET DECIMALS TO 4
|
||||
SET NULLDISPLAY TO ''
|
||||
CLOSE DATABASES
|
||||
|
||||
PUBLIC gcUILog, gcSyncDir
|
||||
gcUILog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\test_pret_cu_tva_nivel2_log.txt"
|
||||
gcSyncDir = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\uisync_nivel2\"
|
||||
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
|
||||
|
||||
ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
ON SHUTDOWN QUIT
|
||||
|
||||
TRY
|
||||
LOCAL gcAppPath, lcPath
|
||||
gcAppPath = "D:\ROA\ROAFACTURARE\"
|
||||
SET DEFAULT TO (gcAppPath)
|
||||
|
||||
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
|
||||
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
|
||||
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
|
||||
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
|
||||
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\CALENDAR;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EMAIL;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\NFJSON;' + gcAppPath + 'COMUN\UTILE\NFXML;' + ;
|
||||
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
|
||||
SET PATH TO &lcPath ADDITIVE
|
||||
DO AfLog WITH 'SET PATH OK'
|
||||
|
||||
*----- CLASE (lista dovedita de suita Nivel 1 - mediul unei suite noi se mosteneste din suita
|
||||
* care TRECE, nu dintr-un smoke-test) -----
|
||||
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
|
||||
SET CLASSLIB TO registry ADDITIVE
|
||||
SET CLASSLIB TO cauta_alfa_forms ADDITIVE
|
||||
SET CLASSLIB TO ofacturare.vcx ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_comun.vcx ADDITIVE
|
||||
SET CLASSLIB TO accessibility.vcx ADDITIVE
|
||||
SET CLASSLIB TO ocriterii.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_statusbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO DECABAZA ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare2 ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_rapoarte ADDITIVE
|
||||
SET CLASSLIB TO orapoarte ADDITIVE
|
||||
SET CLASSLIB TO ferestre_oracle ADDITIVE
|
||||
SET CLASSLIB TO messagebox ADDITIVE
|
||||
SET CLASSLIB TO otoolbar ADDITIVE
|
||||
SET CLASSLIB TO onom_curs ADDITIVE
|
||||
SET CLASSLIB TO comun ADDITIVE
|
||||
SET CLASSLIB TO ferestre_cere_date ADDITIVE
|
||||
SET CLASSLIB TO baza ADDITIVE
|
||||
SET CLASSLIB TO caut ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri ADDITIVE
|
||||
SET CLASSLIB TO serii_numere ADDITIVE
|
||||
SET CLASSLIB TO caut_ora ADDITIVE
|
||||
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
|
||||
SET CLASSLIB TO _calendar.vcx ADDITIVE
|
||||
SET CLASSLIB TO locale ADDITIVE
|
||||
SET CLASSLIB TO overificari ADDITIVE
|
||||
SET CLASSLIB TO ocomenzi ADDITIVE
|
||||
DO AfLog WITH 'SET CLASSLIB OK'
|
||||
|
||||
*----- PROCEDURI (mock amessagebox PRIMUL, ui_harness la final) -----
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg"
|
||||
SET PROCEDURE TO proceduri_comune ADDITIVE
|
||||
SET PROCEDURE TO quitapp ADDITIVE
|
||||
SET PROCEDURE TO init_program ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare.prg ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare2.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_rapoarte_fact.prg ADDITIVE
|
||||
SET PROCEDURE TO email.prg ADDITIVE
|
||||
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
|
||||
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
|
||||
SET PROCEDURE TO updateserver.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
|
||||
SET PROCEDURE TO ocautare ADDITIVE
|
||||
SET PROCEDURE TO odocumente ADDITIVE
|
||||
SET PROCEDURE TO osecurity ADDITIVE
|
||||
SET PROCEDURE TO acces_meniu ADDITIVE
|
||||
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO ini.prg ADDITIVE
|
||||
SET PROCEDURE TO cauta_alfa.prg ADDITIVE
|
||||
SET PROCEDURE TO oHeader.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_curs.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare.prg ADDITIVE
|
||||
SET PROCEDURE TO oserii_numere.prg ADDITIVE
|
||||
SET PROCEDURE TO wwutils.prg ADDITIVE
|
||||
SET PROCEDURE TO wwConfig.prg ADDITIVE
|
||||
SET PROCEDURE TO wwApi.prg ADDITIVE
|
||||
SET PROCEDURE TO oexport.prg ADDITIVE
|
||||
SET PROCEDURE TO validare.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_comun.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_stoc.prg ADDITIVE
|
||||
SET PROCEDURE TO pmenu.prg ADDITIVE
|
||||
SET PROCEDURE TO ointroduceri.prg ADDITIVE
|
||||
SET PROCEDURE TO ovariabile_globale.prg ADDITIVE
|
||||
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
|
||||
SET PROCEDURE TO filebringer.prg ADDITIVE
|
||||
SET PROCEDURE TO iniacces.prg ADDITIVE
|
||||
SET PROCEDURE TO oupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO procese.prg ADDITIVE
|
||||
SET PROCEDURE TO version.prg ADDITIVE
|
||||
SET PROCEDURE TO wwhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlaccess.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlparser.prg ADDITIVE
|
||||
SET PROCEDURE TO xdate.prg ADDITIVE
|
||||
SET PROCEDURE TO suma_in_vorbe.prg ADDITIVE
|
||||
SET PROCEDURE TO controllerecr ADDITIVE
|
||||
SET PROCEDURE TO regex.prg ADDITIVE
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
|
||||
DO AfLog WITH 'SET PROCEDURE OK'
|
||||
|
||||
*----- Globale aplicatie -----
|
||||
PUBLIC gnPc, gnPVal, gnPcant, gnPPretV, gnScadereStoc, gnMemProcDisc, gl406, gcAcces
|
||||
PUBLIC gnModTotFact, gnRF_FACTURARE_FARA_STOC
|
||||
*-- gnModTotFact/gnRF_FACTURARE_FARA_STOC: lista completa a globalelor de aplicatie cerute de
|
||||
*-- Init/do_adauga_articol/do_modifica/do_verifica_articol/do_initializeaza_articol (extrasa cu
|
||||
*-- vfp_symbols.ps1 -Class frm_facturare_articole, identificatori g[nlc]\w+), restul deja
|
||||
*-- prezente in mediu. Puse pe 0 (implicit prudent) ca sa NU activeze ramuri neintentionate -
|
||||
*-- gnModTotFact=1 ar intra pe modificarea totalului facturii, gnRF_FACTURARE_FARA_STOC=1 pe
|
||||
*-- facturare fara stoc; niciuna nu e ce se testeaza aici. NVL() nu apara de variabila
|
||||
*-- nedeclarata, doar de valoare NULL - trebuie sa existe.
|
||||
gnModTotFact = 0
|
||||
gnRF_FACTURARE_FARA_STOC = 0
|
||||
*-- gnPPret/gnPPretVal: presupuse (nu exista in cod - vin din configuratia Oracle citita la
|
||||
*-- pornirea reala; ceruta de creeaza_facturacrs, ofacturare_comun.prg:1770, neintalnita la
|
||||
*-- Nivel 1 care nu atinge acel cursor). Ating DOAR pret_achizitie/pretd (max(...,4)) - niciun
|
||||
*-- camp verificat de testele de mai jos (pretftva/pretctva/valftva/valtva/valctva folosesc
|
||||
*-- gnPPretV+gnPc, deja corecte). precizie_max_pret_vz e #define=6 in acelasi fisier, nu
|
||||
*-- variabila - nu se declara aici.
|
||||
PUBLIC gnPPret, gnPPretVal
|
||||
gnPc = 2
|
||||
gnPVal = 2
|
||||
gnPcant = 3
|
||||
gnPPretV = 4
|
||||
gnPPret = 4
|
||||
gnPPretVal = 4
|
||||
gnScadereStoc = 0 && bypass complet logica de stoc (do_alege_stoc nu se apeleaza)
|
||||
gnMemProcDisc = 0
|
||||
gl406 = .F.
|
||||
gcAcces = "1;2;3;4;5;6;7;8;"
|
||||
PUBLIC nror(65000)
|
||||
|
||||
PUBLIC goApp, goExport, goExecutor
|
||||
goApp = CREATEOBJECT('dummyapp')
|
||||
goExport = CREATEOBJECT('dummyexport')
|
||||
goExecutor = CREATEOBJECT('dummyexecutor')
|
||||
|
||||
IF USED('jtva_coloane')
|
||||
USE IN ('jtva_coloane')
|
||||
ENDIF
|
||||
CREATE CURSOR jtva_coloane (id_jtva_coloana N(14), denumire C(50), cota_tva N(6,2))
|
||||
INSERT INTO jtva_coloane VALUES (1, 'TVA 21%', 21)
|
||||
INSERT INTO jtva_coloane VALUES (2, 'TVA 11%', 11)
|
||||
GO TOP IN jtva_coloane
|
||||
|
||||
IF USED('saft_taxtable')
|
||||
USE IN ('saft_taxtable')
|
||||
ENDIF
|
||||
CREATE CURSOR saft_taxtable (taxname C(250), procent_taxa N(7,2), taxcode N(6), tva_livrari N(1))
|
||||
INSERT INTO saft_taxtable VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%', 21, 301104, 1)
|
||||
INSERT INTO saft_taxtable VALUES ('3011XX-Achizitii de bunuri si servicii taxabile cu cota de 11%', 11, 301108, 1)
|
||||
|
||||
*----- crsfactura: structura REALA, fara Oracle (creeaza_facturacrs, ofacturare_comun.prg:1770) -----
|
||||
DO creeaza_facturacrs WITH 'crsfactura'
|
||||
DO AfLog WITH 'crsfactura creat, Reccount=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
*----- crsarticole: sursa (stoc/lista de preturi) - RecordSource al grd_articole. Campuri
|
||||
* alese ca sa acopere atat coloanele gridului (denumire, gestionabil, codmat, pret,
|
||||
* cantitate, preturi_cu_tva, pret_val, nume_val, nume_lista_preturi, serie, codbare) cat
|
||||
* si tot ce Scatter+do_initializeaza_articol au nevoie (restul, verificat din cod). -----
|
||||
IF USED('crsarticole')
|
||||
USE IN ('crsarticole')
|
||||
ENDIF
|
||||
CREATE CURSOR crsarticole (id_articol N(10), Id_Pol N(10), id_gestiune N(10), denumire C(100), ;
|
||||
codmat C(50), codbare C(50), gestionabil N(1), cantitate N(18,4), pret N(18,4), ;
|
||||
pret_val N(18,4), preturi_cu_tva N(1), proc_tvav N(18,4), discount_unitar N(18,4), ;
|
||||
discount_unitar_val N(18,4), pret_achizitie N(18,4), tip_valuta N(1), Curs N(18,4), ;
|
||||
multiplicator N(10,4), Cont C(10), um C(10), serie C(30), lot C(30), explicatie C(200), ;
|
||||
opt_facturare N(3), id_ctr N(10), numar_contract C(50), pretd N(18,4), id_valuta N(10), ;
|
||||
nume_val C(20), nume_lista_preturi C(100), id_jtva_coloana N(10), taxcode N(6), id_c N(10))
|
||||
INSERT INTO crsarticole (id_articol, Id_Pol, id_gestiune, denumire, codmat, codbare, ;
|
||||
gestionabil, cantitate, pret, pret_val, preturi_cu_tva, proc_tvav, discount_unitar, ;
|
||||
discount_unitar_val, pret_achizitie, tip_valuta, Curs, multiplicator, Cont, um, serie, ;
|
||||
lot, explicatie, opt_facturare, id_ctr, numar_contract, pretd, id_valuta, nume_val, ;
|
||||
nume_lista_preturi, id_jtva_coloana, taxcode, id_c) ;
|
||||
VALUES (2001, 1, 1, 'ARTICOL NIVEL2', 'ART2001', '', ;
|
||||
0, 100, 50, 0, 0, 1.21, 0, ;
|
||||
0, 0, 0, 1, 1, '707', 'BUC', '', ;
|
||||
'', '', 0, 0, '', 0, 0, '', ;
|
||||
'LISTA TEST', 1, 0, 1)
|
||||
GO TOP IN crsarticole
|
||||
DO AfLog WITH 'crsarticole creat, Reccount=' + TRANSFORM(RECCOUNT('crsarticole'))
|
||||
|
||||
*----- poDate: clasa REALA oDateFactura (ofacturare_comun.prg:99, deja incarcata prin SET
|
||||
* PROCEDURE), nu obiect Empty umplut manual - are toate proprietatile cu valorile
|
||||
* implicite de productie (inclusiv discount_evidentiat=0). PRIVATE la nivel de PROGRAM
|
||||
* PRINCIPAL, vizibil (scoping VFP) in tot lantul apelat mai jos (frm_facturare_articole,
|
||||
* do_adauga_articol, do_modifica, frm_articol_factura) - la fel ca in productie
|
||||
* (Procedure factureaza, ofacturare.prg:95). Constructia ramane INLINE in main (capcana l). -----
|
||||
PRIVATE poDate
|
||||
poDate = CREATEOBJECT('oDateFactura')
|
||||
poDate.tip = 1 && 1 = facturare pe baza de lista de preturi
|
||||
poDate.serie_act = 'TST'
|
||||
poDate.nract = 1
|
||||
DO AfLog WITH 'poDate pregatit (oDateFactura), tip=' + TRANSFORM(poDate.tip)
|
||||
|
||||
*----- driverul de deblocare Show(1): Timer la nivel _SCREEN + _SCREEN.Forms + Controls(i),
|
||||
* mecanism validat in test_modal_unlock_smoketest2.prg (PASS). gcCazAct selecteaza
|
||||
* interactiunea de aplicat la fiecare dialog nou detectat. -----
|
||||
PUBLIC goDriver, gnDriverTick, glDlgTratat, gcCazAct
|
||||
gnDriverTick = 0
|
||||
glDlgTratat = .F.
|
||||
gcCazAct = ''
|
||||
goDriver = CREATEOBJECT('driverdeblocare3')
|
||||
_SCREEN.AddObject('tmrDrvN2', 'Timer')
|
||||
_SCREEN.tmrDrvN2.Interval = 200
|
||||
BINDEVENT(_SCREEN.tmrDrvN2, 'Timer', goDriver, 'Executa')
|
||||
_SCREEN.tmrDrvN2.Enabled = .T.
|
||||
DO AfLog WITH 'driver+timer pregatiti'
|
||||
|
||||
*----- Desktop VFP vizibil, ca la celelalte suite UI -----
|
||||
_SCREEN.Visible = .T.
|
||||
_SCREEN.WindowState = 2
|
||||
_SCREEN.Caption = 'TEST UI Nivel 2 (cazurile 6 si 8)'
|
||||
|
||||
PUBLIC goFrm
|
||||
goFrm = CREATEOBJECT('frm_facturare_articole')
|
||||
goFrm.WindowType = 0 && testul instantiaza direct - modeless, Show() revine imediat
|
||||
goFrm.Show()
|
||||
goFrm.WindowState = 2
|
||||
DOEVENTS FORCE
|
||||
DO AfLog WITH 'frm_facturare_articole afisat modeless, Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
DO HarnessStep WITH 0, 'formular afisat, grid gol'
|
||||
|
||||
*========================= PAS 0: grid gol - But_modifica1/DblClick nu fac nimic =========
|
||||
LOCAL lnRecFataDe0
|
||||
lnRecFataDe0 = RECCOUNT('crsfactura')
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
IF RECCOUNT('crsfactura') = lnRecFataDe0
|
||||
DO UILog WITH 'PASS P0a But_modifica1 pe grid gol: nu a modificat Reccount (' + TRANSFORM(RECCOUNT('crsfactura')) + ')'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P0a But_modifica1 pe grid gol: Reccount a devenit ' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
ENDIF
|
||||
goFrm.grd_factura.DblClick()
|
||||
DOEVENTS FORCE
|
||||
IF RECCOUNT('crsfactura') = lnRecFataDe0
|
||||
DO UILog WITH 'PASS P0b grd_factura.DblClick pe grid gol: nu a modificat Reccount'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P0b grd_factura.DblClick pe grid gol: Reccount a devenit ' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
ENDIF
|
||||
DO HarnessStep WITH 1, 'P0 grid gol verificat'
|
||||
|
||||
*========================= PAS 1 (CAZUL 6): adaugare cu bifa schimbata =========================
|
||||
*-- politica implicita (crsarticole.preturi_cu_tva=0, fara TVA) - userul o schimba in dialog la
|
||||
*-- 1 (cu TVA), tasteaza pret cu TVA=100, cantitate=1 (zerorizata de do_initializeaza_articol
|
||||
*-- pt. tip=1, se completeaza in dialog, ca la fluxul real).
|
||||
SELECT crsarticole
|
||||
GO TOP
|
||||
gcCazAct = 'CASE6'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_urmator1.Click()
|
||||
DOEVENTS FORCE
|
||||
LOCAL lnWait
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_urmator1: glDlgTratat=' + TRANSFORM(glDlgTratat) + ' Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
IF cu_tva = 1 AND ABS(valctva - 100) < 0.01
|
||||
DO UILog WITH 'PASS P1 CAZUL 6: cu_tva=' + TRANSFORM(cu_tva) + ' valctva=' + TRANSFORM(valctva) + ' (asteptat cu_tva=1 valctva=100)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P1 CAZUL 6: cu_tva=' + TRANSFORM(cu_tva) + ' valctva=' + TRANSFORM(valctva) + ' (asteptat cu_tva=1 valctva=100)'
|
||||
ENDIF
|
||||
DO UILog WITH 'P1 cifre complete: pretftva=' + TRANSFORM(pretftva) + ' pretctva=' + TRANSFORM(pretctva) + ' valftva=' + TRANSFORM(valftva) + ' valtva=' + TRANSFORM(valtva)
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P1 CAZUL 6: Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) + ' (asteptat 1) - articolul nu a fost adaugat'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 2, 'P1 caz 6 propagare: Reccount=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
*========================= PAS 2 (CAZUL 8a): modificare prin But_modifica1 =========================
|
||||
*-- comuta bifa OFF (fara TVA), tasteaza pret fara TVA=60 -> valctva asteptat 60*1.21=72.60
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
gcCazAct = 'CASE8_MOD_OFF'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_modifica1 (P2): glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
IF cu_tva = 0 AND ABS(valctva - 72.6) < 0.01
|
||||
DO UILog WITH 'PASS P2 CAZUL 8a (But_modifica1): cu_tva=' + TRANSFORM(cu_tva) + ' valctva=' + TRANSFORM(valctva) + ' (asteptat cu_tva=0 valctva=72.60)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P2 CAZUL 8a (But_modifica1): cu_tva=' + TRANSFORM(cu_tva) + ' valctva=' + TRANSFORM(valctva) + ' (asteptat cu_tva=0 valctva=72.60)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P2: nu exista randul din P1 (Reccount=' + TRANSFORM(RECCOUNT('crsfactura')) + ')'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 3, 'P2 caz 8a modificare But_modifica1'
|
||||
|
||||
*========================= PAS 3 (CAZUL 8b): modificare prin grd_factura.DblClick() =========
|
||||
*-- al doilea canal cerut de task - schimba pretul cu TVA la 200, bifa ON
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
gcCazAct = 'CASE8_MOD_ON'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.grd_factura.DblClick()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa grd_factura.DblClick (P3): glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
IF cu_tva = 1 AND ABS(valctva - 200) < 0.01
|
||||
DO UILog WITH 'PASS P3 CAZUL 8b (DblClick): cu_tva=' + TRANSFORM(cu_tva) + ' valctva=' + TRANSFORM(valctva) + ' (asteptat cu_tva=1 valctva=200)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P3 CAZUL 8b (DblClick): cu_tva=' + TRANSFORM(cu_tva) + ' valctva=' + TRANSFORM(valctva) + ' (asteptat cu_tva=1 valctva=200)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P3: nu exista randul (Reccount=' + TRANSFORM(RECCOUNT('crsfactura')) + ')'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 4, 'P3 caz 8b modificare DblClick'
|
||||
|
||||
*========================= PAS 4 (CAZUL 8c): Renunta - randul ramane BIT-IDENTIC =========
|
||||
*-- SCATTER TO array (nu AFIELDS - AFIELDS umple un tablou de METADATE si intoarce un numar,
|
||||
*-- nu e o colectie FOR EACH) captureaza VALORILE campurilor din randul curent, memo inclusiv.
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
LOCAL ARRAY laSnapDinainte[1]
|
||||
LOCAL lnF, lnCampuri
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
SCATTER TO laSnapDinainte
|
||||
|
||||
gcCazAct = 'CASE8_RENUNTA'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_modifica1 (P4, Renunta): glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
LOCAL ARRAY laSnapDupa[1]
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
SCATTER TO laSnapDupa
|
||||
|
||||
LOCAL llIdentic
|
||||
llIdentic = (ALEN(laSnapDinainte,1) == ALEN(laSnapDupa,1))
|
||||
lnCampuri = 0
|
||||
IF llIdentic
|
||||
FOR lnF = 1 TO ALEN(laSnapDinainte,1)
|
||||
lnCampuri = lnCampuri + 1
|
||||
IF !(TRANSFORM(laSnapDinainte(lnF)) == TRANSFORM(laSnapDupa(lnF)))
|
||||
llIdentic = .F.
|
||||
DO AfLog WITH 'P4 diagnostic - campul ' + TRANSFORM(lnF) + ' difera: [' + ;
|
||||
TRANSFORM(laSnapDinainte(lnF)) + '] -> [' + TRANSFORM(laSnapDupa(lnF)) + ']'
|
||||
ENDIF
|
||||
ENDFOR
|
||||
ENDIF
|
||||
|
||||
IF llIdentic
|
||||
DO UILog WITH 'PASS P4 CAZUL 8c Renunta: randul ramane BIT-IDENTIC (' + TRANSFORM(lnCampuri) + ' campuri comparate)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P4 CAZUL 8c Renunta: randul S-A MODIFICAT desi s-a apasat Renunta (vezi diag pe campuri mai sus)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P4: nu exista randul (Reccount=' + TRANSFORM(RECCOUNT('crsfactura')) + ')'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 5, 'P4 caz 8c Renunta'
|
||||
|
||||
*========================= PAS 5 (CAZUL 11, rec_s2c): crestere cantitate pe tip FARA verificare
|
||||
*========================= de stoc -> acceptata neconditionat (plafonul exista dar nu se verifica)
|
||||
*-- tip=1 nu e in Inlist(poDate.tip,4,21,23,28,42,47) din inainte_de_do_termin, deci cresterea
|
||||
*-- cantitatii nu are plafon real - verifica ca S2c (recalcularea plafonului pt. tipurile CU
|
||||
*-- stoc) nu a introdus vreo restrictie neintentionata pe tipurile FARA verificare.
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
gcCazAct = 'CASE11_CANTITATE'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_modifica1 (P5, caz 11): glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
IF ABS(cantitate - 50) < 0.001
|
||||
DO UILog WITH 'PASS P5 CAZUL 11 (rec_s2c): crestere cantitate pe tip fara verificare de stoc acceptata: cantitate=' + TRANSFORM(cantitate) + ' (asteptat 50)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P5 CAZUL 11 (rec_s2c): cantitate=' + TRANSFORM(cantitate) + ' (asteptat 50) - crestere respinsa sau neaplicata'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P5: nu exista randul (Reccount=' + TRANSFORM(RECCOUNT('crsfactura')) + ')'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 6, 'P5 caz 11 plafon - final'
|
||||
|
||||
DO HarnessDone WITH 'done'
|
||||
|
||||
CATCH TO loExc
|
||||
DO AfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
|
||||
DO HarnessDone WITH 'done-error'
|
||||
ENDTRY
|
||||
|
||||
QUIT
|
||||
|
||||
*==================================================================================
|
||||
PROCEDURE AfErr
|
||||
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
|
||||
DO AfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE AfLog
|
||||
LPARAMETERS tcMsg
|
||||
SET SAFETY OFF
|
||||
LOCAL lcL
|
||||
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
|
||||
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE UILog
|
||||
LPARAMETERS tcMsg
|
||||
DO AfLog WITH tcMsg
|
||||
ENDPROC
|
||||
|
||||
*-- FindCtl: referinta directa la un control prin Controls(i), potrivit dupa .Name - tehnica
|
||||
*-- validata in test_modal_unlock_smoketest2.prg (accesul cu prefix direct pe o referinta obtinuta
|
||||
*-- din _SCREEN.Forms a dat eroare 1925 in acel diagnostic; Controls(i) e calea sigura, folosita
|
||||
*-- consecvent, inclusiv pentru nivelurile imbricate).
|
||||
PROCEDURE FindCtl
|
||||
LPARAMETERS toParent, tcName
|
||||
LOCAL lnI, loGasit
|
||||
loGasit = .NULL.
|
||||
FOR lnI = 1 TO toParent.ControlCount
|
||||
IF UPPER(toParent.Controls(lnI).Name) == UPPER(tcName)
|
||||
loGasit = toParent.Controls(lnI)
|
||||
ENDIF
|
||||
ENDFOR
|
||||
RETURN loGasit
|
||||
ENDPROC
|
||||
|
||||
DEFINE CLASS dummyapp AS Custom
|
||||
PROCEDURE ReadIni
|
||||
LPARAMETERS tcSection, tcKey
|
||||
RETURN ''
|
||||
ENDPROC
|
||||
PROCEDURE WriteIni
|
||||
LPARAMETERS tcSection, tcKey, tcValue
|
||||
RETURN .T.
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS dummyexport AS Custom
|
||||
PROCEDURE citesteSetareRegistru
|
||||
LPARAMETERS tcCheie
|
||||
RETURN ''
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS dummyexecutor AS Custom
|
||||
cEroare = ''
|
||||
PROCEDURE oExecute
|
||||
LPARAMETERS tcSql, tcCursor
|
||||
IF USED(tcCursor)
|
||||
USE IN (tcCursor)
|
||||
ENDIF
|
||||
CREATE CURSOR (tcCursor) (codmatf C(50))
|
||||
RETURN 1
|
||||
ENDPROC
|
||||
PROCEDURE oReset
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS driverdeblocare3 AS Custom
|
||||
PROCEDURE Executa
|
||||
*-- rulat la fiecare tick al _SCREEN.tmrDrvN2. Cauta FRM_ARTICOL_FACTURA prin _SCREEN.Forms,
|
||||
*-- aplica interactiunea selectata de gcCazAct (setata de test INAINTE de fiecare click),
|
||||
*-- si inchide dialogul (do_termin sau do_renunt, dupa caz).
|
||||
LOCAL lnI, loForm, llGasit
|
||||
gnDriverTick = gnDriverTick + 1
|
||||
llGasit = .F.
|
||||
FOR lnI = 1 TO _SCREEN.FormCount
|
||||
IF UPPER(_SCREEN.Forms(lnI).Class) == 'FRM_ARTICOL_FACTURA'
|
||||
loForm = _SCREEN.Forms(lnI)
|
||||
llGasit = .T.
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
IF glDlgTratat OR !llGasit
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
DO AfLog WITH 'driver3 tick ' + TRANSFORM(gnDriverTick) + ' POTRIVIT (caz=' + gcCazAct + '), intru in interactiune'
|
||||
|
||||
LOCAL loBifa, loCantitateCtn, loCantitate, loPretCtvaCtn, loPretCtvaNat, loPretFtvaCtn, loPretFtvaNat, loRenunt
|
||||
|
||||
TRY
|
||||
DO CASE
|
||||
CASE gcCazAct == 'CASE6'
|
||||
loBifa = FindCtl(loForm, 'ck_pret_cu_tva')
|
||||
loBifa.Value = 1
|
||||
loBifa.InteractiveChange()
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = 1
|
||||
loCantitate.InteractiveChange()
|
||||
loPretCtvaCtn = FindCtl(loForm, 'Clb_pretctva')
|
||||
loPretCtvaNat = FindCtl(loPretCtvaCtn, 'tx_suma_nat')
|
||||
loPretCtvaNat.Value = 100
|
||||
loPretCtvaNat.InteractiveChange()
|
||||
DO AfLog WITH 'driver3 CASE6: bifa=1 cantitate=1 pretctva=100, apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'CASE8_MOD_OFF'
|
||||
loBifa = FindCtl(loForm, 'ck_pret_cu_tva')
|
||||
loBifa.Value = 0
|
||||
loBifa.InteractiveChange()
|
||||
loPretFtvaCtn = FindCtl(loForm, 'Clb_pretftva')
|
||||
loPretFtvaNat = FindCtl(loPretFtvaCtn, 'tx_suma_nat')
|
||||
loPretFtvaNat.Value = 60
|
||||
loPretFtvaNat.InteractiveChange()
|
||||
DO AfLog WITH 'driver3 CASE8_MOD_OFF: bifa=0 pretftva=60, apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'CASE8_MOD_ON'
|
||||
loBifa = FindCtl(loForm, 'ck_pret_cu_tva')
|
||||
loBifa.Value = 1
|
||||
loBifa.InteractiveChange()
|
||||
loPretCtvaCtn = FindCtl(loForm, 'Clb_pretctva')
|
||||
loPretCtvaNat = FindCtl(loPretCtvaCtn, 'tx_suma_nat')
|
||||
loPretCtvaNat.Value = 200
|
||||
loPretCtvaNat.InteractiveChange()
|
||||
DO AfLog WITH 'driver3 CASE8_MOD_ON: bifa=1 pretctva=200, apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'CASE8_RENUNTA'
|
||||
loPretCtvaCtn = FindCtl(loForm, 'Clb_pretctva')
|
||||
loPretCtvaNat = FindCtl(loPretCtvaCtn, 'tx_suma_nat')
|
||||
loPretCtvaNat.Value = 9999
|
||||
loPretCtvaNat.InteractiveChange()
|
||||
loRenunt = FindCtl(loForm, 'But_renunt1')
|
||||
DO AfLog WITH 'driver3 CASE8_RENUNTA: pretctva tastat 9999, apas But_renunt1 (Renunta)'
|
||||
loRenunt.Click()
|
||||
|
||||
CASE gcCazAct == 'CASE11_CANTITATE'
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = 50
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driver3 CASE11_CANTITATE: cantitate=50 (tip fara verificare de stoc), apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
OTHERWISE
|
||||
DO AfLog WITH 'driver3: gcCazAct necunoscut [' + gcCazAct + ']'
|
||||
ENDCASE
|
||||
|
||||
glDlgTratat = .T.
|
||||
DO AfLog WITH 'driver3: interactiune REUSITA pentru caz=' + gcCazAct
|
||||
CATCH TO loExcDrv
|
||||
DO AfLog WITH 'driver3: CATCH caz=' + gcCazAct + ' ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ;
|
||||
' Message=' + loExcDrv.Message + ' Procedure=' + loExcDrv.Procedure + ;
|
||||
' LineNo=' + TRANSFORM(loExcDrv.LineNo) + ' LineContents=[' + loExcDrv.LineContents + ']'
|
||||
ENDTRY
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
@@ -0,0 +1,11 @@
|
||||
# test_pret_cu_tva_nivel2.ps1 - wrapper peste harness-ul generic pentru testele Nivel 2
|
||||
# (cazurile 6 si 8, S5, plan #7). Rulare: powershell -ExecutionPolicy Bypass -File test_pret_cu_tva_nivel2.ps1
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Teste = $PSScriptRoot
|
||||
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
|
||||
-TestPrg (Join-Path $Teste 'test_pret_cu_tva_nivel2.prg') `
|
||||
-Steps @('grid_gol_afisat', 'p0_grid_gol', 'p1_caz6', 'p2_caz8a', 'p3_caz8b', 'p4_caz8c', 'p5_caz11_plafon') `
|
||||
-ShotsDir (Join-Path $Teste 'screenshots_nivel2') `
|
||||
-SyncDir (Join-Path $Teste 'uisync_nivel2') `
|
||||
-StepTimeoutSec 60 `
|
||||
-ReadyTimeoutSec 90
|
||||
@@ -0,0 +1,506 @@
|
||||
* test_pret_cu_tva_nivel2_retur.prg
|
||||
* Test UI Nivel 2 (S5, plan #7) pentru RAMURA DE RETUR (tip 8/9) a plafonului recalculat de S2c
|
||||
* (rec_s2c_ncantitatemax.md). Verificarea de plafon pentru retur (frm_articol_factura.
|
||||
* inainte_de_do_termin, ofacturare.vc2:2265, "Nu se poate returna mai mult decat a fost facturat!")
|
||||
* NU are garda de gestionabil/llStoculConteaza - se verifica NECONDITIONAT - deci articolul poate
|
||||
* fi gestionabil=0, ceea ce pastreaza fluxul de adaugare pe calea SIMPLA (frm_articol_factura
|
||||
* direct, fara do_alege_stoc), aceeasi infrastructura dovedita la cazurile 6/8.
|
||||
*
|
||||
* Cazuri (din rec_s2c_ncantitatemax.md, ramura retur - tip 8/9):
|
||||
* PAS 0: adaugare linie retur (crsarticole.cantitate=10 "cat s-a facturat", id_c=3001) prin
|
||||
* But_urmator1.Click() real -> crsfactura.cantitate=-10 (negat de do_initializeaza_articol
|
||||
* pt. tip 8/9), crsarticole.cantitate scade la 0 (decrementata de do_adauga_articol).
|
||||
* PAS 1: modificare DOAR de pret (cantitate neschimbata) -> trebuie ACCEPTATA (plafonul recalculat
|
||||
* egaleaza cantitatea curenta a liniei: 0 - (-10) = 10 = Abs(-10), nu strict mai mare).
|
||||
* PAS 2: se simuleaza o schimbare externa a stocului sursa (alt utilizator/proces a modificat
|
||||
* cat mai e disponibil de returnat) - crsarticole.cantitate setat manual la 5 (NU e
|
||||
* populare de crsfactura, e o schimbare pe cursorul SURSA, plauzibila in productie).
|
||||
* PAS 3: crestere cantitate returnata la -12 (magnitudine 12) -> plafonul RECALCULAT e
|
||||
* 5 - (-10) = 15, deci 12 <= 15 -> ACCEPTATA. Sub formula VECHE (ncantitatemax fixat la
|
||||
* cantitatea curenta a liniei, magnitudine 10, nerecalculat), 12 > 10 ar fi fost RESPINSA -
|
||||
* acesta e cazul care distinge formula veche de cea noua (S2c).
|
||||
* PAS 4: crestere cantitate returnata la -20 (magnitudine 20) -> peste plafonul recalculat (15) ->
|
||||
* RESPINSA cu mesajul "Nu se poate returna mai mult decat a fost facturat!"; iesire din
|
||||
* dialog prin do_renunt() (nu do_termin(), care nu elibereaza formularul la respingere).
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
SET DELETED ON
|
||||
SET EXACT ON
|
||||
SET CENTURY ON
|
||||
SET DATE DMY
|
||||
SET DECIMALS TO 4
|
||||
SET NULLDISPLAY TO ''
|
||||
CLOSE DATABASES
|
||||
|
||||
PUBLIC gcUILog, gcSyncDir
|
||||
gcUILog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\test_pret_cu_tva_nivel2_retur_log.txt"
|
||||
gcSyncDir = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\uisync_nivel2_retur\"
|
||||
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
|
||||
|
||||
ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
ON SHUTDOWN QUIT
|
||||
|
||||
TRY
|
||||
LOCAL gcAppPath, lcPath
|
||||
gcAppPath = "D:\ROA\ROAFACTURARE\"
|
||||
SET DEFAULT TO (gcAppPath)
|
||||
|
||||
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
|
||||
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
|
||||
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
|
||||
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
|
||||
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\CALENDAR;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EMAIL;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\NFJSON;' + gcAppPath + 'COMUN\UTILE\NFXML;' + ;
|
||||
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
|
||||
SET PATH TO &lcPath ADDITIVE
|
||||
DO AfLog WITH 'SET PATH OK'
|
||||
|
||||
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
|
||||
SET CLASSLIB TO registry ADDITIVE
|
||||
SET CLASSLIB TO cauta_alfa_forms ADDITIVE
|
||||
SET CLASSLIB TO ofacturare.vcx ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_comun.vcx ADDITIVE
|
||||
SET CLASSLIB TO accessibility.vcx ADDITIVE
|
||||
SET CLASSLIB TO ocriterii.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_statusbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO DECABAZA ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare2 ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_rapoarte ADDITIVE
|
||||
SET CLASSLIB TO orapoarte ADDITIVE
|
||||
SET CLASSLIB TO ferestre_oracle ADDITIVE
|
||||
SET CLASSLIB TO messagebox ADDITIVE
|
||||
SET CLASSLIB TO otoolbar ADDITIVE
|
||||
SET CLASSLIB TO onom_curs ADDITIVE
|
||||
SET CLASSLIB TO comun ADDITIVE
|
||||
SET CLASSLIB TO ferestre_cere_date ADDITIVE
|
||||
SET CLASSLIB TO baza ADDITIVE
|
||||
SET CLASSLIB TO caut ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri ADDITIVE
|
||||
SET CLASSLIB TO serii_numere ADDITIVE
|
||||
SET CLASSLIB TO caut_ora ADDITIVE
|
||||
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
|
||||
SET CLASSLIB TO _calendar.vcx ADDITIVE
|
||||
SET CLASSLIB TO locale ADDITIVE
|
||||
SET CLASSLIB TO overificari ADDITIVE
|
||||
SET CLASSLIB TO ocomenzi ADDITIVE
|
||||
DO AfLog WITH 'SET CLASSLIB OK'
|
||||
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg"
|
||||
SET PROCEDURE TO proceduri_comune ADDITIVE
|
||||
SET PROCEDURE TO quitapp ADDITIVE
|
||||
SET PROCEDURE TO init_program ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare.prg ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare2.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_rapoarte_fact.prg ADDITIVE
|
||||
SET PROCEDURE TO email.prg ADDITIVE
|
||||
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
|
||||
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
|
||||
SET PROCEDURE TO updateserver.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
|
||||
SET PROCEDURE TO ocautare ADDITIVE
|
||||
SET PROCEDURE TO odocumente ADDITIVE
|
||||
SET PROCEDURE TO osecurity ADDITIVE
|
||||
SET PROCEDURE TO acces_meniu ADDITIVE
|
||||
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO ini.prg ADDITIVE
|
||||
SET PROCEDURE TO cauta_alfa.prg ADDITIVE
|
||||
SET PROCEDURE TO oHeader.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_curs.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare.prg ADDITIVE
|
||||
SET PROCEDURE TO oserii_numere.prg ADDITIVE
|
||||
SET PROCEDURE TO wwutils.prg ADDITIVE
|
||||
SET PROCEDURE TO wwConfig.prg ADDITIVE
|
||||
SET PROCEDURE TO wwApi.prg ADDITIVE
|
||||
SET PROCEDURE TO oexport.prg ADDITIVE
|
||||
SET PROCEDURE TO validare.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_comun.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_stoc.prg ADDITIVE
|
||||
SET PROCEDURE TO pmenu.prg ADDITIVE
|
||||
SET PROCEDURE TO ointroduceri.prg ADDITIVE
|
||||
SET PROCEDURE TO ovariabile_globale.prg ADDITIVE
|
||||
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
|
||||
SET PROCEDURE TO filebringer.prg ADDITIVE
|
||||
SET PROCEDURE TO iniacces.prg ADDITIVE
|
||||
SET PROCEDURE TO oupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO procese.prg ADDITIVE
|
||||
SET PROCEDURE TO version.prg ADDITIVE
|
||||
SET PROCEDURE TO wwhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlaccess.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlparser.prg ADDITIVE
|
||||
SET PROCEDURE TO xdate.prg ADDITIVE
|
||||
SET PROCEDURE TO suma_in_vorbe.prg ADDITIVE
|
||||
SET PROCEDURE TO controllerecr ADDITIVE
|
||||
SET PROCEDURE TO regex.prg ADDITIVE
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
|
||||
DO AfLog WITH 'SET PROCEDURE OK'
|
||||
|
||||
PUBLIC gnPc, gnPVal, gnPcant, gnPPretV, gnScadereStoc, gnMemProcDisc, gl406, gcAcces
|
||||
PUBLIC gnModTotFact, gnRF_FACTURARE_FARA_STOC, gnPPret, gnPPretVal
|
||||
gnPc = 2
|
||||
gnPVal = 2
|
||||
gnPcant = 3
|
||||
gnPPretV = 4
|
||||
gnPPret = 4
|
||||
gnPPretVal = 4
|
||||
gnScadereStoc = 0
|
||||
gnMemProcDisc = 0
|
||||
gl406 = .F.
|
||||
gcAcces = "1;2;3;4;5;6;7;8;"
|
||||
gnModTotFact = 0
|
||||
gnRF_FACTURARE_FARA_STOC = 0
|
||||
PUBLIC nror(65000)
|
||||
|
||||
PUBLIC goApp, goExport, goExecutor
|
||||
goApp = CREATEOBJECT('dummyapp')
|
||||
goExport = CREATEOBJECT('dummyexport')
|
||||
goExecutor = CREATEOBJECT('dummyexecutor')
|
||||
|
||||
IF USED('jtva_coloane')
|
||||
USE IN ('jtva_coloane')
|
||||
ENDIF
|
||||
CREATE CURSOR jtva_coloane (id_jtva_coloana N(14), denumire C(50), cota_tva N(6,2))
|
||||
INSERT INTO jtva_coloane VALUES (1, 'TVA 21%', 21)
|
||||
GO TOP IN jtva_coloane
|
||||
|
||||
IF USED('saft_taxtable')
|
||||
USE IN ('saft_taxtable')
|
||||
ENDIF
|
||||
CREATE CURSOR saft_taxtable (taxname C(250), procent_taxa N(7,2), taxcode N(6), tva_livrari N(1))
|
||||
INSERT INTO saft_taxtable VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%', 21, 301104, 1)
|
||||
|
||||
DO creeaza_facturacrs WITH 'crsfactura'
|
||||
DO AfLog WITH 'crsfactura creat, Reccount=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
*-- crsarticole: cantitate=10 reprezinta "cat s-a facturat / e disponibil de returnat".
|
||||
*-- gestionabil=0: verificarea de retur (:2265) nu are garda de gestionabil, deci ramane pe
|
||||
*-- calea simpla (frm_articol_factura direct), dar plafonul tot se verifica.
|
||||
IF USED('crsarticole')
|
||||
USE IN ('crsarticole')
|
||||
ENDIF
|
||||
CREATE CURSOR crsarticole (id_articol N(10), Id_Pol N(10), id_gestiune N(10), denumire C(100), ;
|
||||
codmat C(50), codbare C(50), gestionabil N(1), cantitate N(18,4), pret N(18,4), ;
|
||||
pret_val N(18,4), preturi_cu_tva N(1), proc_tvav N(18,4), discount_unitar N(18,4), ;
|
||||
discount_unitar_val N(18,4), pret_achizitie N(18,4), tip_valuta N(1), Curs N(18,4), ;
|
||||
multiplicator N(10,4), Cont C(10), um C(10), serie C(30), lot C(30), explicatie C(200), ;
|
||||
opt_facturare N(3), id_ctr N(10), numar_contract C(50), pretd N(18,4), id_valuta N(10), ;
|
||||
nume_val C(20), nume_lista_preturi C(100), id_jtva_coloana N(10), taxcode N(6), id_c N(10))
|
||||
INSERT INTO crsarticole (id_articol, Id_Pol, id_gestiune, denumire, codmat, codbare, ;
|
||||
gestionabil, cantitate, pret, pret_val, preturi_cu_tva, proc_tvav, discount_unitar, ;
|
||||
discount_unitar_val, pret_achizitie, tip_valuta, Curs, multiplicator, Cont, um, serie, ;
|
||||
lot, explicatie, opt_facturare, id_ctr, numar_contract, pretd, id_valuta, nume_val, ;
|
||||
nume_lista_preturi, id_jtva_coloana, taxcode, id_c) ;
|
||||
VALUES (3001, 1, 1, 'ARTICOL RETUR NIVEL2', 'ART3001', '', ;
|
||||
0, 10, 50, 0, 1, 1.21, 0, ;
|
||||
0, 0, 0, 1, 1, '707', 'BUC', '', ;
|
||||
'', '', 0, 0, '', 0, 0, '', ;
|
||||
'LISTA TEST', 1, 0, 3001)
|
||||
GO TOP IN crsarticole
|
||||
DO AfLog WITH 'crsarticole (retur) creat, Reccount=' + TRANSFORM(RECCOUNT('crsarticole'))
|
||||
|
||||
PRIVATE poDate
|
||||
poDate = CREATEOBJECT('oDateFactura')
|
||||
poDate.tip = 8 && 8 = factura retur lei
|
||||
poDate.serie_act = 'TST'
|
||||
poDate.nract = 1
|
||||
DO AfLog WITH 'poDate pregatit (oDateFactura), tip=' + TRANSFORM(poDate.tip)
|
||||
|
||||
PUBLIC goDriver, gnDriverTick, glDlgTratat, gcCazAct
|
||||
gnDriverTick = 0
|
||||
glDlgTratat = .F.
|
||||
gcCazAct = ''
|
||||
goDriver = CREATEOBJECT('driverdeblocare4')
|
||||
_SCREEN.AddObject('tmrDrvN2R', 'Timer')
|
||||
_SCREEN.tmrDrvN2R.Interval = 200
|
||||
BINDEVENT(_SCREEN.tmrDrvN2R, 'Timer', goDriver, 'Executa')
|
||||
_SCREEN.tmrDrvN2R.Enabled = .T.
|
||||
DO AfLog WITH 'driver+timer pregatiti'
|
||||
|
||||
_SCREEN.Visible = .T.
|
||||
_SCREEN.WindowState = 2
|
||||
_SCREEN.Caption = 'TEST UI Nivel 2 - ramura retur (S2c)'
|
||||
|
||||
PUBLIC goFrm
|
||||
goFrm = CREATEOBJECT('frm_facturare_articole')
|
||||
goFrm.WindowType = 0
|
||||
goFrm.Show()
|
||||
goFrm.WindowState = 2
|
||||
DOEVENTS FORCE
|
||||
DO AfLog WITH 'frm_facturare_articole afisat modeless, Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
DO HarnessStep WITH 0, 'formular afisat, grid gol'
|
||||
|
||||
*========================= PAS 0: adaugare linie retur (cantitate default, neschimbata) =========
|
||||
SELECT crsarticole
|
||||
GO TOP
|
||||
gcCazAct = 'ADD_DEFAULT'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_urmator1.Click()
|
||||
DOEVENTS FORCE
|
||||
LOCAL lnWait
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_urmator1: glDlgTratat=' + TRANSFORM(glDlgTratat) + ' Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
SELECT crsarticole
|
||||
LOCATE FOR id_c = 3001
|
||||
IF ABS(crsfactura.cantitate - (-10)) < 0.001 AND ABS(crsarticole.cantitate - 0) < 0.001
|
||||
DO UILog WITH 'PASS P0 adaugare retur: crsfactura.cantitate=' + TRANSFORM(crsfactura.cantitate) + ' crsarticole.cantitate=' + TRANSFORM(crsarticole.cantitate) + ' (asteptat -10 / 0)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P0 adaugare retur: crsfactura.cantitate=' + TRANSFORM(crsfactura.cantitate) + ' crsarticole.cantitate=' + TRANSFORM(crsarticole.cantitate) + ' (asteptat -10 / 0)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P0: Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) + ' (asteptat 1) - articolul retur nu a fost adaugat'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 1, 'P0 adaugare retur: Reccount=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
*========================= PAS 1: modificare DOAR de pret, cantitate neschimbata -> ACCEPTATA ===
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
gcCazAct = 'RETUR_DOAR_PRET'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_modifica1 (P1): glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
IF ABS(cantitate - (-10)) < 0.001 AND ABS(pretftva - 77) < 0.01
|
||||
DO UILog WITH 'PASS P1 retur - doar pret modificat, ACCEPTAT: cantitate=' + TRANSFORM(cantitate) + ' pretftva=' + TRANSFORM(pretftva) + ' (asteptat -10 / 77)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P1 retur - doar pret: cantitate=' + TRANSFORM(cantitate) + ' pretftva=' + TRANSFORM(pretftva) + ' (asteptat -10 / 77 - verifica daca a fost respins pe nedrept)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P1: nu exista randul'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 2, 'P1 retur doar pret'
|
||||
|
||||
*========================= PAS 2: simulare schimbare externa a stocului sursa =========
|
||||
SELECT crsarticole
|
||||
LOCATE FOR id_c = 3001
|
||||
IF FOUND()
|
||||
REPLACE cantitate WITH 5
|
||||
DO AfLog WITH 'P2: crsarticole.cantitate setat manual la 5 (simuleaza schimbare externa a stocului sursa, NU populare de crsfactura)'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 3, 'P2 stoc extern schimbat'
|
||||
|
||||
*========================= PAS 3: crestere la -12 (in limita plafonului RECALCULAT=15, dar peste
|
||||
*========================= plafonul VECHI fixat la 10) -> trebuie ACCEPTATA =========
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
gcCazAct = 'RETUR_CRESTERE_IN_PLAFON_NOU'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_modifica1 (P3): glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
IF ABS(cantitate - (-12)) < 0.001
|
||||
DO UILog WITH 'PASS P3 retur - crestere la magnitudine 12 (peste plafonul VECHI=10, in plafonul NOU recalculat=15), ACCEPTATA: cantitate=' + TRANSFORM(cantitate) + ' - confirma ca S2c chiar RECALCULEAZA plafonul, nu il fixeaza la cantitatea initiala a liniei'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P3 retur - crestere in plafonul nou: cantitate=' + TRANSFORM(cantitate) + ' (asteptat -12) - fie a fost respinsa (plafon nerecalculat), fie alta problema'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P3: nu exista randul'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 4, 'P3 retur crestere in plafon nou'
|
||||
|
||||
*========================= PAS 4: crestere la -20 (peste plafonul NOU=15) -> RESPINSA =========
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
LOCAL lnCantitateInainte
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
lnCantitateInainte = cantitate
|
||||
|
||||
gcCazAct = 'RETUR_CRESTERE_PESTE_PLAFON'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa But_modifica1 (P4): glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
IF ABS(cantitate - lnCantitateInainte) < 0.001
|
||||
DO UILog WITH 'PASS P4 retur - crestere la magnitudine 20 (peste plafonul nou=15) RESPINSA: randul a ramas neschimbat, cantitate=' + TRANSFORM(cantitate)
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P4 retur - crestere peste plafon: cantitate=' + TRANSFORM(cantitate) + ' (asteptat neschimbat, ' + TRANSFORM(lnCantitateInainte) + ') - a fost acceptata desi trebuia respinsa'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P4: nu exista randul'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 5, 'P4 retur peste plafon - final'
|
||||
|
||||
DO HarnessDone WITH 'done'
|
||||
|
||||
CATCH TO loExc
|
||||
DO AfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
|
||||
DO HarnessDone WITH 'done-error'
|
||||
ENDTRY
|
||||
|
||||
QUIT
|
||||
|
||||
*==================================================================================
|
||||
PROCEDURE AfErr
|
||||
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
|
||||
DO AfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE AfLog
|
||||
LPARAMETERS tcMsg
|
||||
SET SAFETY OFF
|
||||
LOCAL lcL
|
||||
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
|
||||
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE UILog
|
||||
LPARAMETERS tcMsg
|
||||
DO AfLog WITH tcMsg
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE FindCtl
|
||||
LPARAMETERS toParent, tcName
|
||||
LOCAL lnI, loGasit
|
||||
loGasit = .NULL.
|
||||
FOR lnI = 1 TO toParent.ControlCount
|
||||
IF UPPER(toParent.Controls(lnI).Name) == UPPER(tcName)
|
||||
loGasit = toParent.Controls(lnI)
|
||||
ENDIF
|
||||
ENDFOR
|
||||
RETURN loGasit
|
||||
ENDPROC
|
||||
|
||||
DEFINE CLASS dummyapp AS Custom
|
||||
PROCEDURE ReadIni
|
||||
LPARAMETERS tcSection, tcKey
|
||||
RETURN ''
|
||||
ENDPROC
|
||||
PROCEDURE WriteIni
|
||||
LPARAMETERS tcSection, tcKey, tcValue
|
||||
RETURN .T.
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS dummyexport AS Custom
|
||||
PROCEDURE citesteSetareRegistru
|
||||
LPARAMETERS tcCheie
|
||||
RETURN ''
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS dummyexecutor AS Custom
|
||||
cEroare = ''
|
||||
PROCEDURE oExecute
|
||||
LPARAMETERS tcSql, tcCursor
|
||||
IF USED(tcCursor)
|
||||
USE IN (tcCursor)
|
||||
ENDIF
|
||||
CREATE CURSOR (tcCursor) (codmatf C(50))
|
||||
RETURN 1
|
||||
ENDPROC
|
||||
PROCEDURE oReset
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS driverdeblocare4 AS Custom
|
||||
PROCEDURE Executa
|
||||
LOCAL lnI, loForm, llGasit
|
||||
gnDriverTick = gnDriverTick + 1
|
||||
llGasit = .F.
|
||||
FOR lnI = 1 TO _SCREEN.FormCount
|
||||
IF UPPER(_SCREEN.Forms(lnI).Class) == 'FRM_ARTICOL_FACTURA'
|
||||
loForm = _SCREEN.Forms(lnI)
|
||||
llGasit = .T.
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
IF glDlgTratat OR !llGasit
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
DO AfLog WITH 'driver4 tick ' + TRANSFORM(gnDriverTick) + ' POTRIVIT (caz=' + gcCazAct + '), intru in interactiune'
|
||||
|
||||
LOCAL loCantitateCtn, loCantitate, loPretFtvaCtn, loPretFtvaNat, loRenunt
|
||||
|
||||
TRY
|
||||
DO CASE
|
||||
CASE gcCazAct == 'ADD_DEFAULT'
|
||||
DO AfLog WITH 'driver4 ADD_DEFAULT: nu ating nimic, apas do_termin() (accepta valorile implicite)'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'RETUR_DOAR_PRET'
|
||||
loPretFtvaCtn = FindCtl(loForm, 'Clb_pretftva')
|
||||
loPretFtvaNat = FindCtl(loPretFtvaCtn, 'tx_suma_nat')
|
||||
loPretFtvaNat.Value = 77
|
||||
loPretFtvaNat.InteractiveChange()
|
||||
DO AfLog WITH 'driver4 RETUR_DOAR_PRET: pretftva=77, cantitate neatinsa, apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'RETUR_CRESTERE_IN_PLAFON_NOU'
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = -12
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driver4 RETUR_CRESTERE_IN_PLAFON_NOU: cantitate=-12, apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'RETUR_CRESTERE_PESTE_PLAFON'
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = -20
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driver4 RETUR_CRESTERE_PESTE_PLAFON: cantitate=-20, apas do_termin() (asteptat: respins, ramane deschis)'
|
||||
loForm.do_termin()
|
||||
DO AfLog WITH 'driver4: dupa do_termin() pe cazul de respingere - inchid explicit prin do_renunt() ca sa nu ramana Show(1) blocat'
|
||||
loForm.do_renunt()
|
||||
|
||||
OTHERWISE
|
||||
DO AfLog WITH 'driver4: gcCazAct necunoscut [' + gcCazAct + ']'
|
||||
ENDCASE
|
||||
|
||||
glDlgTratat = .T.
|
||||
DO AfLog WITH 'driver4: interactiune REUSITA pentru caz=' + gcCazAct
|
||||
CATCH TO loExcDrv
|
||||
DO AfLog WITH 'driver4: CATCH caz=' + gcCazAct + ' ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ;
|
||||
' Message=' + loExcDrv.Message + ' Procedure=' + loExcDrv.Procedure + ;
|
||||
' LineNo=' + TRANSFORM(loExcDrv.LineNo) + ' LineContents=[' + loExcDrv.LineContents + ']'
|
||||
ENDTRY
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
@@ -0,0 +1,12 @@
|
||||
# test_pret_cu_tva_nivel2_retur.ps1 - wrapper peste harness-ul generic pentru ramura de retur
|
||||
# a plafonului recalculat (S2c, rec_s2c_ncantitatemax.md). Rulare:
|
||||
# powershell -ExecutionPolicy Bypass -File test_pret_cu_tva_nivel2_retur.ps1
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Teste = $PSScriptRoot
|
||||
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
|
||||
-TestPrg (Join-Path $Teste 'test_pret_cu_tva_nivel2_retur.prg') `
|
||||
-Steps @('formular_afisat', 'p0_adaugare', 'p1_doar_pret', 'p2_stoc_extern', 'p3_in_plafon_nou', 'p4_peste_plafon') `
|
||||
-ShotsDir (Join-Path $Teste 'screenshots_nivel2_retur') `
|
||||
-SyncDir (Join-Path $Teste 'uisync_nivel2_retur') `
|
||||
-StepTimeoutSec 60 `
|
||||
-ReadyTimeoutSec 90
|
||||
@@ -0,0 +1,940 @@
|
||||
* test_pret_cu_tva_nivel3_gestiuni.prg
|
||||
* Test UI Nivel 3 (S2d, plan #7) pentru ramura GESTIONABILA a lui do_modifica/do_adauga_articol -
|
||||
* dialogul frm_articol_gest_factura, deschis prin do_alege_stoc (frm_facturare_articole,
|
||||
* ofacturare.vc2). Decizia coordonatorului: se mockuieste Oracle la GRANITA (goExecutor.oExecute,
|
||||
* singurul punct de contact al lui do_alege_stoc cu Oracle), NU se populeaza direct crsgestarticol/
|
||||
* crsfactura - fluxul real (butoane, taste, SPACE) ramane intact, doar sursa de date se inlocuieste.
|
||||
*
|
||||
* Articol 3001, gestionabil=1, gnScadereStoc=1, poDate.tip=4 (aviz - in Inlist-ul validat de
|
||||
* inainte_de_do_termin SI de plafonul S2c/S2d). 4 gestiuni mock, stoc constant (10/15/8/6) - Oracle
|
||||
* nu stie de cosul in lucru, exact ca in productie; scaderea celor deja pe factura o face codul
|
||||
* real (sub-selectul cu excluderea id_temp, S2d pct. 1).
|
||||
*
|
||||
* Cazuri (litere din review-ul S2d):
|
||||
* PAS 1 (caz a): adaugare linie1 din gestiunea G1 -> dialogul cu gestiuni arata mai multe
|
||||
* gestiuni (nu auto-select), ck_pret_cu_tva exista si e la Top=510 pe forma Height=546.
|
||||
* PAS 2: adaugare linie2 (acelasi articol) din gestiunea G2 - pregateste discriminantul de la c.
|
||||
* PAS 3 (cazuri b+c): redeschide linia1 -> crsgestarticol pozitionat pe gestiunea G1 a liniei;
|
||||
* randul G1 arata stocul disponibil PLUS cantitatea proprie (10, nu 7); randul G2 (linia2,
|
||||
* neexclusa) arata stocul scazut normal (11, nu 15). Inchis cu Renunta, nimic comis.
|
||||
* PAS 4 (caz d, respins): redeschide linia1, cere cantitate 11 (peste stocul gestiunii G1=10) ->
|
||||
* respins cu mesajul real "Cantitatea nu poate fi mai mare decat stocul gestiunii ...".
|
||||
* PAS 5 (caz d, acceptat): redeschide linia1, cere cantitate 10 (exact stocul gestiunii) ->
|
||||
* acceptat.
|
||||
* PAS 6 (caz e): redeschide linia1, navigheaza (fara SPACE) pe gestiunea G3, cantitate 5 ->
|
||||
* acceptat, linia1 trece pe G3. Verifica si g) crsarticole ajustat cu diferenta (-5).
|
||||
* PAS 7 (caz f+g): redeschide linia1, SPACE pe G1 si G4 (multi-selectie) -> linia1 devine G1/10,
|
||||
* apare O SINGURA linie noua G4/6 (exact regresia Scan/Skip, deja corectata) - Reccount
|
||||
* creste cu 1, nu cu 2. Verifica si crsarticole ajustat cu diferenta (delta 16-5=11).
|
||||
* PAS 8 (caz h): redeschide linia1, schimba pretul, apasa Renunta -> randul ramane BIT-IDENTIC.
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
SET DELETED ON
|
||||
SET EXACT ON
|
||||
SET CENTURY ON
|
||||
SET DATE DMY
|
||||
SET DECIMALS TO 4
|
||||
SET NULLDISPLAY TO ''
|
||||
CLOSE DATABASES
|
||||
|
||||
PUBLIC gcUILog, gcSyncDir
|
||||
gcUILog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\test_pret_cu_tva_nivel3_gestiuni_log.txt"
|
||||
gcSyncDir = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\uisync_nivel3\"
|
||||
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)
|
||||
|
||||
ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
ON SHUTDOWN QUIT
|
||||
|
||||
TRY
|
||||
LOCAL gcAppPath, lcPath
|
||||
gcAppPath = "D:\ROA\ROAFACTURARE\"
|
||||
SET DEFAULT TO (gcAppPath)
|
||||
|
||||
lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
|
||||
gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
|
||||
gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
|
||||
gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
|
||||
gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\CALENDAR;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EMAIL;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\NFJSON;' + gcAppPath + 'COMUN\UTILE\NFXML;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\GridExtras;' + ;
|
||||
ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
|
||||
SET PATH TO &lcPath ADDITIVE
|
||||
DO AfLog WITH 'SET PATH OK'
|
||||
|
||||
*----- CLASE (lista dovedita de Nivel 1/2 - mediul unei suite noi se mosteneste din suita
|
||||
* care TRECE, nu dintr-un smoke-test) -----
|
||||
SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
|
||||
SET CLASSLIB TO registry ADDITIVE
|
||||
SET CLASSLIB TO cauta_alfa_forms ADDITIVE
|
||||
SET CLASSLIB TO ofacturare.vcx ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_comun.vcx ADDITIVE
|
||||
SET CLASSLIB TO accessibility.vcx ADDITIVE
|
||||
SET CLASSLIB TO ocriterii.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_statusbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_common.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
|
||||
SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
|
||||
SET CLASSLIB TO DECABAZA ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare2 ADDITIVE
|
||||
SET CLASSLIB TO ofacturare_rapoarte ADDITIVE
|
||||
SET CLASSLIB TO orapoarte ADDITIVE
|
||||
SET CLASSLIB TO ferestre_oracle ADDITIVE
|
||||
SET CLASSLIB TO messagebox ADDITIVE
|
||||
SET CLASSLIB TO otoolbar ADDITIVE
|
||||
SET CLASSLIB TO onom_curs ADDITIVE
|
||||
SET CLASSLIB TO comun ADDITIVE
|
||||
SET CLASSLIB TO ferestre_cere_date ADDITIVE
|
||||
SET CLASSLIB TO baza ADDITIVE
|
||||
SET CLASSLIB TO caut ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri ADDITIVE
|
||||
SET CLASSLIB TO serii_numere ADDITIVE
|
||||
SET CLASSLIB TO caut_ora ADDITIVE
|
||||
SET CLASSLIB TO wwdialogs.vcx ADDITIVE
|
||||
SET CLASSLIB TO _calendar.vcx ADDITIVE
|
||||
SET CLASSLIB TO locale ADDITIVE
|
||||
SET CLASSLIB TO overificari ADDITIVE
|
||||
SET CLASSLIB TO ocomenzi ADDITIVE
|
||||
DO AfLog WITH 'SET CLASSLIB OK'
|
||||
|
||||
*----- PROCEDURI (mock amessagebox PRIMUL, ui_harness la final) -----
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg"
|
||||
SET PROCEDURE TO proceduri_comune ADDITIVE
|
||||
SET PROCEDURE TO quitapp ADDITIVE
|
||||
SET PROCEDURE TO init_program ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare.prg ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare2.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_rapoarte_fact.prg ADDITIVE
|
||||
SET PROCEDURE TO email.prg ADDITIVE
|
||||
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
|
||||
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
|
||||
SET PROCEDURE TO updateserver.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
|
||||
SET PROCEDURE TO ocautare ADDITIVE
|
||||
SET PROCEDURE TO odocumente ADDITIVE
|
||||
SET PROCEDURE TO osecurity ADDITIVE
|
||||
SET PROCEDURE TO acces_meniu ADDITIVE
|
||||
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO ini.prg ADDITIVE
|
||||
SET PROCEDURE TO cauta_alfa.prg ADDITIVE
|
||||
SET PROCEDURE TO oHeader.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_curs.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare.prg ADDITIVE
|
||||
SET PROCEDURE TO oserii_numere.prg ADDITIVE
|
||||
SET PROCEDURE TO wwutils.prg ADDITIVE
|
||||
SET PROCEDURE TO wwConfig.prg ADDITIVE
|
||||
SET PROCEDURE TO wwApi.prg ADDITIVE
|
||||
SET PROCEDURE TO oexport.prg ADDITIVE
|
||||
SET PROCEDURE TO validare.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_comun.prg ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_stoc.prg ADDITIVE
|
||||
SET PROCEDURE TO pmenu.prg ADDITIVE
|
||||
SET PROCEDURE TO ointroduceri.prg ADDITIVE
|
||||
SET PROCEDURE TO ovariabile_globale.prg ADDITIVE
|
||||
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
|
||||
SET PROCEDURE TO filebringer.prg ADDITIVE
|
||||
SET PROCEDURE TO iniacces.prg ADDITIVE
|
||||
SET PROCEDURE TO oupdate.prg ADDITIVE
|
||||
SET PROCEDURE TO procese.prg ADDITIVE
|
||||
SET PROCEDURE TO version.prg ADDITIVE
|
||||
SET PROCEDURE TO wwhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlaccess.prg ADDITIVE
|
||||
SET PROCEDURE TO xmlparser.prg ADDITIVE
|
||||
SET PROCEDURE TO xdate.prg ADDITIVE
|
||||
SET PROCEDURE TO suma_in_vorbe.prg ADDITIVE
|
||||
SET PROCEDURE TO controllerecr ADDITIVE
|
||||
SET PROCEDURE TO regex.prg ADDITIVE
|
||||
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
|
||||
DO AfLog WITH 'SET PROCEDURE OK'
|
||||
|
||||
*----- Globale aplicatie -----
|
||||
PUBLIC gnPc, gnPVal, gnPcant, gnPPretV, gnScadereStoc, gnMemProcDisc, gl406, gcAcces
|
||||
PUBLIC gnModTotFact, gnRF_FACTURARE_FARA_STOC
|
||||
gnModTotFact = 0
|
||||
gnRF_FACTURARE_FARA_STOC = 0
|
||||
PUBLIC gnPPret, gnPPretVal
|
||||
gnPc = 2
|
||||
gnPVal = 2
|
||||
gnPcant = 3
|
||||
gnPPretV = 4
|
||||
gnPPret = 4
|
||||
gnPPretVal = 4
|
||||
gnScadereStoc = 1 && activeaza ramura de stoc - do_alege_stoc SE apeleaza (opusul Nivel 2)
|
||||
gnMemProcDisc = 0
|
||||
gl406 = .F.
|
||||
gcAcces = "1;2;3;4;5;6;7;8;"
|
||||
*-- do_alege_stoc citeste si aceste globale (parametri SQL cursor_gestiuni_articol) - lipsa lor
|
||||
*-- da ON ERROR 12 "Variable not found" la primul apel
|
||||
PUBLIC gnAn, gnLuna, gnIdUtil, gnIdSucursala
|
||||
gnAn = YEAR(DATE())
|
||||
gnLuna = MONTH(DATE())
|
||||
gnIdUtil = 1
|
||||
gnIdSucursala = 0
|
||||
PUBLIC nror(65000)
|
||||
|
||||
*-- gcMockUltimMesaj: mock_amessagebox.prg memoreaza aici ultimul mesaj afisat - folosit pt.
|
||||
*-- asertia pe TEXTUL respingerii de plafon (caz d).
|
||||
PUBLIC gcMockUltimMesaj, gnMockUltimTip
|
||||
gcMockUltimMesaj = ''
|
||||
gnMockUltimTip = 0
|
||||
|
||||
PUBLIC goApp, goExport, goExecutor
|
||||
goApp = CREATEOBJECT('dummyapp')
|
||||
goExport = CREATEOBJECT('dummyexport')
|
||||
goExecutor = CREATEOBJECT('dummyexecutor')
|
||||
|
||||
IF USED('jtva_coloane')
|
||||
USE IN ('jtva_coloane')
|
||||
ENDIF
|
||||
CREATE CURSOR jtva_coloane (id_jtva_coloana N(14), denumire C(50), cota_tva N(6,2))
|
||||
INSERT INTO jtva_coloane VALUES (1, 'TVA 21%', 21)
|
||||
INSERT INTO jtva_coloane VALUES (2, 'TVA 11%', 11)
|
||||
GO TOP IN jtva_coloane
|
||||
|
||||
IF USED('saft_taxtable')
|
||||
USE IN ('saft_taxtable')
|
||||
ENDIF
|
||||
CREATE CURSOR saft_taxtable (taxname C(250), procent_taxa N(7,2), taxcode N(6), tva_livrari N(1))
|
||||
INSERT INTO saft_taxtable VALUES ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%', 21, 301104, 1)
|
||||
INSERT INTO saft_taxtable VALUES ('3011XX-Achizitii de bunuri si servicii taxabile cu cota de 11%', 11, 301108, 1)
|
||||
|
||||
*----- crsfactura: structura REALA, fara Oracle -----
|
||||
DO creeaza_facturacrs WITH 'crsfactura'
|
||||
DO AfLog WITH 'crsfactura creat, Reccount=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
*----- crsarticole: sursa (stoc/lista de preturi). Articolul 3001, gestionabil=1, cantitate mare
|
||||
* (plafonul S2c/S2d ramane generos - testele de mai jos verifica plafonul PE LOT din
|
||||
* dialogul de gestiuni, nu plafonul pe articol din crsarticole). -----
|
||||
IF USED('crsarticole')
|
||||
USE IN ('crsarticole')
|
||||
ENDIF
|
||||
CREATE CURSOR crsarticole (id_articol N(10), Id_Pol N(10), id_gestiune N(10), denumire C(100), ;
|
||||
codmat C(50), codbare C(50), gestionabil N(1), cantitate N(18,4), pret N(18,4), ;
|
||||
pret_val N(18,4), preturi_cu_tva N(1), proc_tvav N(18,4), discount_unitar N(18,4), ;
|
||||
discount_unitar_val N(18,4), pret_achizitie N(18,4), tip_valuta N(1), Curs N(18,4), ;
|
||||
multiplicator N(10,4), Cont C(10), um C(10), serie C(30), lot C(30), explicatie C(200), ;
|
||||
opt_facturare N(3), id_ctr N(10), numar_contract C(50), pretd N(18,4), id_valuta N(10), ;
|
||||
nume_val C(20), nume_lista_preturi C(100), id_jtva_coloana N(10), taxcode N(6), id_c N(10))
|
||||
INSERT INTO crsarticole (id_articol, Id_Pol, id_gestiune, denumire, codmat, codbare, ;
|
||||
gestionabil, cantitate, pret, pret_val, preturi_cu_tva, proc_tvav, discount_unitar, ;
|
||||
discount_unitar_val, pret_achizitie, tip_valuta, Curs, multiplicator, Cont, um, serie, ;
|
||||
lot, explicatie, opt_facturare, id_ctr, numar_contract, pretd, id_valuta, nume_val, ;
|
||||
nume_lista_preturi, id_jtva_coloana, taxcode, id_c) ;
|
||||
VALUES (3001, 1, 0, 'ARTICOL GESTIUNI NIVEL3', 'ART3001', '', ;
|
||||
1, 1000, 50, 0, 0, 1.21, 0, ;
|
||||
0, 0, 0, 1, 1, '701', 'BUC', '', ;
|
||||
'', '', 0, 0, '', 0, 0, '', ;
|
||||
'LISTA TEST', 1, 0, 3001)
|
||||
GO TOP IN crsarticole
|
||||
DO AfLog WITH 'crsarticole creat, Reccount=' + TRANSFORM(RECCOUNT('crsarticole'))
|
||||
|
||||
*----- crsMockStoc: gestiunile "Oracle" pentru articolul 3001, stoc FIX pe tot testul - Oracle
|
||||
* nu stie de cosul in lucru; scaderea celor deja pe factura o face codul real (LEFT JOIN +
|
||||
* excluderea id_temp, S2d pct. 1), nu mock-ul. dummyexecutor.oExecute o serveste la fiecare
|
||||
* apel cu 'cursor_gestiuni_articol' in SQL. Coloanele sunt exact cele citite de do_alege_stoc
|
||||
* (Insert Into (lcCursor) (...), ofacturare.vc2:13299, si copiaza_structura_cursor). -----
|
||||
IF USED('crsMockStoc')
|
||||
USE IN ('crsMockStoc')
|
||||
ENDIF
|
||||
*-- Cont/serie/lot cu ACEEASI latime ca in crsfactura (creeaza_facturacrs: Cont c(4), serie c(100),
|
||||
*-- lot C(20)) - LEFT JOIN-ul din do_alege_stoc compara aceste campuri intre cele doua cursoare
|
||||
*-- (:13304-13306); latimi diferite ar produce padding diferit si ar rupe egalitatea sub SET EXACT ON.
|
||||
*-- datain e DateTime (T), nu Date: coloana cDataIn a gridului are ControlSource "TTOD(datain)"
|
||||
*-- (ofacturare.vc2:3519), iar TTOD pe un camp D da eroarea 11 la constructia formularului.
|
||||
CREATE CURSOR crsMockStoc (ales N(1), id_gestiune N(10), cantitate N(18,4), Cont C(4), ;
|
||||
serie C(100), lot C(20), Pret N(18,4), nume_gestiune C(50), datain T, pretv N(18,4), ;
|
||||
pretvctva N(18,4), part_rez C(30), id_part_rez N(10), nrord_rez N(10), id_lucrare_rez N(10), ;
|
||||
pretd N(18,4), id_valuta N(10), nume_val C(20))
|
||||
INSERT INTO crsMockStoc VALUES (0, 101, 10, '701', 'SG1', 'LOT1', 50, 'GESTIUNE 1', {^2020-01-01 08:00:00}, 50, 60.50, '', 0, 0, 0, 0, 0, '')
|
||||
INSERT INTO crsMockStoc VALUES (0, 102, 15, '701', 'SG2', 'LOT2', 55, 'GESTIUNE 2', {^2020-01-02 08:00:00}, 55, 66.55, '', 0, 0, 0, 0, 0, '')
|
||||
INSERT INTO crsMockStoc VALUES (0, 103, 8, '701', 'SG3', 'LOT3', 52, 'GESTIUNE 3', {^2020-01-03 08:00:00}, 52, 62.92, '', 0, 0, 0, 0, 0, '')
|
||||
INSERT INTO crsMockStoc VALUES (0, 104, 6, '701', 'SG4', 'LOT4', 48, 'GESTIUNE 4', {^2020-01-04 08:00:00}, 48, 58.08, '', 0, 0, 0, 0, 0, '')
|
||||
GO TOP IN crsMockStoc
|
||||
DO AfLog WITH 'crsMockStoc creat (4 gestiuni, stoc 10/15/8/6), Reccount=' + TRANSFORM(RECCOUNT('crsMockStoc'))
|
||||
|
||||
*----- poDate: clasa REALA oDateFactura -----
|
||||
PRIVATE poDate
|
||||
poDate = CREATEOBJECT('oDateFactura')
|
||||
poDate.tip = 4 && 4 = aviz - in Inlist-ul validat de inainte_de_do_termin SI de plafonul S2c/S2d
|
||||
poDate.serie_act = 'TST'
|
||||
poDate.nract = 1
|
||||
DO AfLog WITH 'poDate pregatit (oDateFactura), tip=' + TRANSFORM(poDate.tip) + ' gnScadereStoc=' + TRANSFORM(gnScadereStoc)
|
||||
|
||||
*----- driverul de deblocare Show(1): Timer la nivel _SCREEN + _SCREEN.Forms + Controls(i),
|
||||
* mecanism validat (test_modal_unlock_smoketest2.prg / Nivel 2). De data asta cauta
|
||||
* FRM_ARTICOL_GEST_FACTURA, nu FRM_ARTICOL_FACTURA. -----
|
||||
PUBLIC goDriver, gnDriverTick, glDlgTratat, gcCazAct
|
||||
gnDriverTick = 0
|
||||
glDlgTratat = .F.
|
||||
gcCazAct = ''
|
||||
goDriver = CREATEOBJECT('driverdeblocaregest')
|
||||
_SCREEN.AddObject('tmrDrvN3', 'Timer')
|
||||
_SCREEN.tmrDrvN3.Interval = 200
|
||||
BINDEVENT(_SCREEN.tmrDrvN3, 'Timer', goDriver, 'Executa')
|
||||
_SCREEN.tmrDrvN3.Enabled = .T.
|
||||
DO AfLog WITH 'driver+timer pregatiti (cauta FRM_ARTICOL_GEST_FACTURA)'
|
||||
|
||||
*----- Desktop VFP vizibil, ca la celelalte suite UI -----
|
||||
_SCREEN.Visible = .T.
|
||||
_SCREEN.WindowState = 2
|
||||
_SCREEN.Caption = 'TEST UI Nivel 3 (S2d - ramura gestiuni)'
|
||||
|
||||
PUBLIC goFrm
|
||||
goFrm = CREATEOBJECT('frm_facturare_articole')
|
||||
goFrm.WindowType = 0 && testul instantiaza direct - modeless, Show() revine imediat
|
||||
goFrm.Show()
|
||||
goFrm.WindowState = 2
|
||||
DOEVENTS FORCE
|
||||
DO AfLog WITH 'frm_facturare_articole afisat modeless, Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
DO HarnessStep WITH 0, 'formular afisat, mediu pregatit'
|
||||
|
||||
*-- Local-e folosite pe tot parcursul --
|
||||
LOCAL lnWait, lnIdTempLinie1, lnIdTempLinie2, lnArtStocInainte, lnArtStocDupa
|
||||
|
||||
*========================= PAS 1 (caz a): adaugare linie1 din G1 =========================
|
||||
SELECT crsarticole
|
||||
GO TOP
|
||||
gcCazAct = 'ADD_G1_Q3'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_urmator1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa ADD_G1_Q3: glDlgTratat=' + TRANSFORM(glDlgTratat) + ' Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
IF RECCOUNT('crsfactura') = 1
|
||||
SELECT crsfactura
|
||||
GO TOP
|
||||
lnIdTempLinie1 = id_temp
|
||||
IF id_gestiune = 101 AND ABS(cantitate - 3) < 0.001
|
||||
DO UILog WITH 'PASS P1 (caz a) linia1 adaugata din G1: id_gestiune=' + TRANSFORM(id_gestiune) + ' cantitate=' + TRANSFORM(cantitate) + ' pret_achizitie=' + TRANSFORM(pret_achizitie)
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P1 (caz a) linia1: id_gestiune=' + TRANSFORM(id_gestiune) + ' cantitate=' + TRANSFORM(cantitate) + ' (asteptat id_gestiune=101 cantitate=3)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P1 (caz a): Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) + ' (asteptat 1) - linia1 nu a fost adaugata'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 1, 'P1 linia1 adaugata din G1'
|
||||
|
||||
*========================= PAS 2: adaugare linie2 (acelasi articol) din G2 =========================
|
||||
SELECT crsarticole
|
||||
GO TOP
|
||||
gcCazAct = 'ADD_G2_Q4'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_urmator1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa ADD_G2_Q4: glDlgTratat=' + TRANSFORM(glDlgTratat) + ' Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
IF RECCOUNT('crsfactura') = 2
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_gestiune = 102
|
||||
IF FOUND()
|
||||
lnIdTempLinie2 = id_temp
|
||||
IF ABS(cantitate - 4) < 0.001
|
||||
DO UILog WITH 'PASS P2 linia2 adaugata din G2: cantitate=' + TRANSFORM(cantitate)
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P2 linia2: cantitate=' + TRANSFORM(cantitate) + ' (asteptat 4)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P2: nu exista rand cu id_gestiune=102'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P2: Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) + ' (asteptat 2)'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 2, 'P2 linia2 adaugata din G2'
|
||||
|
||||
*========================= PAS 3 (cazuri b+c): redeschide linia1, verifica preselectia si
|
||||
*========================= excluderea id_temp, apoi Renunta (nimic comis) =========================
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
gcCazAct = 'MOD_L1_PRESELECT_CHECK'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa MOD_L1_PRESELECT_CHECK: glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
IF RECCOUNT('crsfactura') = 2 AND FOUND() AND id_gestiune = 101 AND ABS(cantitate - 3) < 0.001
|
||||
DO UILog WITH 'PASS P3 (caz b+c, Renunta) nimic comis: Reccount=2, linia1 neschimbata (G1/3)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P3 (caz b+c, Renunta): Reccount=' + TRANSFORM(RECCOUNT('crsfactura')) + ' found=' + TRANSFORM(FOUND()) + ' id_gestiune=' + TRANSFORM(id_gestiune) + ' cantitate=' + TRANSFORM(cantitate) + ' (asteptat 2 / 101 / 3)'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 3, 'P3 cazuri b+c - preselectie si excludere id_temp'
|
||||
|
||||
*========================= PAS 4 (caz d, respins): redeschide linia1, cere 11 (peste stocul G1=10) =========================
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
gcCazAct = 'MOD_L1_REJECT_OVER_LOT'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
gcMockUltimMesaj = ''
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa MOD_L1_REJECT_OVER_LOT: glDlgTratat=' + TRANSFORM(glDlgTratat) + ' mesaj=[' + gcMockUltimMesaj + ']'
|
||||
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
IF ABS(cantitate - 3) < 0.001 AND 'stocul gestiunii' $ gcMockUltimMesaj
|
||||
DO UILog WITH 'PASS P4 (caz d, respins) cantitate 11 peste stocul G1(10) respinsa, linia neschimbata (cantitate=' + TRANSFORM(cantitate) + '), mesaj=[' + gcMockUltimMesaj + ']'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P4 (caz d, respins): cantitate=' + TRANSFORM(cantitate) + ' (asteptat 3, neschimbata) mesaj=[' + gcMockUltimMesaj + ']'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 4, 'P4 caz d - respins peste plafonul lotului'
|
||||
|
||||
*========================= PAS 5 (caz d, acceptat): redeschide linia1, cere exact 10 =========================
|
||||
SELECT crsarticole
|
||||
lnArtStocInainte = cantitate
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
gcCazAct = 'MOD_L1_ACCEPT_AT_LOT'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa MOD_L1_ACCEPT_AT_LOT: glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
IF ABS(cantitate - 10) < 0.001 AND id_gestiune = 101
|
||||
DO UILog WITH 'PASS P5 (caz d, acceptat) cantitate 10 (exact stocul G1) acceptata: cantitate=' + TRANSFORM(cantitate)
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P5 (caz d, acceptat): cantitate=' + TRANSFORM(cantitate) + ' id_gestiune=' + TRANSFORM(id_gestiune) + ' (asteptat 10 / 101)'
|
||||
ENDIF
|
||||
*-- caz g: cantitatea liniei a crescut de la 3 la 10 (delta +7) -> crsarticole trebuie sa scada cu 7
|
||||
SELECT crsarticole
|
||||
lnArtStocDupa = cantitate
|
||||
IF ABS((lnArtStocInainte - lnArtStocDupa) - 7) < 0.001
|
||||
DO UILog WITH 'PASS P5 (caz g) crsarticole ajustat cu diferenta: ' + TRANSFORM(lnArtStocInainte) + ' -> ' + TRANSFORM(lnArtStocDupa) + ' (-7, cantitatea liniei a crescut 3->10)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P5 (caz g): crsarticole ' + TRANSFORM(lnArtStocInainte) + ' -> ' + TRANSFORM(lnArtStocDupa) + ' (asteptat -7)'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 5, 'P5 caz d - acceptat la exact plafonul lotului'
|
||||
|
||||
*========================= PAS 6 (caz e + g): navigheaza (fara SPACE) pe G3, cantitate 5 =========================
|
||||
*-- martorul se ia AICI: cel din PAS 5 masoara efectul lui PAS 5, nu al lui PAS 6
|
||||
SELECT crsarticole
|
||||
lnArtStocInainte = cantitate
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
gcCazAct = 'MOD_L1_CHANGE_GESTIUNE_NAV'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa MOD_L1_CHANGE_GESTIUNE_NAV: glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
SELECT crsarticole
|
||||
lnArtStocDupa = cantitate
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
IF id_gestiune = 103 AND ABS(cantitate - 5) < 0.001 AND ABS(pret_achizitie - 52) < 0.001
|
||||
DO UILog WITH 'PASS P6 (caz e) schimbare gestiune prin navigare (fara SPACE): id_gestiune=' + TRANSFORM(id_gestiune) + ' cantitate=' + TRANSFORM(cantitate) + ' pret_achizitie=' + TRANSFORM(pret_achizitie)
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P6 (caz e): id_gestiune=' + TRANSFORM(id_gestiune) + ' cantitate=' + TRANSFORM(cantitate) + ' pret_achizitie=' + TRANSFORM(pret_achizitie) + ' (asteptat 103 / 5 / 52)'
|
||||
ENDIF
|
||||
*-- caz g: cantitatea liniei a scazut de la 10 la 5 (delta -5) -> crsarticole trebuie sa creasca cu 5
|
||||
IF ABS((lnArtStocDupa - lnArtStocInainte) - 5) < 0.001
|
||||
DO UILog WITH 'PASS P6 (caz g) crsarticole ajustat cu diferenta: ' + TRANSFORM(lnArtStocInainte) + ' -> ' + TRANSFORM(lnArtStocDupa) + ' (+5, cantitatea liniei a scazut 10->5)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P6 (caz g): crsarticole ' + TRANSFORM(lnArtStocInainte) + ' -> ' + TRANSFORM(lnArtStocDupa) + ' (asteptat +5)'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 6, 'P6 caz e+g - schimbare gestiune prin navigare + sincronizare crsarticole'
|
||||
|
||||
*========================= PAS 7 (caz f + g): multi-selectie SPACE pe G1 si G4 =========================
|
||||
SELECT crsarticole
|
||||
lnArtStocInainte = cantitate
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
gcCazAct = 'MOD_L1_MULTISELECT'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa MOD_L1_MULTISELECT: glDlgTratat=' + TRANSFORM(glDlgTratat) + ' Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
|
||||
|
||||
SELECT crsarticole
|
||||
lnArtStocDupa = cantitate
|
||||
IF RECCOUNT('crsfactura') = 3
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
LOCAL llL1ok, llL2ok, llNouaOk
|
||||
llL1ok = (id_gestiune = 101 AND ABS(cantitate - 10) < 0.001)
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie2
|
||||
llL2ok = FOUND() AND id_gestiune = 102 AND ABS(cantitate - 4) < 0.001
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_gestiune = 104
|
||||
llNouaOk = FOUND() AND ABS(cantitate - 6) < 0.001 AND id_temp <> lnIdTempLinie1 AND id_temp <> lnIdTempLinie2
|
||||
IF llL1ok AND llL2ok AND llNouaOk
|
||||
DO UILog WITH 'PASS P7 (caz f) multi-selectie: Reccount=3 (linia1 actualizata G1/10, linia2 neschimbata G2/4, O SINGURA linie noua G4/6 - fara duplicat)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P7 (caz f): llL1ok=' + TRANSFORM(llL1ok) + ' llL2ok=' + TRANSFORM(llL2ok) + ' llNouaOk=' + TRANSFORM(llNouaOk)
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P7 (caz f): Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura')) + ' (asteptat 3 - daca e 4, a reaparut regresia Scan/Skip cu linie duplicat)'
|
||||
ENDIF
|
||||
*-- caz g: cantitatea totala a articolului pe factura a crescut de la 5+4=9 la 10+6+4=20, delta +11 -> crsarticole trebuie sa scada cu 11
|
||||
IF ABS((lnArtStocInainte - lnArtStocDupa) - 11) < 0.001
|
||||
DO UILog WITH 'PASS P7 (caz g) crsarticole ajustat cu diferenta: ' + TRANSFORM(lnArtStocInainte) + ' -> ' + TRANSFORM(lnArtStocDupa) + ' (-11, cantitatea totala a crescut de la 5 la 16 pe aceasta redeschidere)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P7 (caz g): crsarticole ' + TRANSFORM(lnArtStocInainte) + ' -> ' + TRANSFORM(lnArtStocDupa) + ' (asteptat -11)'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 7, 'P7 caz f+g - multi-selectie si sincronizare crsarticole'
|
||||
|
||||
*========================= PAS 8 (caz h): Renunta pe dialogul cu gestiuni - rand bit-identic =========================
|
||||
IF RECCOUNT('crsfactura') >= 1
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
IF FOUND()
|
||||
LOCAL ARRAY laSnapDinainte[1]
|
||||
LOCAL lnF, lnCampuri
|
||||
SCATTER TO laSnapDinainte
|
||||
|
||||
gcCazAct = 'MOD_L1_RENUNTA'
|
||||
glDlgTratat = .F.
|
||||
gnDriverTick = 0
|
||||
goFrm.But_modifica1.Click()
|
||||
DOEVENTS FORCE
|
||||
lnWait = 0
|
||||
DO WHILE !glDlgTratat AND lnWait < 150
|
||||
DOEVENTS FORCE
|
||||
lnWait = lnWait + 1
|
||||
ENDDO
|
||||
DO AfLog WITH 'dupa MOD_L1_RENUNTA: glDlgTratat=' + TRANSFORM(glDlgTratat)
|
||||
|
||||
LOCAL ARRAY laSnapDupa[1]
|
||||
SELECT crsfactura
|
||||
LOCATE FOR id_temp = lnIdTempLinie1
|
||||
SCATTER TO laSnapDupa
|
||||
|
||||
LOCAL llIdentic
|
||||
llIdentic = (ALEN(laSnapDinainte,1) == ALEN(laSnapDupa,1))
|
||||
lnCampuri = 0
|
||||
IF llIdentic
|
||||
FOR lnF = 1 TO ALEN(laSnapDinainte,1)
|
||||
lnCampuri = lnCampuri + 1
|
||||
IF !(TRANSFORM(laSnapDinainte(lnF)) == TRANSFORM(laSnapDupa(lnF)))
|
||||
llIdentic = .F.
|
||||
DO AfLog WITH 'P8 diagnostic - campul ' + TRANSFORM(lnF) + ' difera: [' + ;
|
||||
TRANSFORM(laSnapDinainte(lnF)) + '] -> [' + TRANSFORM(laSnapDupa(lnF)) + ']'
|
||||
ENDIF
|
||||
ENDFOR
|
||||
ENDIF
|
||||
|
||||
IF llIdentic
|
||||
DO UILog WITH 'PASS P8 (caz h) Renunta pe dialogul cu gestiuni: randul ramane BIT-IDENTIC (' + TRANSFORM(lnCampuri) + ' campuri comparate)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P8 (caz h): randul S-A MODIFICAT desi s-a apasat Renunta (vezi diag pe campuri mai sus)'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P8: linia1 (id_temp=' + TRANSFORM(lnIdTempLinie1) + ') nu mai exista'
|
||||
ENDIF
|
||||
ELSE
|
||||
DO UILog WITH 'NEACOPERIT P8: crsfactura gol'
|
||||
ENDIF
|
||||
DO HarnessStep WITH 8, 'P8 caz h - Renunta bit-identic'
|
||||
|
||||
DO HarnessDone WITH 'done'
|
||||
|
||||
CATCH TO loExc
|
||||
DO AfLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
|
||||
|
||||
*-- DIAGNOSTIC temporar: AERROR() suplimentar, stare crsgestarticol, si o proba izolata de
|
||||
*-- CREATEOBJECT("frm_articol_gest_factura",...) cu poArticol construit liber (ca Nivel 1) -
|
||||
*-- separa o cauza de MEDIU (clase/globale) de una legata de FORMA lui poArticol produs de
|
||||
*-- fluxul real (do_initializeaza_articol).
|
||||
LOCAL ARRAY laErrDiag(1)
|
||||
LOCAL lnEd
|
||||
=AERROR(laErrDiag)
|
||||
FOR lnEd = 1 TO ALEN(laErrDiag,1)
|
||||
DO AfLog WITH 'AERROR[' + TRANSFORM(lnEd) + ']=' + TRANSFORM(NVL(laErrDiag(lnEd),'.NULL.'))
|
||||
ENDFOR
|
||||
DO AfLog WITH 'DIAG: USED(crsgestarticol)=' + TRANSFORM(USED('crsgestarticol')) + IIF(USED('crsgestarticol'), ' Reccount=' + TRANSFORM(RECCOUNT('crsgestarticol')), '')
|
||||
|
||||
LOCAL lnPi, loProba
|
||||
LOCAL ARRAY laPPropN(49), laPPropC(11)
|
||||
laPPropN( 1)='id_articol'
|
||||
laPPropN( 2)='Id_Pol'
|
||||
laPPropN( 3)='id_gestiune'
|
||||
laPPropN( 4)='id_c'
|
||||
laPPropN( 5)='id_ctr'
|
||||
laPPropN( 6)='id_valuta'
|
||||
laPPropN( 7)='id_valuta_d'
|
||||
laPPropN( 8)='id_lucrare_rez'
|
||||
laPPropN( 9)='id_part_rez'
|
||||
laPPropN(10)='id_jtva_coloana'
|
||||
laPPropN(11)='taxcode'
|
||||
laPPropN(12)='opt_facturare'
|
||||
laPPropN(13)='gestionabil'
|
||||
laPPropN(14)='tip_valuta'
|
||||
laPPropN(15)='cantitate'
|
||||
laPPropN(16)='Curs'
|
||||
laPPropN(17)='multiplicator'
|
||||
laPPropN(18)='pret_achizitie'
|
||||
laPPropN(19)='pretv_orig'
|
||||
laPPropN(20)='pretd'
|
||||
laPPropN(21)='proc_tvav'
|
||||
laPPropN(22)='preturi_cu_tva'
|
||||
laPPropN(23)='pretftva'
|
||||
laPPropN(24)='pretftva_val'
|
||||
laPPropN(25)='pretctva'
|
||||
laPPropN(26)='pretctva_val'
|
||||
laPPropN(27)='tva'
|
||||
laPPropN(28)='tva_val'
|
||||
laPPropN(29)='discount_unitar'
|
||||
laPPropN(30)='discount_unitar_val'
|
||||
laPPropN(31)='discount_unitar_ctva'
|
||||
laPPropN(32)='discount_unitar_ctva_val'
|
||||
laPPropN(33)='valftva'
|
||||
laPPropN(34)='valtva'
|
||||
laPPropN(35)='valctva'
|
||||
laPPropN(36)='valdiscountftva'
|
||||
laPPropN(37)='valdiscounttva'
|
||||
laPPropN(38)='valdiscountctva'
|
||||
laPPropN(39)='valdiminuatftva'
|
||||
laPPropN(40)='valdiminuattva'
|
||||
laPPropN(41)='valdiminuatctva'
|
||||
laPPropN(42)='vvalftva'
|
||||
laPPropN(43)='vvaltva'
|
||||
laPPropN(44)='vvalctva'
|
||||
laPPropN(45)='vvaldiscountftva'
|
||||
laPPropN(46)='vvaldiscounttva'
|
||||
laPPropN(47)='vvaldiscountctva'
|
||||
laPPropN(48)='vvaldiminuatftva'
|
||||
laPPropN(49)='vvaldiminuattva'
|
||||
laPPropC( 1)='codmat'
|
||||
laPPropC( 2)='codmatf'
|
||||
laPPropC( 3)='denumire'
|
||||
laPPropC( 4)='um'
|
||||
laPPropC( 5)='serie'
|
||||
laPPropC( 6)='lot'
|
||||
laPPropC( 7)='explicatie'
|
||||
laPPropC( 8)='numar_contract'
|
||||
laPPropC( 9)='codbare'
|
||||
laPPropC(10)='nume_val'
|
||||
laPPropC(11)='Cont'
|
||||
|
||||
PRIVATE poArticol
|
||||
poArticol = CREATEOBJECT('Empty')
|
||||
FOR lnPi = 1 TO 49
|
||||
=ADDPROPERTY(poArticol, laPPropN(lnPi), 0)
|
||||
ENDFOR
|
||||
=ADDPROPERTY(poArticol, 'vvaldiminuatctva', 0)
|
||||
FOR lnPi = 1 TO 11
|
||||
=ADDPROPERTY(poArticol, laPPropC(lnPi), '')
|
||||
ENDFOR
|
||||
poArticol.id_articol = 3001
|
||||
poArticol.Id_Pol = 1
|
||||
poArticol.Cont = '701'
|
||||
poArticol.id_gestiune = 101
|
||||
poArticol.gestionabil = 1
|
||||
poArticol.tip_valuta = 0
|
||||
poArticol.Curs = 1
|
||||
poArticol.multiplicator = 1
|
||||
poArticol.cantitate = 3
|
||||
poArticol.codmat = 'ART3001'
|
||||
poArticol.denumire = 'ARTICOL GESTIUNI NIVEL3'
|
||||
poArticol.um = 'BUC'
|
||||
poArticol.proc_tvav = 1.21
|
||||
poArticol.preturi_cu_tva = 0
|
||||
poArticol.pretftva = 50
|
||||
poArticol.pretctva = 60.5
|
||||
|
||||
TRY
|
||||
loProba = CREATEOBJECT('frm_articol_gest_factura', 3, .F., .F.)
|
||||
DO AfLog WITH 'DIAG PROBA: CREATEOBJECT reusit izolat, Class=' + loProba.Class
|
||||
loProba.Release()
|
||||
CATCH TO loExcProba
|
||||
DO AfLog WITH 'DIAG PROBA: CATCH ErrorNo=' + TRANSFORM(loExcProba.ErrorNo) + ' Message=' + loExcProba.Message + ' Proc=' + loExcProba.Procedure + ' Line=' + TRANSFORM(loExcProba.LineNo) + ' [' + loExcProba.LineContents + ']'
|
||||
ENDTRY
|
||||
|
||||
DO HarnessDone WITH 'done-error'
|
||||
ENDTRY
|
||||
|
||||
QUIT
|
||||
|
||||
*==================================================================================
|
||||
PROCEDURE AfErr
|
||||
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
|
||||
DO AfLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE AfLog
|
||||
LPARAMETERS tcMsg
|
||||
SET SAFETY OFF
|
||||
LOCAL lcL
|
||||
lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
|
||||
STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE UILog
|
||||
LPARAMETERS tcMsg
|
||||
DO AfLog WITH tcMsg
|
||||
ENDPROC
|
||||
|
||||
*-- FindCtl: referinta directa la un control prin Controls(i), potrivit dupa .Name - tehnica
|
||||
*-- validata in test_modal_unlock_smoketest2.prg / Nivel 2 (accesul cu prefix direct pe o referinta
|
||||
*-- obtinuta din _SCREEN.Forms da eroare 1925; Controls(i) e calea sigura).
|
||||
PROCEDURE FindCtl
|
||||
LPARAMETERS toParent, tcName
|
||||
LOCAL lnI, loGasit
|
||||
loGasit = .NULL.
|
||||
FOR lnI = 1 TO toParent.ControlCount
|
||||
IF UPPER(toParent.Controls(lnI).Name) == UPPER(tcName)
|
||||
loGasit = toParent.Controls(lnI)
|
||||
ENDIF
|
||||
ENDFOR
|
||||
RETURN loGasit
|
||||
ENDPROC
|
||||
|
||||
DEFINE CLASS dummyapp AS Custom
|
||||
PROCEDURE ReadIni
|
||||
LPARAMETERS tcSection, tcKey
|
||||
RETURN ''
|
||||
ENDPROC
|
||||
PROCEDURE WriteIni
|
||||
LPARAMETERS tcSection, tcKey, tcValue
|
||||
RETURN .T.
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS dummyexport AS Custom
|
||||
PROCEDURE citesteSetareRegistru
|
||||
LPARAMETERS tcCheie
|
||||
RETURN ''
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
*-- dummyexecutor: mock la GRANITA (goExecutor.oExecute e singurul punct de contact al lui
|
||||
*-- do_alege_stoc cu Oracle, ofacturare.vc2:13254). Ramifica pe continutul SQL-ului: cererile
|
||||
*-- 'cursor_gestiuni_articol*' (normal/_retur/_stoc0 - toate three trec prin acelasi mock, textul
|
||||
*-- nu se distinge in teste, doar sursa comuna crsMockStoc) primesc structura+datele din
|
||||
*-- crsMockStoc; orice alta interogare (ex. select codmatf ... from nom_articole, apelata dupa
|
||||
*-- gnButon=1) primeste comportamentul implicit de dinainte (cursor gol cu un singur camp).
|
||||
DEFINE CLASS dummyexecutor AS Custom
|
||||
cEroare = ''
|
||||
PROCEDURE oExecute
|
||||
LPARAMETERS tcSql, tcCursor
|
||||
IF USED(tcCursor)
|
||||
USE IN (tcCursor)
|
||||
ENDIF
|
||||
IF 'CURSOR_GESTIUNI_ARTICOL' $ UPPER(tcSql)
|
||||
SELECT * FROM crsMockStoc INTO CURSOR (tcCursor) READWRITE
|
||||
ELSE
|
||||
CREATE CURSOR (tcCursor) (codmatf C(50))
|
||||
ENDIF
|
||||
RETURN 1
|
||||
ENDPROC
|
||||
PROCEDURE oPrelucrareEroare
|
||||
RETURN cEroare
|
||||
ENDPROC
|
||||
PROCEDURE oReset
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
|
||||
DEFINE CLASS driverdeblocaregest AS Custom
|
||||
PROCEDURE Executa
|
||||
*-- rulat la fiecare tick al _SCREEN.tmrDrvN3. Cauta FRM_ARTICOL_GEST_FACTURA (nu
|
||||
*-- FRM_ARTICOL_FACTURA - dialogul cu gridul de gestiuni, deschis de do_alege_stoc),
|
||||
*-- aplica interactiunea selectata de gcCazAct, inchide dialogul (do_termin sau
|
||||
*-- But_renunt1.Click(), dupa caz).
|
||||
LOCAL lnI, loForm, llGasit
|
||||
gnDriverTick = gnDriverTick + 1
|
||||
llGasit = .F.
|
||||
FOR lnI = 1 TO _SCREEN.FormCount
|
||||
IF UPPER(_SCREEN.Forms(lnI).Class) == 'FRM_ARTICOL_GEST_FACTURA'
|
||||
loForm = _SCREEN.Forms(lnI)
|
||||
llGasit = .T.
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
IF glDlgTratat OR !llGasit
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
DO AfLog WITH 'driverGest tick ' + TRANSFORM(gnDriverTick) + ' POTRIVIT (caz=' + gcCazAct + '), intru in interactiune'
|
||||
|
||||
LOCAL loCantitateCtn, loCantitate, loBifa, loRenunt, loGrid
|
||||
|
||||
TRY
|
||||
DO CASE
|
||||
CASE gcCazAct == 'ADD_G1_Q3'
|
||||
*-- caz a: dialogul cu gestiuni s-a deschis pe mai multe gestiuni (nu auto-select);
|
||||
*-- verific ck_pret_cu_tva (mostenit din frm_articol_factura, S2a) - existenta si layout.
|
||||
loBifa = FindCtl(loForm, 'ck_pret_cu_tva')
|
||||
IF VARTYPE(loBifa) = 'O'
|
||||
IF loForm.Height = 546 AND loBifa.Top = 510
|
||||
DO AfLog WITH 'driverGest ADD_G1_Q3: ck_pret_cu_tva EXISTA, Top=' + TRANSFORM(loBifa.Top) + ' pe forma Height=' + TRANSFORM(loForm.Height) + ' -> PASS layout'
|
||||
ELSE
|
||||
DO AfLog WITH 'driverGest ADD_G1_Q3: ck_pret_cu_tva EXISTA dar layout neasteptat: Top=' + TRANSFORM(loBifa.Top) + ' Height forma=' + TRANSFORM(loForm.Height)
|
||||
ENDIF
|
||||
ELSE
|
||||
DO AfLog WITH 'driverGest ADD_G1_Q3: ck_pret_cu_tva LIPSESTE din instanta'
|
||||
ENDIF
|
||||
DO AfLog WITH 'driverGest ADD_G1_Q3: Reccount(crsgestarticol)=' + TRANSFORM(RECCOUNT('crsgestarticol'))
|
||||
*-- pozitia implicita (Go Top, tnIdTempExclus=0 la adaugare) e deja pe G1 (datain cel mai vechi)
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = 3
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driverGest ADD_G1_Q3: cantitate=3 pe G1 (pozitia implicita), apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'ADD_G2_Q4'
|
||||
SELECT crsgestarticol
|
||||
LOCATE FOR id_gestiune = 102
|
||||
loGrid = FindCtl(loForm, 'grd_gestiuni')
|
||||
loGrid.AfterRowColChange(1)
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = 4
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driverGest ADD_G2_Q4: navigheaza pe G2, cantitate=4, apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'MOD_L1_PRESELECT_CHECK'
|
||||
*-- cazuri b+c: verifica preselectia pe randul liniei si excluderea id_temp, fara sa comita nimic
|
||||
SELECT crsgestarticol
|
||||
IF id_gestiune = 101 AND ABS(cantitate - 10) < 0.001
|
||||
DO UILog WITH 'PASS P3 (caz b) preselectie pe randul liniei modificate, cu propria cantitate reintoarsa in stoc: id_gestiune=' + TRANSFORM(id_gestiune) + ' cantitate=' + TRANSFORM(cantitate)
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P3 (caz b): id_gestiune=' + TRANSFORM(id_gestiune) + ' cantitate=' + TRANSFORM(cantitate) + ' (asteptat 101 / 10)'
|
||||
ENDIF
|
||||
LOCATE FOR id_gestiune = 102
|
||||
IF FOUND() AND ABS(cantitate - 11) < 0.001
|
||||
DO UILog WITH 'PASS P3 (caz c) randul G2 (linia2, neexclusa) scade normal cu cantitatea ei: cantitate=' + TRANSFORM(cantitate) + ' (15-4)'
|
||||
ELSE
|
||||
DO UILog WITH 'FAIL P3 (caz c): randul G2 found=' + TRANSFORM(FOUND()) + IIF(FOUND(), ' cantitate=' + TRANSFORM(cantitate), '') + ' (asteptat 11 = 15-4)'
|
||||
ENDIF
|
||||
loRenunt = FindCtl(loForm, 'But_renunt1')
|
||||
DO AfLog WITH 'driverGest MOD_L1_PRESELECT_CHECK: apas Renunta (nimic de comis)'
|
||||
loRenunt.Click()
|
||||
|
||||
CASE gcCazAct == 'MOD_L1_REJECT_OVER_LOT'
|
||||
SELECT crsgestarticol
|
||||
LOCATE FOR id_gestiune = 101
|
||||
loGrid = FindCtl(loForm, 'grd_gestiuni')
|
||||
loGrid.AfterRowColChange(1)
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = 11
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driverGest MOD_L1_REJECT_OVER_LOT: cantitate=11 pe G1 (stoc 10), apas do_termin() - astept respingere'
|
||||
loForm.do_termin()
|
||||
*-- daca a respins, formularul ramane deschis (testare-ui-vfp.md, "Dialoguri modale") - inchid prin Renunta
|
||||
loRenunt = FindCtl(loForm, 'But_renunt1')
|
||||
IF VARTYPE(loRenunt) = 'O'
|
||||
DO AfLog WITH 'driverGest MOD_L1_REJECT_OVER_LOT: dialogul a ramas deschis (validare respinsa, cum era asteptat), inchid cu Renunta'
|
||||
loRenunt.Click()
|
||||
ENDIF
|
||||
|
||||
CASE gcCazAct == 'MOD_L1_ACCEPT_AT_LOT'
|
||||
SELECT crsgestarticol
|
||||
LOCATE FOR id_gestiune = 101
|
||||
loGrid = FindCtl(loForm, 'grd_gestiuni')
|
||||
loGrid.AfterRowColChange(1)
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = 10
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driverGest MOD_L1_ACCEPT_AT_LOT: cantitate=10 pe G1 (exact stocul), apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'MOD_L1_CHANGE_GESTIUNE_NAV'
|
||||
SELECT crsgestarticol
|
||||
LOCATE FOR id_gestiune = 103
|
||||
loGrid = FindCtl(loForm, 'grd_gestiuni')
|
||||
loGrid.AfterRowColChange(1)
|
||||
loCantitateCtn = FindCtl(loForm, 'clb_cantitate')
|
||||
loCantitate = FindCtl(loCantitateCtn, 'Text_simplu1')
|
||||
loCantitate.Value = 5
|
||||
loCantitate.InteractiveChange()
|
||||
DO AfLog WITH 'driverGest MOD_L1_CHANGE_GESTIUNE_NAV: navigheaza (fara SPACE) pe G3, cantitate=5, apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'MOD_L1_MULTISELECT'
|
||||
SELECT crsgestarticol
|
||||
LOCATE FOR id_gestiune = 101
|
||||
DO AfLog WITH 'driverGest MOD_L1_MULTISELECT: SPACE (do_executa) pe G1'
|
||||
loForm.do_executa()
|
||||
SELECT crsgestarticol
|
||||
LOCATE FOR id_gestiune = 104
|
||||
DO AfLog WITH 'driverGest MOD_L1_MULTISELECT: SPACE (do_executa) pe G4'
|
||||
loForm.do_executa()
|
||||
DO AfLog WITH 'driverGest MOD_L1_MULTISELECT: nselectate=' + TRANSFORM(loForm.nselectate) + IIF(TYPE('poArticol.cantitate') = 'N', ' poArticol.cantitate acumulata=' + TRANSFORM(poArticol.cantitate), '') + ', apas do_termin()'
|
||||
loForm.do_termin()
|
||||
|
||||
CASE gcCazAct == 'MOD_L1_RENUNTA'
|
||||
loCantitateCtn = FindCtl(loForm, 'Clb_pretftva')
|
||||
IF VARTYPE(loCantitateCtn) = 'O'
|
||||
loCantitate = FindCtl(loCantitateCtn, 'tx_suma_nat')
|
||||
IF VARTYPE(loCantitate) = 'O'
|
||||
loCantitate.Value = 9999
|
||||
loCantitate.InteractiveChange()
|
||||
ENDIF
|
||||
ENDIF
|
||||
loRenunt = FindCtl(loForm, 'But_renunt1')
|
||||
DO AfLog WITH 'driverGest MOD_L1_RENUNTA: pret tastat 9999, apas But_renunt1 (Renunta)'
|
||||
loRenunt.Click()
|
||||
|
||||
OTHERWISE
|
||||
DO AfLog WITH 'driverGest: gcCazAct necunoscut [' + gcCazAct + ']'
|
||||
ENDCASE
|
||||
|
||||
glDlgTratat = .T.
|
||||
DO AfLog WITH 'driverGest: interactiune REUSITA pentru caz=' + gcCazAct
|
||||
CATCH TO loExcDrv
|
||||
DO AfLog WITH 'driverGest: CATCH caz=' + gcCazAct + ' ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ;
|
||||
' Message=' + loExcDrv.Message + ' Procedure=' + loExcDrv.Procedure + ;
|
||||
' LineNo=' + TRANSFORM(loExcDrv.LineNo) + ' LineContents=[' + loExcDrv.LineContents + ']'
|
||||
ENDTRY
|
||||
ENDPROC
|
||||
ENDDEFINE
|
||||
@@ -0,0 +1,13 @@
|
||||
# test_pret_cu_tva_nivel3_gestiuni.ps1 - wrapper peste harness-ul generic pentru ramura GESTIONABILA
|
||||
# a lui do_modifica/do_adauga_articol (S2d, review). Oracle mockuit la granita (goExecutor), fluxul
|
||||
# real (butoane, taste, SPACE) ramane intact. Rulare:
|
||||
# powershell -ExecutionPolicy Bypass -File test_pret_cu_tva_nivel3_gestiuni.ps1
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Teste = $PSScriptRoot
|
||||
& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') `
|
||||
-TestPrg (Join-Path $Teste 'test_pret_cu_tva_nivel3_gestiuni.prg') `
|
||||
-Steps @('mediu', 'p1_add_g1', 'p2_add_g2', 'p3_preselectie_excludere', 'p4_respins_peste_lot', 'p5_acceptat_la_lot', 'p6_schimbare_gestiune_nav', 'p7_multiselectie', 'p8_renunta') `
|
||||
-ShotsDir (Join-Path $Teste 'screenshots_nivel3') `
|
||||
-SyncDir (Join-Path $Teste 'uisync_nivel3') `
|
||||
-StepTimeoutSec 60 `
|
||||
-ReadyTimeoutSec 90
|
||||
128
utile/Teste/nnir_registru_jurnal/date_test_nnir.md
Normal file
128
utile/Teste/nnir_registru_jurnal/date_test_nnir.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Date de test - NNIR editabil in Registru Jurnal
|
||||
|
||||
Baza: `MARIUSM_AUTO@ROA_CENTRAL` (test, nu productie). Verificare: `verif_nnir_cod.sql` in acest
|
||||
folder (`sqlplus ... @verif_nnir_cod.sql <cod>`).
|
||||
|
||||
| Caz | COD | AN | LUNA | ID_SET | NNIR curent | ACT randuri | RUL randuri | RUL_OBINV randuri |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| NIR/achizitie (principal) | 1140841 | 2026 | 7 | 209 | 3 | 7 (doar 1 cu nnir=3, restul 0) | 1 (nnir=3) | 0 |
|
||||
| Obiecte de inventar | 1140835 | 2026 | 6 | 211 | 2026060001 | 1 | 0 | 2 (nnir=2026060001) |
|
||||
| Fara rulaje | 1140848 | 2026 | 7 | 209 | 124 | 2 (ambele nnir=124) | 0 | 0 |
|
||||
| Nota de inventar (blocare) | 1140716 | 2026 | 3 | 90101 | 2026030004 | 1 | 1 (nnir=2026030004) | 0 |
|
||||
|
||||
Note:
|
||||
- ACT e pe linii (nu pe antet) - la COD 1140841 doar linia efectiv legata de rulaj are NNIR-ul
|
||||
real, restul liniilor documentului au NNIR=0. Sincronizarea (`WHERE Nvl(nnir,0) = vechi`) trebuie
|
||||
sa lase liniile cu 0 neatinse.
|
||||
- Nu exista nicio nota cu `id_set=90101` sau cu rulaje in `RUL_OBINV` in luna curenta de lucru
|
||||
(AN=2026, LUNA=7) - alese din perioade anterioare. Editarea reala prin `afisjurcom.do_modifica`
|
||||
e limitata la luna curenta (`comun.vc2:2265-2268`); testul instantiaza `frm_modific2024` direct
|
||||
(ca `test_repro_cnrcrt_footer.prg`), cu cursoare construite pe AN/LUNA propriu notei, ocolind
|
||||
acel filtru - la fel ca precedentul deja acceptat in `achizitie_import`.
|
||||
|
||||
## Stare implementare (livrata, 03.08.2026)
|
||||
|
||||
`COMUN\clase\omodificari.vc2` (frm_modific2024):
|
||||
- `Grid1.ColumnCount = 44`, `Column44.ControlSource = "nnir"` (la runtime apare calificat automat
|
||||
de VFP cu aliasul cursorului: `tact.nnir`), `ReadOnly = .F.` - confirmat prin instantiere reala
|
||||
(nu doar citire de sursa).
|
||||
- `PROCEDURE sincronizeaza_nnir(tnNnirVechi, tnNnirNou)` (`omodificari.vc2:13762`) - update pe
|
||||
`tact`/`trul`/`trul_obinv` unde `Nvl(nnir,0) = vechi`, cu revenire pe recno. Propaga si valoarea
|
||||
0 (stergerea NNIR) - nu exista garda `EMPTY` pe valoarea noua.
|
||||
- Legare pe coloana: `Grid1.Column44.Text1.When` retine valoarea veche in `thisform.nnnirvechi`;
|
||||
**`Grid1.Column44.Text1.LostFocus`** apeleaza `sincronizeaza_nnir` si `Thisform.Grid1.Refresh()`
|
||||
- `Valid` a fost eliminat (la textbox valoarea nu ajunge in ControlSource decat DUPA ce Valid
|
||||
returneaza .T., deci nu propaga). Testul declanseaza `LostFocus`.
|
||||
- Blocarea pentru `id_set = 90101` (nota de inventar): in `Init` (`omodificari.vc2:13654`) SI
|
||||
reimpusa in `Grid1.AfterRowColChange` (14289-14292), dupa `SetAll("ReadOnly", ...)` - fara a doua,
|
||||
`SetAll` anuleaza blocarea la prima navigare in grid.
|
||||
- `ColumnOrder = 7` in clasa, plus repozitionare la runtime in `Show()`, dupa `gridextra1.setup()`
|
||||
(13729-13738) - preferintele de grid salvate per utilizator impingeau coloana noua la coada
|
||||
(vezi `COMUN\docs\capcana_grid_preferinte_utilizator.md`). Pozitia NU e o asertiune stabila intre
|
||||
masini; asertat tare in test: `ControlSource = "nnir"`, `ReadOnly` (.F. normal / .T. pe
|
||||
id_set 90101), propagarea valorii.
|
||||
|
||||
## Cerinte de mediu descoperite la construirea harness-ului (deja tratate in scripturile livrate)
|
||||
|
||||
- `COMUN\utile\Teste\test_init_env_auto.prg` (generic) e de fapt specific ROACONT (`gcAppPath`,
|
||||
classlib-uri si proceduri hardcodate `D:\ROA\ROACONT\`) - inutilizabil pentru ROAGEST. S-a scris
|
||||
`COMUN\utile\Teste\test_init_env_auto_roagest.prg`, cu SET PATH/CLASSLIB/PROCEDURE reconstruite
|
||||
din `Programe\roagest.prg`.
|
||||
- `gcUserName` trebuie setat explicit inainte de `optiuni_firma` (`oinit_optiuni.prg`) - altfel
|
||||
`SCRIE_OPTIUNI(gcUserName)` da "Operator/operand type mismatch" (PUBLIC nedeclarat ramane
|
||||
logic .F.). **`gcUserName` e schema/userul de conectare Oracle** (`Programe\roagest.prg:560,575`)
|
||||
- `SCRIE_OPTIUNI` il foloseste direct in `from <gcUserName>.optiuni`, deci trebuie
|
||||
`gcUserName = m.gcS`, NU un nume de persoana (ex. 'MARIUS M' da ORA-00907, identificator invalid
|
||||
- incercare gresita initiala). Numele de persoana e `gcUserNameApp` (variabila separata).
|
||||
- `frm_modific2024` face `Seek(..,'crsJtvaTemp','id_jtva')` in ControlSource-ul coloanei de
|
||||
explicatie TVA a rulajelor (Column63) - evaluat la CONSTRUCTIA formularului. Fara cursorul
|
||||
deschis, `CREATEOBJECT('frm_modific2024',...)` pica cu "File 'crsjtvatemp.dbf' does not exist".
|
||||
Fix: `update_jtva_coloane('', 'crsJtvaTemp', 6)` (in `COMUN\programe\updateserver.prg:553`)
|
||||
inainte de instantiere - construieste direct cursorul cu indexul cerut, fara pasii intermediari
|
||||
folositi de exemplul ROACONT (`update_jtva_coloana`/`crsExplicatiiTVATemp`, care oricum nu
|
||||
exista in ROAGEST).
|
||||
- Mock-ul `amessagebox` trebuie incarcat **INAINTE** de `test_init_env_auto_roagest.prg` (nu doar
|
||||
dupa, cum sugereaza exemplele din `achizitie_import`) - `optiuni_firma` poate afisa un dialog
|
||||
real daca `SCRIE_OPTIUNI` raporteaza eroare, inainte sa apuce sa se incarce mock-ul "la coada".
|
||||
- La citirea unei coloane de grid prin ControlSource dintr-un cursor legat ca RecordSource, VFP
|
||||
calificat automat campul simplu cu aliasul (`nnir` -> `tact.nnir`) - comparatiile exacte
|
||||
`== 'NNIR'` trebuie sa accepte si forma calificata.
|
||||
- Coloanele de grid nu sunt garantat numite `Column<N>` - unele au `Name` custom (ex. `cAles` pe
|
||||
pozitia 41 in acest grid); accesul dinamic la coloana trebuie facut prin colectia
|
||||
`Grid1.Columns(i)`, nu prin constructia textuala a numelui `"column" + TRANSFORM(i)`.
|
||||
- `frm_modific2024.Grid1.AfterRowColChange` are propria logica de blocare pe sucursala (SetAll
|
||||
ReadOnly pe toate coloanele daca `Nvl(gnIdSucursala,0) <> Nvl(tAct.id_sucursala,0)`) - independenta
|
||||
de blocarea 90101, se declanseaza automat la pozitionare in grid. COD 1140835 (cazul obiecte de
|
||||
inventar) are `id_sucursala` diferit de sesiunea de test (`gnIdSucursala = NULL`), deci Column44
|
||||
iese `ReadOnly=.T.` in acest scenariu - nu e o eroare, e comportament existent, neplanificat de
|
||||
NNIR; sincronizarea tot functioneaza (apelul e direct, nu prin UI).
|
||||
- **Termin reatribuie COD nou**: `afisjurcom.do_modifica` (comun.vc2:2444-2487) cheama
|
||||
`oscrie_in_fisiere` de DOUA ori - intai `(2,.T.,llRul)` (STERGE, marcheaza `sters=1` pe COD-ul
|
||||
ORIGINAL, din `actactan` neatins de editare), apoi `(0,.T.,llRul)` (SCRIE varianta editata sub
|
||||
COD nou, generat de `pack_contafin`, sub AN/LUNA de sesiune curenta - nu pastreaza COD-ul/AN/LUNA
|
||||
notei editate). Verificarea si curatenia testului se fac dupa NNIR (marcaj distinct), nu dupa
|
||||
COD, si readuc nota originala la `sters=0` dupa test (pasul STERGE o dezactiveaza altfel permanent).
|
||||
- Salvarea reala cere tranzactie manuala explicita: `SQLSetProp(gnHandle,'Transactions',2)` inainte
|
||||
de blocul STERGE+SCRIE+finalizeaza, apoi `SQLCOMMIT(gnHandle)`/`SQLROLLBACK` +
|
||||
`SQLSetProp(...,1)` dupa - echivalentul direct al `thisform.do_deschide_tranzactie()`/
|
||||
`do_inchide_tranzactie()` din `afisjurcom` (`_frm_base.vc2:252-305`, mostenite, apelate pe
|
||||
formularul de jurnal - nu pe `frm_modific2024`, deci invizibile la o privire doar pe clasa notei).
|
||||
Fara acest wrapping, `oscrie_in_fisiere`/`finalizeaza_modificare_nota` raporteaza succes dar nu
|
||||
se vede nimic persistat, nici in aceeasi sesiune.
|
||||
|
||||
## Capcana: .FXP stale ascunde scenariile noi
|
||||
|
||||
VFP nu recompileaza .prg-ul daca exista un .FXP mai vechi - ruleaza tacut versiunea veche a
|
||||
scriptului. Simptom: suita raporteaza PASS-uri corecte, dar scenariile adaugate dupa ultima
|
||||
compilare nu apar deloc in log (verifica numarul de assert-uri, nu doar `0 FAIL`). Sterge
|
||||
.FXP-ul inainte de fiecare rulare.
|
||||
|
||||
## Capcana: dialog modal "Enter the value for <var>" in loc de eroare catchabila
|
||||
|
||||
O variabila memorie lipsa/umbrita folosita ca `?param` intr-un SQL pass-through (SQLEXEC/
|
||||
`goExecutor.oExecuta`) NU da o eroare VFP catchabila (ON ERROR) - deschide dialogul nativ
|
||||
"View Parameter" ("Enter the value for <var>"), MODAL, care blocheaza tot procesul headless la
|
||||
nesfarsit si nu lasa nimic in log (spre deosebire de un `REPLACE`/expresie cu aceeasi variabila
|
||||
lipsa, care DA eroare catchabila - vezi cazul `gnIdUtil` scapat o data ca `PRIVATE` neasignat).
|
||||
Simptom: proces `vfp9.exe` care nu mai raspunde, fara `.ERR`, fara linie noua in log.
|
||||
|
||||
Remediu: **garda explicita inainte de orice rulare care ajunge la cod ce foloseste `?param`** -
|
||||
verifica `TYPE(<nume>) == 'U'` pe toate variabilele relevante (nu doar cele proprii testului, ci
|
||||
si cele din codul apelat: `oscrie_in_fisiere`, `pack_contafin`/`pack_sesiune`, `oinit_optiuni.prg`)
|
||||
si opreste testul cu FAIL clar in log daca lipseste ceva, inainte sa ajunga la SQLEXEC. Implementat
|
||||
in `test_nnir_sincronizare.prg` (`NnirGardaVariabile`, apelata imediat dupa init mediu). `TYPE()`
|
||||
returneaza `'X'` (nu `'U'`) pentru NULL - o valoare NULL e un bind valid, doar variabila absenta
|
||||
e problema.
|
||||
|
||||
## Rezultat test complet (03.08.2026, pe binarul livrat)
|
||||
|
||||
**33 PASS, 0 FAIL** pe cele 6 scenarii: NIR, obiecte de inventar si nota fara rulaje (toate cu
|
||||
salvare reala prin Termin + verificare in Oracle), blocare `id_set=90101`, `NNIR -> 0`, si blocare
|
||||
`id_set=90101` pe sucursala curenta. Baza de test verificata dupa rulare: cele 4 note originale
|
||||
(1140841, 1140835, 1140848, 1140716) raman intacte (NNIR si `sters` la valorile initiale); notele
|
||||
noi create de Termin (COD reatribuit) au fost marcate `sters=1` de curatenia din test.
|
||||
|
||||
Scenariul 6 (`INVENTAR2`) exista pentru ca scenariul 4 ruleaza pe o nota din ALTA sucursala, unde
|
||||
`AfterRowColChange` blocheaza oricum tot gridul - trecea din motivul gresit. Scenariul 6 aliniaza
|
||||
`gnIdSucursala` la nota (`llReadOnly` iese `.F.`) si asertesteaza si ca restul coloanelor raman
|
||||
editabile, altfel blocarea NNIR nu dovedeste nimic.
|
||||
839
utile/Teste/nnir_registru_jurnal/test_nnir_sincronizare.prg
Normal file
839
utile/Teste/nnir_registru_jurnal/test_nnir_sincronizare.prg
Normal file
@@ -0,0 +1,839 @@
|
||||
* test_nnir_sincronizare.prg
|
||||
* Test e2e (fluxul real): NNIR editabil in Registru Jurnal, cu sincronizare in tact/trul/trul_obinv
|
||||
* si in ACT/RUL/RUL_OBINV (Oracle). Vezi cerinta initiala (todos.txt pct. 9) si
|
||||
* date_test_nnir.md (datele de test alese, an/luna/cod, stare implementare la data scrierii).
|
||||
*
|
||||
* Instantiaza frm_modific2024 direct (ca test_repro_cnrcrt_footer.prg din achizitie_import),
|
||||
* cu cursoarele tact/trul/trul_obinv construite exact ca afisjurcom.do_modifica (comun.vc2:2352-
|
||||
* 2434), dar pe AN/LUNA proprii notei - do_modifica limiteaza editarea la luna curenta de lucru
|
||||
* (comun.vc2:2265-2268), iar notele de test nu sunt toate in luna curenta.
|
||||
*
|
||||
* Editarea NNIR se simuleaza ca un utilizator: pozitionare pe rand, declansarea evenimentelor
|
||||
* reale ale coloanei (When la intrare, LostFocus la iesire - textboxul nu comite valoarea in
|
||||
* ControlSource inainte de Valid, de-aia implementarea sincronizeaza pe LostFocus), NU apel
|
||||
* direct al metodei de sincronizare. Salvarea (Termin) replica blocul din
|
||||
* afisjurcom.do_modifica (comun.vc2:2456-2487): oscrie_in_fisiere + pack_contafin.
|
||||
* finalizeaza_modificare_nota. Termin reatribuie COD nou (pack_contafin), sub AN/LUNA de sesiune
|
||||
* curenta - nu pastreaza COD-ul original; verificarea si curatenia de dupa salvare se fac dupa
|
||||
* valoarea NNIR marcaj (nu poate coincide cu date reale), marcand sters=1 (conventia aplicatiei)
|
||||
* orice a ajuns sub acea valoare - nota originala (COD/NNIR vechi) ramane intacta.
|
||||
*
|
||||
* Rulare headless (nu tine VFP IDE deschis; nu rula cu roagest.exe pornit):
|
||||
* & "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A -T ;
|
||||
* "D:\ROA\ROAGEST\COMUN\utile\Teste\nnir_registru_jurnal\test_nnir_sincronizare.prg"
|
||||
* Timeout recomandat: minim 220s. Log: %TEMP%\test_nnir_sincronizare_log.txt (PASS/FAIL pe linie).
|
||||
* STERGE .FXP-ul inainte de rulare: VFP nu recompileaza automat si ruleaza tacut versiunea
|
||||
* veche a scriptului - scenariile adaugate intre timp lipsesc cu totul din log.
|
||||
|
||||
LPARAMETERS tcMode
|
||||
tcMode = IIF(EMPTY(tcMode), 'ALL', UPPER(ALLTRIM(tcMode)))
|
||||
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
PUBLIC gcLogFile, gnFail, gnPass
|
||||
gcLogFile = ADDBS(SYS(2023)) + 'test_nnir_sincronizare_log.txt'
|
||||
gnFail = 0
|
||||
gnPass = 0
|
||||
STRTOFILE('START ' + tcMode + ' ' + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLogFile)
|
||||
|
||||
ON ERROR DO NnirErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||
ON SHUTDOWN QUIT
|
||||
|
||||
* mock amessagebox incarcat INAINTE de mediul aplicatiei: optiuni_firma (in mediul de test)
|
||||
* poate afisa un dialog real daca SCRIE_OPTIUNI raporteaza eroare
|
||||
SET PROCEDURE TO D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
|
||||
DO D:\ROA\ROAGEST\COMUN\utile\Teste\test_init_env_auto_roagest.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
|
||||
IF gnHandle <= 0
|
||||
DO NnirLog WITH 'EROARE: conectare Oracle esuata'
|
||||
DO NnirLog WITH 'REZULTAT SUITA: NEDETERMINAT'
|
||||
QUIT
|
||||
ENDIF
|
||||
DO NnirLog WITH 'mediu OK, gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna)
|
||||
|
||||
* garda anti-blocaj: o variabila lipsa folosita ca ?param intr-un SQL pass-through NU da eroare
|
||||
* catchabila - VFP deschide dialogul modal nativ "Enter the value for <var>", care blocheaza
|
||||
* headless-ul la nesfarsit si nu lasa nimic in log (vezi date_test_nnir.md). Verificare
|
||||
* explicita INAINTE de orice apel care le foloseste, opreste testul cu FAIL clar daca lipseste ceva.
|
||||
IF !NnirGardaVariabile()
|
||||
DO NnirLog WITH 'REZULTAT SUITA: NEDETERMINAT (garda variabile a picat)'
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
* mock amessagebox - se incarca ULTIMUL (dupa fisierele aplicatiei), vezi antetul mock-ului
|
||||
SET PROCEDURE TO D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
|
||||
|
||||
* Grid1.Column63 (explicatie TVA pe rulaje) face Seek pe alias 'crsJtvaTemp' la CONSTRUCTIA
|
||||
* formularului (inainte de Init) - fara cursorul deschis, CREATEOBJECT('frm_modific2024',...)
|
||||
* pica cu "File 'crsjtvatemp.dbf' does not exist"
|
||||
update_jtva_coloane('', 'crsJtvaTemp', 6)
|
||||
|
||||
LOCAL Omodif, lcCallWhen, lcCallLostFocus, lcCall
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 1: NIR/achizitie, cu rulaje in RUL, cu salvare (Termin) + verificare Oracle
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'NIR')
|
||||
LOCAL lnCod, lnAn, lnLuna, lnIdSet, lnNnirVechi, lnNnirNou
|
||||
LOCAL lnCntTactVechi, lnCntTrulVechi, lnCntTactNou, lnCntTrulNou
|
||||
LOCAL i, llGasit, lnColOrder, llReadOnly, lnColCheck, lcColName
|
||||
|
||||
lnCod = 1140841
|
||||
lnAn = 2026
|
||||
lnLuna = 7
|
||||
lnIdSet = 209
|
||||
lnNnirVechi = 3
|
||||
lnNnirNou = lnNnirVechi + 90000000
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod, lnAn, lnLuna
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechi = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi TO lnCntTactVechi
|
||||
SELECT trul
|
||||
lnCntTrulVechi = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi TO lnCntTrulVechi
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'NIR', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit = .F.
|
||||
lnColOrder = 0
|
||||
llReadOnly = .T.
|
||||
lnColCheck = 0
|
||||
FOR i = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName = 'Omodif.grid1.Columns(' + TRANSFORM(i) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName + '.ControlSource'))
|
||||
llGasit = .T.
|
||||
lnColOrder = EVALUATE(lcColName + '.ColumnOrder')
|
||||
llReadOnly = EVALUATE(lcColName + '.ReadOnly')
|
||||
lnColCheck = i
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'NIR', llGasit, 'ControlSource=nnir gasit=' + ;
|
||||
TRANSFORM(llGasit) + ' ColumnOrder=' + TRANSFORM(lnColOrder) + ' ReadOnly=' + TRANSFORM(llReadOnly)
|
||||
|
||||
IF llGasit
|
||||
DO NnirAssert WITH 'coloana_editabila', 'NIR', !llReadOnly, 'nota normala: ReadOnly asteptat .F.'
|
||||
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechi
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
REPLACE nnir WITH lnNnirNou
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactNou = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou TO lnCntTactNou
|
||||
DO NnirAssert WITH 'sync_tact', 'NIR', lnCntTactNou = lnCntTactVechi, ;
|
||||
TRANSFORM(lnCntTactNou) + ' randuri tact cu nnir nou (asteptat ' + TRANSFORM(lnCntTactVechi) + ')'
|
||||
|
||||
* trul = cursorul legat de pgfArticole.page1.grdRulaje (RecordSource) - verificare
|
||||
* explicita ca propagarea se vede in cursorul de rulaje, nu doar in tact
|
||||
SELECT trul
|
||||
lnCntTrulNou = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou TO lnCntTrulNou
|
||||
DO NnirAssert WITH 'sync_trul', 'NIR', lnCntTrulNou = lnCntTrulVechi, ;
|
||||
TRANSFORM(lnCntTrulNou) + ' randuri trul (grid rulaje) cu nnir nou (asteptat ' + TRANSFORM(lnCntTrulVechi) + ')'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'NIR', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
DO NnirVerificaOracleNeschimbat WITH lnCod, lnNnirVechi, 'NIR'
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
DO NnirSalveazaSiVerifica WITH lnCod, lnAn, lnLuna, lnIdSet, lnNnirVechi, lnNnirNou, 'NIR'
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 2: obiecte de inventar, cu rulaje in RUL_OBINV, cu salvare + verificare Oracle
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'OBINV')
|
||||
LOCAL lnCod2, lnAn2, lnLuna2, lnIdSet2, lnNnirVechi2, lnNnirNou2
|
||||
LOCAL lnCntTactVechi2, lnCntRobinvVechi2, lnCntTactNou2, lnCntRobinvNou2
|
||||
LOCAL i2, llGasit2, lnColOrder2, llReadOnly2, lnColCheck2, lcColName2
|
||||
|
||||
lnCod2 = 1140835
|
||||
lnAn2 = 2026
|
||||
lnLuna2 = 6
|
||||
lnIdSet2 = 211
|
||||
lnNnirVechi2 = 2026060001
|
||||
lnNnirNou2 = lnNnirVechi2 + 90000000
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod2, lnAn2, lnLuna2
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechi2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi2 TO lnCntTactVechi2
|
||||
SELECT trul_obinv
|
||||
lnCntRobinvVechi2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi2 TO lnCntRobinvVechi2
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet2)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'OBINV', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit2 = .F.
|
||||
lnColOrder2 = 0
|
||||
llReadOnly2 = .T.
|
||||
lnColCheck2 = 0
|
||||
FOR i2 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName2 = 'Omodif.grid1.Columns(' + TRANSFORM(i2) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName2 + '.ControlSource'))
|
||||
llGasit2 = .T.
|
||||
lnColOrder2 = EVALUATE(lcColName2 + '.ColumnOrder')
|
||||
llReadOnly2 = EVALUATE(lcColName2 + '.ReadOnly')
|
||||
lnColCheck2 = i2
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'OBINV', llGasit2, 'ControlSource=nnir gasit=' + ;
|
||||
TRANSFORM(llGasit2) + ' ColumnOrder=' + TRANSFORM(lnColOrder2) + ' ReadOnly=' + TRANSFORM(llReadOnly2)
|
||||
|
||||
IF llGasit2
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechi2
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck2) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
REPLACE nnir WITH lnNnirNou2
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck2) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactNou2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou2 TO lnCntTactNou2
|
||||
DO NnirAssert WITH 'sync_tact', 'OBINV', lnCntTactNou2 = lnCntTactVechi2, ;
|
||||
TRANSFORM(lnCntTactNou2) + ' randuri tact cu nnir nou (asteptat ' + TRANSFORM(lnCntTactVechi2) + ')'
|
||||
|
||||
SELECT trul_obinv
|
||||
lnCntRobinvNou2 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou2 TO lnCntRobinvNou2
|
||||
DO NnirAssert WITH 'sync_trul_obinv', 'OBINV', lnCntRobinvNou2 = lnCntRobinvVechi2, ;
|
||||
TRANSFORM(lnCntRobinvNou2) + ' randuri trul_obinv cu nnir nou (asteptat ' + TRANSFORM(lnCntRobinvVechi2) + ')'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'OBINV', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
DO NnirSalveazaSiVerificaObinv WITH lnCod2, lnAn2, lnLuna2, lnIdSet2, lnNnirVechi2, lnNnirNou2
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 3: nota fara rulaje - regresie (nu crapa), cu salvare + verificare Oracle
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'FARARUL')
|
||||
LOCAL lnCod3, lnAn3, lnLuna3, lnIdSet3, lnNnirVechi3, lnNnirNou3
|
||||
LOCAL lnCntTactVechi3, lnCntTactNou3
|
||||
LOCAL i3, llGasit3, lnColCheck3, lcColName3
|
||||
|
||||
lnCod3 = 1140848
|
||||
lnAn3 = 2026
|
||||
lnLuna3 = 7
|
||||
lnIdSet3 = 209
|
||||
lnNnirVechi3 = 124
|
||||
lnNnirNou3 = lnNnirVechi3 + 90000000
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod3, lnAn3, lnLuna3
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechi3 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechi3 TO lnCntTactVechi3
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet3)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'FARARUL', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit3 = .F.
|
||||
lnColCheck3 = 0
|
||||
FOR i3 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName3 = 'Omodif.grid1.Columns(' + TRANSFORM(i3) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName3 + '.ControlSource'))
|
||||
llGasit3 = .T.
|
||||
lnColCheck3 = i3
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'FARARUL', llGasit3, 'ControlSource=nnir gasit=' + TRANSFORM(llGasit3)
|
||||
|
||||
IF llGasit3
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechi3
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck3) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
REPLACE nnir WITH lnNnirNou3
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheck3) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactNou3 = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirNou3 TO lnCntTactNou3
|
||||
DO NnirAssert WITH 'sync_tact', 'FARARUL', lnCntTactNou3 = lnCntTactVechi3, ;
|
||||
TRANSFORM(lnCntTactNou3) + ' randuri tact cu nnir nou (asteptat ' + TRANSFORM(lnCntTactVechi3) + ')'
|
||||
DO NnirAssert WITH 'nu_crapa', 'FARARUL', .T., 'editarea pe nota fara rulaje nu a generat eroare'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'FARARUL', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
DO NnirSalveazaSiVerifica WITH lnCod3, lnAn3, lnLuna3, lnIdSet3, lnNnirVechi3, lnNnirNou3, 'FARARUL'
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 4: nota de inventar (id_set=90101) - regresie blocare editare NNIR
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'INVENTAR')
|
||||
LOCAL lnCod4, lnAn4, lnLuna4, lnIdSet4
|
||||
LOCAL i4, llGasit4, llReadOnly4, lcColName4
|
||||
|
||||
lnCod4 = 1140716
|
||||
lnAn4 = 2026
|
||||
lnLuna4 = 3
|
||||
lnIdSet4 = 90101
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod4, lnAn4, lnLuna4
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet4)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'INVENTAR', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasit4 = .F.
|
||||
llReadOnly4 = .F.
|
||||
FOR i4 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName4 = 'Omodif.grid1.Columns(' + TRANSFORM(i4) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName4 + '.ControlSource'))
|
||||
llGasit4 = .T.
|
||||
llReadOnly4 = EVALUATE(lcColName4 + '.ReadOnly')
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'INVENTAR', llGasit4, 'ControlSource=nnir gasit=' + TRANSFORM(llGasit4)
|
||||
IF llGasit4
|
||||
* nu se incearca editarea - doar se verifica blocarea, ca sa nu se altereze o nota
|
||||
* reala de inventar cat timp blocarea nu e implementata
|
||||
DO NnirAssert WITH 'coloana_blocata', 'INVENTAR', llReadOnly4, ;
|
||||
'id_set=90101: ReadOnly asteptat .T., gasit ' + TRANSFORM(llReadOnly4)
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 5: stergere NNIR (-> 0) pe randul unei note cu rulaje - propagare la 0.
|
||||
* Comportament nou (runda 4): garda EMPTY(NVL(tnNnirNou,0)) eliminata din sincronizeaza_nnir,
|
||||
* ramane doar egalitatea - stergerea celulei (0 scris pe rand inainte de LostFocus) trebuie sa
|
||||
* se propage la toate liniile cu valoarea veche, nu doar schimbarile intre doua valori nenule.
|
||||
* Doar la nivel de cursoare (tact/trul) - nu se salveaza in Oracle.
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'ZERO')
|
||||
LOCAL lnCodZ, lnAnZ, lnLunaZ, lnIdSetZ, lnNnirVechiZ
|
||||
LOCAL lnCntTactVechiZ, lnCntTrulVechiZ, lnCntTactRamasVechiZ, lnCntTrulRamasVechiZ
|
||||
LOCAL lnCntTactZeroZ, lnCntTrulZeroZ
|
||||
LOCAL iz, llGasitZ, lnColCheckZ, lcColNameZ
|
||||
|
||||
lnCodZ = 1140841
|
||||
lnAnZ = 2026
|
||||
lnLunaZ = 7
|
||||
lnIdSetZ = 209
|
||||
lnNnirVechiZ = 3
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCodZ, lnAnZ, lnLunaZ
|
||||
|
||||
SELECT tact
|
||||
lnCntTactVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTactVechiZ
|
||||
SELECT trul
|
||||
lnCntTrulVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTrulVechiZ
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSetZ)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'ZERO', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
llGasitZ = .F.
|
||||
lnColCheckZ = 0
|
||||
FOR iz = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColNameZ = 'Omodif.grid1.Columns(' + TRANSFORM(iz) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColNameZ + '.ControlSource'))
|
||||
llGasitZ = .T.
|
||||
lnColCheckZ = iz
|
||||
ENDIF
|
||||
ENDFOR
|
||||
DO NnirAssert WITH 'coloana_grid', 'ZERO', llGasitZ, 'ControlSource=nnir gasit=' + TRANSFORM(llGasitZ)
|
||||
|
||||
IF llGasitZ
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = lnNnirVechiZ
|
||||
IF FOUND()
|
||||
lcCallWhen = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheckZ) + ').Text1.When'
|
||||
&lcCallWhen
|
||||
* simuleaza stergerea celulei: utilizatorul goleste campul, valoarea ajunge 0
|
||||
REPLACE nnir WITH 0
|
||||
lcCallLostFocus = 'Omodif.grid1.Columns(' + TRANSFORM(lnColCheckZ) + ').Text1.LostFocus'
|
||||
&lcCallLostFocus
|
||||
|
||||
SELECT tact
|
||||
lnCntTactRamasVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTactRamasVechiZ
|
||||
lnCntTactZeroZ = 0
|
||||
COUNT FOR NVL(nnir,0) = 0 TO lnCntTactZeroZ
|
||||
DO NnirAssert WITH 'sync_tact_zero', 'ZERO', lnCntTactRamasVechiZ = 0 AND lnCntTactZeroZ >= lnCntTactVechiZ, ;
|
||||
TRANSFORM(lnCntTactRamasVechiZ) + ' randuri tact au ramas pe valoarea veche (asteptat 0), ' + ;
|
||||
TRANSFORM(lnCntTactZeroZ) + ' au ajuns la 0 (asteptat cel putin ' + TRANSFORM(lnCntTactVechiZ) + ')'
|
||||
|
||||
* verificare explicita in cursorul legat de grid-ul de rulaje (pgfArticole.page1.grdRulaje)
|
||||
SELECT trul
|
||||
lnCntTrulRamasVechiZ = 0
|
||||
COUNT FOR NVL(nnir,0) = lnNnirVechiZ TO lnCntTrulRamasVechiZ
|
||||
lnCntTrulZeroZ = 0
|
||||
COUNT FOR NVL(nnir,0) = 0 TO lnCntTrulZeroZ
|
||||
DO NnirAssert WITH 'sync_trul_zero', 'ZERO', lnCntTrulRamasVechiZ = 0 AND lnCntTrulZeroZ >= lnCntTrulVechiZ, ;
|
||||
TRANSFORM(lnCntTrulRamasVechiZ) + ' randuri trul au ramas pe valoarea veche (asteptat 0), ' + ;
|
||||
TRANSFORM(lnCntTrulZeroZ) + ' au ajuns la 0 (asteptat cel putin ' + TRANSFORM(lnCntTrulVechiZ) + ')'
|
||||
ELSE
|
||||
DO NnirAssert WITH 'locate_rand_vechi', 'ZERO', .F., 'nu s-a gasit randul cu nnir vechi in tact'
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
ENDIF
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
*=====================================================================================
|
||||
* Scenariul 6: nota de inventar (id_set=90101) pe sucursala CURENTA - blocarea NNIR trebuie sa
|
||||
* vina din regula 90101, nu din blocarea pe sucursala din AfterRowColChange. Scenariul 4 ruleaza
|
||||
* pe o nota din alta sucursala, unde SetAll("ReadOnly",.T.) blocheaza oricum tot gridul, deci ar
|
||||
* trece si fara implementare. Aici gnIdSucursala se aliniaza la id_sucursala notei (llReadOnly
|
||||
* iese .F.), se declanseaza AfterRowColChange (care face SetAll dupa Init) si se verifica ca
|
||||
* Column44 ramane blocata cat timp restul coloanelor sunt editabile.
|
||||
*=====================================================================================
|
||||
IF INLIST(tcMode, 'ALL', 'INVENTAR2')
|
||||
LOCAL lnCod6, lnAn6, lnLuna6, lnIdSet6
|
||||
LOCAL i6, llGasit6, llReadOnly6, lnEditabile6, lnSucVechi6, llMamaVechi6
|
||||
LOCAL lnIdSucNota6, lcColName6
|
||||
|
||||
lnCod6 = 1140716
|
||||
lnAn6 = 2026
|
||||
lnLuna6 = 3
|
||||
lnIdSet6 = 90101
|
||||
|
||||
DO NnirConstruiesteCursoare WITH lnCod6, lnAn6, lnLuna6
|
||||
|
||||
SELECT tact
|
||||
GO TOP
|
||||
lnIdSucNota6 = NVL(tact.id_sucursala, 0)
|
||||
lnSucVechi6 = gnIdSucursala
|
||||
llMamaVechi6 = glEMama
|
||||
gnIdSucursala = lnIdSucNota6
|
||||
glEMama = .F.
|
||||
|
||||
Omodif = CREATEOBJECT('frm_modific2024', lnIdSet6)
|
||||
IF VARTYPE(Omodif) <> 'O'
|
||||
DO NnirAssert WITH 'instantiere', 'INVENTAR2', .F., 'frm_modific2024 nu s-a instantiat'
|
||||
ELSE
|
||||
SELECT tact
|
||||
GO TOP
|
||||
Omodif.grid1.SetFocus
|
||||
Omodif.gridextra1.setup()
|
||||
Omodif.CalculeazaTotal()
|
||||
|
||||
* AfterRowColChange face SetAll("ReadOnly", llReadOnly) peste blocarea pusa in Init
|
||||
Omodif.grid1.AfterRowColChange(1)
|
||||
|
||||
llGasit6 = .F.
|
||||
llReadOnly6 = .F.
|
||||
lnEditabile6 = 0
|
||||
FOR i6 = 1 TO Omodif.grid1.ColumnCount
|
||||
lcColName6 = 'Omodif.grid1.Columns(' + TRANSFORM(i6) + ')'
|
||||
IF NnirEsteColoanaNnir(EVALUATE(lcColName6 + '.ControlSource'))
|
||||
llGasit6 = .T.
|
||||
llReadOnly6 = EVALUATE(lcColName6 + '.ReadOnly')
|
||||
ELSE
|
||||
IF !EVALUATE(lcColName6 + '.ReadOnly')
|
||||
lnEditabile6 = lnEditabile6 + 1
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDFOR
|
||||
|
||||
DO NnirAssert WITH 'coloana_grid', 'INVENTAR2', llGasit6, 'ControlSource=nnir gasit=' + TRANSFORM(llGasit6)
|
||||
* control: daca gridul e blocat integral, testul de blocare NNIR nu dovedeste nimic
|
||||
DO NnirAssert WITH 'grid_editabil', 'INVENTAR2', lnEditabile6 > 0, ;
|
||||
'coloane editabile (fara nnir): ' + TRANSFORM(lnEditabile6) + ' (asteptat > 0, ' + ;
|
||||
'gnIdSucursala=' + TRANSFORM(lnIdSucNota6) + ')'
|
||||
IF llGasit6
|
||||
DO NnirAssert WITH 'coloana_blocata', 'INVENTAR2', llReadOnly6, ;
|
||||
'id_set=90101 pe sucursala curenta: ReadOnly asteptat .T., gasit ' + TRANSFORM(llReadOnly6)
|
||||
ENDIF
|
||||
|
||||
Omodif.Release()
|
||||
Omodif = NULL
|
||||
ENDIF
|
||||
|
||||
gnIdSucursala = lnSucVechi6
|
||||
glEMama = llMamaVechi6
|
||||
DO NnirCurataCursoare
|
||||
ENDIF
|
||||
|
||||
DO NnirLog WITH 'REZULTAT SUITA: ' + TRANSFORM(gnPass) + ' PASS, ' + TRANSFORM(gnFail) + ' FAIL'
|
||||
QUIT
|
||||
|
||||
*=====================================================================================
|
||||
* proceduri ajutatoare (fara CREATEOBJECT - vezi depanare_testare_vfp.md / capcana l:
|
||||
* CREATEOBJECT apelat dintr-o procedura se comporta gresit in acest runtime headless)
|
||||
*=====================================================================================
|
||||
|
||||
PROCEDURE NnirLog
|
||||
LPARAMETERS tcMsg
|
||||
STRTOFILE(tcMsg + CHR(13)+CHR(10), gcLogFile, 1)
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NnirAssert
|
||||
LPARAMETERS tcPas, tcCaz, llOk, tcDetaliu
|
||||
LOCAL lcRez
|
||||
lcRez = IIF(llOk, 'PASS', 'FAIL')
|
||||
IF llOk
|
||||
gnPass = gnPass + 1
|
||||
ELSE
|
||||
gnFail = gnFail + 1
|
||||
ENDIF
|
||||
DO NnirLog WITH lcRez + ' [' + tcCaz + '/' + tcPas + '] ' + tcDetaliu
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NnirErr
|
||||
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
|
||||
DO NnirLog WITH 'ERR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
|
||||
ENDPROC
|
||||
|
||||
* verifica ca toate variabilele folosite ca ?param in SQL pass-through pe calea de test (env-init,
|
||||
* optiuni_firma, oscrie_in_fisiere, pack_contafin/pack_sesiune) sunt definite - o variabila
|
||||
* PUBLIC lipsa/umbrita da direct dialogul modal "Enter the value for <var>", nu o eroare catchabila
|
||||
FUNCTION NnirGardaVariabile
|
||||
LOCAL laVar(9), i, llOk
|
||||
laVar(1) = 'gnIdUtil'
|
||||
laVar(2) = 'gnAn'
|
||||
laVar(3) = 'gnLuna'
|
||||
laVar(4) = 'gnIdFirma'
|
||||
laVar(5) = 'gnIdSucursala'
|
||||
laVar(6) = 'gcS'
|
||||
laVar(7) = 'gnIdProgram'
|
||||
laVar(8) = 'gnId_Prg_Owner'
|
||||
laVar(9) = 'gnHandle'
|
||||
llOk = .T.
|
||||
FOR i = 1 TO ALEN(laVar)
|
||||
IF TYPE(laVar(i)) == 'U'
|
||||
DO NnirLog WITH 'FAIL [garda_variabile] ' + laVar(i) + ' nu exista (TYPE U) - ar fi dat dialog modal "Enter the value"'
|
||||
llOk = .F.
|
||||
ENDIF
|
||||
ENDFOR
|
||||
RETURN llOk
|
||||
ENDFUNC
|
||||
|
||||
* VFP calificat automat ControlSource-ul unui camp simplu cu aliasul cursorului (RecordSource) -
|
||||
* "nnir" definit in sursa apare la runtime ca "tact.nnir" - se accepta ambele forme
|
||||
FUNCTION NnirEsteColoanaNnir
|
||||
LPARAMETERS tcControlSource
|
||||
LOCAL lcCs
|
||||
lcCs = UPPER(ALLTRIM(TRANSFORM(tcControlSource)))
|
||||
RETURN lcCs == 'NNIR' OR RIGHT(lcCs, 5) == '.NNIR'
|
||||
ENDFUNC
|
||||
|
||||
* construieste tact/trul/trul_obinv exact ca afisjurcom.do_modifica (comun.vc2:2352-2434),
|
||||
* dar pe AN/LUNA proprii notei (nu gnAn/gnLuna) - vezi antetul fisierului
|
||||
PROCEDURE NnirConstruiesteCursoare
|
||||
LPARAMETERS tnCod, tnAn, tnLuna
|
||||
LOCAL lcSql, lnSucces
|
||||
|
||||
DO NnirCurataCursoare
|
||||
|
||||
lcSql = [select * from vact_tot where sters = 0 and an = ] + TRANSFORM(tnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(tnLuna) + [ and cod = ] + TRANSFORM(tnCod) + [ order by id_act]
|
||||
lnSucces = goExecutor.oExecute(lcSql, 'v_act')
|
||||
goExecutor.oReset()
|
||||
IF lnSucces < 0
|
||||
DO NnirLog WITH 'EROARE construire tact: ' + goExecutor.cEroare
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
SELECT * FROM v_act INTO CURSOR actactan
|
||||
SELECT .F. AS ales, T.*, CAST(0 AS N(2)) AS tipnota FROM actactan T INTO CURSOR tact READWRITE
|
||||
USE IN v_act
|
||||
|
||||
lcSql = [select * from vrul_tot where sters = 0 and an = ] + TRANSFORM(tnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(tnLuna) + [ and cod = ] + TRANSFORM(tnCod) + [ order by id_rul]
|
||||
goExecutor.oExecute(lcSql, 'v_rul')
|
||||
goExecutor.oReset()
|
||||
SELECT *, valoare + valtva AS valoarectva, valoarev + valtvav AS valoarevctva ;
|
||||
FROM v_rul INTO CURSOR RUL_TEMP READWRITE
|
||||
SELECT * FROM RUL_TEMP INTO CURSOR trul READWRITE
|
||||
USE IN v_rul
|
||||
|
||||
lcSql = [select * from vrul_obinv_tot where sters = 0 and an = ] + TRANSFORM(tnAn) + ;
|
||||
[ and luna = ] + TRANSFORM(tnLuna) + [ and cod = ] + TRANSFORM(tnCod) + [ order by id_rul_obinv]
|
||||
goExecutor.oExecute(lcSql, 'v_rul_obinv')
|
||||
goExecutor.oReset()
|
||||
SELECT *, valoare + valtva AS valoarectva, valoarev + valtvav AS valoarevctva ;
|
||||
FROM v_rul_obinv INTO CURSOR RUL_TEMP_OBINV READWRITE
|
||||
SELECT * FROM RUL_TEMP_OBINV INTO CURSOR trul_obinv READWRITE
|
||||
USE IN v_rul_obinv
|
||||
|
||||
SELECT a.*, IIF(NVL(a.id_jtva_coloana,0)=0,0,1) AS cu_tva FROM tact a INTO CURSOR tact READWRITE
|
||||
SELECT tact
|
||||
GO TOP
|
||||
RETURN .T.
|
||||
ENDPROC
|
||||
|
||||
PROCEDURE NnirCurataCursoare
|
||||
IF USED('tact')
|
||||
USE IN tact
|
||||
ENDIF
|
||||
IF USED('trul')
|
||||
USE IN trul
|
||||
ENDIF
|
||||
IF USED('trul_obinv')
|
||||
USE IN trul_obinv
|
||||
ENDIF
|
||||
IF USED('actactan')
|
||||
USE IN actactan
|
||||
ENDIF
|
||||
IF USED('rul_temp')
|
||||
USE IN rul_temp
|
||||
ENDIF
|
||||
IF USED('rul_temp_obinv')
|
||||
USE IN rul_temp_obinv
|
||||
ENDIF
|
||||
ENDPROC
|
||||
|
||||
FUNCTION NnirOraCount
|
||||
LPARAMETERS tcSql
|
||||
LOCAL lnVal, llOk
|
||||
lnVal = -1
|
||||
llOk = goExecutor.oExecuta(tcSql, 'cNnirOraCnt')
|
||||
IF llOk AND USED('cNnirOraCnt') AND RECCOUNT('cNnirOraCnt') > 0
|
||||
lnVal = cNnirOraCnt.cnt
|
||||
ENDIF
|
||||
IF USED('cNnirOraCnt')
|
||||
USE IN cNnirOraCnt
|
||||
ENDIF
|
||||
RETURN lnVal
|
||||
ENDFUNC
|
||||
|
||||
* verifica ca in Oracle nu s-a scris nimic dupa editarea DOAR in cursoare (echivalent Renunt)
|
||||
PROCEDURE NnirVerificaOracleNeschimbat
|
||||
LPARAMETERS tnCod, tnNnirVechi, tcCaz
|
||||
LOCAL lnCnt, lcSql
|
||||
lcSql = [select count(*) cnt from act where cod = ] + TRANSFORM(tnCod) + ;
|
||||
[ and nnir = ] + TRANSFORM(tnNnirVechi)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'renunt_neschimbat', tcCaz, lnCnt > 0, ;
|
||||
'ACT.NNIR in Oracle inainte de Termin ramane ' + TRANSFORM(tnNnirVechi) + ' (' + TRANSFORM(lnCnt) + ' randuri)'
|
||||
ENDPROC
|
||||
|
||||
* replica blocul de salvare din afisjurcom.do_modifica (comun.vc2:2456-2487): scrie tact/trul/
|
||||
* trul_obinv in ACT/RUL/RUL_OBINV prin oscrie_in_fisiere + pack_contafin.finalizeaza_modificare_
|
||||
* nota, verifica in Oracle, apoi reface valoarea originala (revert - baza de test ramane
|
||||
* neschimbata pentru rulari repetate)
|
||||
PROCEDURE NnirSalveazaSiVerifica
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tnIdSet, tnNnirVechi, tnNnirNou, tcCaz
|
||||
PRIVATE pnAn, pnLuna, pdDataOra
|
||||
LOCAL lnIdFact, lnIdfactd, llRul, lnSuccesSalvare, lcSqlFin, lnCnt, lcSql
|
||||
|
||||
pnAn = tnAn
|
||||
pnLuna = tnLuna
|
||||
pdDataOra = NULL
|
||||
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = tnNnirNou
|
||||
lnIdFact = NVL(id_fact, 0)
|
||||
lnIdfactd = NVL(id_factd, 0)
|
||||
|
||||
llRul = (RECCOUNT('trul') > 0) OR (RECCOUNT('trul_obinv') > 0)
|
||||
|
||||
* thisform.do_deschide_tranzactie()/do_inchide_tranzactie() din afisjurcom (_frm_base.vc2:252-
|
||||
* 305, mostenite, apelate pe formularul de jurnal, nu pe frm_modific2024) - echivalent direct,
|
||||
* fara instanta de forma: manual pe durata scrierii, apoi commit/rollback + revenire pe auto
|
||||
SQLSetProp(gnHandle, 'Transactions', 2)
|
||||
|
||||
* replica exact secventa din afisjurcom.do_modifica: intai STERGE nota veche (COD-ul
|
||||
* original, din actactan neatins de editare), abia apoi SCRIE varianta editata
|
||||
SELECT actactan
|
||||
lnSuccesSalvare = oscrie_in_fisiere(2, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere_sterge', tcCaz, lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SELECT * FROM tact INTO CURSOR actactan READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN actactan
|
||||
|
||||
IF llRul
|
||||
SELECT * FROM trul INTO CURSOR rul_temp READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp
|
||||
SELECT * FROM trul_obinv INTO CURSOR rul_temp_obinv READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp_obinv
|
||||
ENDIF
|
||||
|
||||
lnSuccesSalvare = oscrie_in_fisiere(0, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere', tcCaz, lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
lcSqlFin = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,?pdDataOra,] + ;
|
||||
TRANSFORM(tnIdSet) + [,] + TRANSFORM(tnCod) + [,] + TRANSFORM(lnIdFact) + [,] + ;
|
||||
TRANSFORM(lnIdfactd) + [,?gnIdUtil); end;]
|
||||
lnSuccesSalvare = IIF(goExecutor.oExecuta(lcSqlFin), 1, -1)
|
||||
DO NnirAssert WITH 'finalizeaza_modificare_nota', tcCaz, lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SQLCOMMIT(gnHandle)
|
||||
ELSE
|
||||
SQLROLLBACK(gnHandle)
|
||||
ENDIF
|
||||
SQLSetProp(gnHandle, 'Transactions', 1)
|
||||
|
||||
* Termin reatribuie COD nou (pack_contafin), sub AN/LUNA de sesiune curente - nu pastreaza
|
||||
* COD-ul original notei editate. Verificarea si curatenia se fac dupa valoarea NNIR marcaj
|
||||
* (distincta, nu poate coincide cu date reale), nu dupa COD-ul original.
|
||||
lcSql = [select count(*) cnt from act where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_act_final', tcCaz, lnCnt > 0, TRANSFORM(lnCnt) + ' randuri ACT cu nnir nou in Oracle'
|
||||
|
||||
IF RECCOUNT('trul') > 0
|
||||
lcSql = [select count(*) cnt from rul where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_rul_final', tcCaz, lnCnt > 0, TRANSFORM(lnCnt) + ' randuri RUL cu nnir nou in Oracle'
|
||||
ENDIF
|
||||
|
||||
* curatenie: pasul STERGE (oscrie_in_fisiere param 2) marcheaza sters=1 pe COD-ul ORIGINAL -
|
||||
* readuc nota originala activa, apoi marchez sters=1 (conventia aplicatiei) pe orice a ajuns
|
||||
* sub NNIR-ul marcaj (COD nou, atribuit de pack_contafin la scriere)
|
||||
goExecutor.oExecuta([update act set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update act set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta('commit')
|
||||
ENDPROC
|
||||
|
||||
* varianta pt. scenariul RUL_OBINV (verifica RUL_OBINV in loc de RUL)
|
||||
PROCEDURE NnirSalveazaSiVerificaObinv
|
||||
LPARAMETERS tnCod, tnAn, tnLuna, tnIdSet, tnNnirVechi, tnNnirNou
|
||||
PRIVATE pnAn, pnLuna, pdDataOra
|
||||
LOCAL lnIdFact, lnIdfactd, llRul, lnSuccesSalvare, lcSqlFin, lnCnt, lcSql
|
||||
|
||||
pnAn = tnAn
|
||||
pnLuna = tnLuna
|
||||
pdDataOra = NULL
|
||||
|
||||
SELECT tact
|
||||
LOCATE FOR NVL(nnir,0) = tnNnirNou
|
||||
lnIdFact = NVL(id_fact, 0)
|
||||
lnIdfactd = NVL(id_factd, 0)
|
||||
|
||||
llRul = (RECCOUNT('trul') > 0) OR (RECCOUNT('trul_obinv') > 0)
|
||||
|
||||
* thisform.do_deschide_tranzactie()/do_inchide_tranzactie() din afisjurcom (_frm_base.vc2:252-
|
||||
* 305, mostenite, apelate pe formularul de jurnal, nu pe frm_modific2024) - echivalent direct,
|
||||
* fara instanta de forma: manual pe durata scrierii, apoi commit/rollback + revenire pe auto
|
||||
SQLSetProp(gnHandle, 'Transactions', 2)
|
||||
|
||||
* replica exact secventa din afisjurcom.do_modifica: intai STERGE nota veche (COD-ul
|
||||
* original, din actactan neatins de editare), abia apoi SCRIE varianta editata
|
||||
SELECT actactan
|
||||
lnSuccesSalvare = oscrie_in_fisiere(2, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere_sterge', 'OBINV', lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SELECT * FROM tact INTO CURSOR actactan READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN actactan
|
||||
|
||||
IF llRul
|
||||
SELECT * FROM trul INTO CURSOR rul_temp READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp
|
||||
SELECT * FROM trul_obinv INTO CURSOR rul_temp_obinv READWRITE
|
||||
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0 IN rul_temp_obinv
|
||||
ENDIF
|
||||
|
||||
lnSuccesSalvare = oscrie_in_fisiere(0, .T., llRul)
|
||||
DO NnirAssert WITH 'oscrie_in_fisiere', 'OBINV', lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
lcSqlFin = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,?pdDataOra,] + ;
|
||||
TRANSFORM(tnIdSet) + [,] + TRANSFORM(tnCod) + [,] + TRANSFORM(lnIdFact) + [,] + ;
|
||||
TRANSFORM(lnIdfactd) + [,?gnIdUtil); end;]
|
||||
lnSuccesSalvare = IIF(goExecutor.oExecuta(lcSqlFin), 1, -1)
|
||||
DO NnirAssert WITH 'finalizeaza_modificare_nota', 'OBINV', lnSuccesSalvare > 0, 'a returnat ' + TRANSFORM(lnSuccesSalvare)
|
||||
ENDIF
|
||||
|
||||
IF lnSuccesSalvare > 0
|
||||
SQLCOMMIT(gnHandle)
|
||||
ELSE
|
||||
SQLROLLBACK(gnHandle)
|
||||
ENDIF
|
||||
SQLSetProp(gnHandle, 'Transactions', 1)
|
||||
|
||||
* Termin reatribuie COD nou (pack_contafin), sub AN/LUNA de sesiune curente - nu pastreaza
|
||||
* COD-ul original notei editate. Verificarea si curatenia se fac dupa valoarea NNIR marcaj
|
||||
* (distincta, nu poate coincide cu date reale), nu dupa COD-ul original.
|
||||
lcSql = [select count(*) cnt from act where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_act_final', 'OBINV', lnCnt > 0, TRANSFORM(lnCnt) + ' randuri ACT cu nnir nou in Oracle'
|
||||
|
||||
lcSql = [select count(*) cnt from rul_obinv where sters = 0 and nnir = ] + TRANSFORM(tnNnirNou)
|
||||
lnCnt = NnirOraCount(lcSql)
|
||||
DO NnirAssert WITH 'oracle_rul_obinv_final', 'OBINV', lnCnt > 0, TRANSFORM(lnCnt) + ' randuri RUL_OBINV cu nnir nou in Oracle'
|
||||
|
||||
* curatenie: pasul STERGE (oscrie_in_fisiere param 2) marcheaza sters=1 pe COD-ul ORIGINAL -
|
||||
* readuc nota originala activa, apoi marchez sters=1 (conventia aplicatiei) pe orice a ajuns
|
||||
* sub NNIR-ul marcaj (COD nou, atribuit de pack_contafin la scriere)
|
||||
goExecutor.oExecuta([update act set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 0 where cod = ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update act set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta([update rul_obinv set sters = 1 where nnir = ] + TRANSFORM(tnNnirNou) + [ and cod <> ] + TRANSFORM(tnCod))
|
||||
goExecutor.oExecuta('commit')
|
||||
ENDPROC
|
||||
11
utile/Teste/nnir_registru_jurnal/verif_nnir_cod.sql
Normal file
11
utile/Teste/nnir_registru_jurnal/verif_nnir_cod.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- verif_nnir_cod.sql - NNIR distinct pe ACT/RUL/RUL_OBINV pentru un COD dat
|
||||
-- Rulare: sqlplus -L -S MARIUSM_AUTO/<parola>@ROA_CENTRAL @verif_nnir_cod.sql <cod>
|
||||
set pagesize 200 linesize 200 trimspool on feedback off
|
||||
define v_cod = &1
|
||||
prompt ==ACT==
|
||||
select cod, an, luna, id_set, nnir from act where cod = &v_cod;
|
||||
prompt ==RUL_NNIR_DISTINCT==
|
||||
select an, luna, nnir, count(*) cnt from rul where cod = &v_cod group by an, luna, nnir;
|
||||
prompt ==RUL_OBINV_NNIR_DISTINCT==
|
||||
select an, luna, nnir, count(*) cnt from rul_obinv where cod = &v_cod group by an, luna, nnir;
|
||||
exit;
|
||||
302
utile/Teste/test_init_env_auto_roagest.prg
Normal file
302
utile/Teste/test_init_env_auto_roagest.prg
Normal file
@@ -0,0 +1,302 @@
|
||||
* test_init_env_auto_roagest.prg
|
||||
* Varianta ROAGEST a test_init_env_auto.prg (acel fisier e specializat pe ROACONT -
|
||||
* gcAppPath/clase/proceduri hardcodate D:\ROA\ROACONT\ - nu poate initializa mediul ROAGEST).
|
||||
* Initializare completa de mediu FARA interactiune, pentru vfp9.exe -A -T.
|
||||
*
|
||||
* Utilizare:
|
||||
* DO test_init_env_auto_roagest WITH 'CENTRAL', 'MARIUSM_AUTO', 'parola'
|
||||
* IF gnHandle <= 0 ... eroare conectare
|
||||
*
|
||||
* Dupa apel sunt disponibile: goConn/goExecutor/goApp/goLog/goApi, goFirma/goCalendar,
|
||||
* gnAn/gnLuna/gcS/gnIdFirma etc., SET PATH/CLASSLIB/PROCEDURE ca in roagest.prg,
|
||||
* pachetele Oracle de sesiune setate (pack_sesiune/pack_contafin).
|
||||
* ATENTIE: mentine lista de SET CLASSLIB/PROCEDURE sincronizata cu Programe\roagest.prg.
|
||||
|
||||
LPARAMETERS tcHost, tcSchema, tcPassword, tnAn, tnLuna
|
||||
|
||||
tcHost = IIF(EMPTY(tcHost), 'CENTRAL', tcHost)
|
||||
tcSchema = IIF(EMPTY(tcSchema), 'MARIUSM_AUTO', tcSchema)
|
||||
tcPassword = IIF(EMPTY(tcPassword), 'ROMFASTSOFT', tcPassword)
|
||||
|
||||
SET DELETED ON
|
||||
SET ANSI ON
|
||||
SET EXACT ON
|
||||
SET SAFETY OFF
|
||||
CLOSE DATABASES
|
||||
SET CENTURY ON
|
||||
SET DATE DMY
|
||||
SET NULLDISPLAY TO ''
|
||||
SET DECIMALS TO 4
|
||||
SET POINT TO '.'
|
||||
|
||||
PUBLIC CT_SUCCES, CT_INSUCCES, crlf, gnAn, gnLuna, gnIdUtil, glEMama, gnIdFirma, gcCondSucursala, ;
|
||||
gnIdSucursala, gcS, gcFirma, gcUserName, gcUserNameApp, gcNumeProgram, gcAppName, glLunaInchisa, ;
|
||||
buton, gnButon, pnButon, gl406, gcAcces, gnIdProgram, gnId_Prg_Owner
|
||||
CT_SUCCES = 1
|
||||
CT_INSUCCES = -1
|
||||
crlf = CHR(13) + CHR(10)
|
||||
gnAn = IIF(EMPTY(tnAn), YEAR(DATE()), tnAn)
|
||||
gnLuna = IIF(EMPTY(tnLuna), MONTH(DATE()), tnLuna)
|
||||
gnIdUtil = -3
|
||||
gnIdProgram = 0
|
||||
gnId_Prg_Owner = 0
|
||||
gnIdFirma = 110
|
||||
gcCondSucursala = []
|
||||
gnIdSucursala = m.gnIdFirma
|
||||
gcS = UPPER(ALLTRIM(tcSchema))
|
||||
gcFirma = m.gcS
|
||||
gcUserName = m.gcS
|
||||
gcUserNameApp = [MARIUS M]
|
||||
gcNumeProgram = [ROAGEST]
|
||||
gcAppName = [ROAGEST]
|
||||
glLunaInchisa = .F.
|
||||
glEMama = .F.
|
||||
gl406 = .F.
|
||||
* PUBLIC, nu Declare: nrcrt() (oproceduri_comune.prg) citeste NROR din ControlSource-uri
|
||||
* de grid mult dupa ce acest program s-a terminat (Declare ar muri la RETURN)
|
||||
PUBLIC nror(65000)
|
||||
buton = 1
|
||||
gnButon = 1
|
||||
pnButon = 1
|
||||
|
||||
LOCAL lcPath
|
||||
PUBLIC gcAppPath, DIRGEN, gcDirMare, gcBasePath, gcTempPath, gcGeneralIniFile, gcSettingsFile, ;
|
||||
gcSecurityPath, gcSecurityFile
|
||||
gcAppPath = [D:\ROA\ROAGEST\]
|
||||
Set Default To (gcAppPath)
|
||||
lcPath = gcAppPath + 'Date;' + ;
|
||||
gcAppPath + 'Include;' + ;
|
||||
gcAppPath + 'FERESTRE;' + ;
|
||||
gcAppPath + 'GRAFICE;' + ;
|
||||
gcAppPath + 'CLASE;' + ;
|
||||
gcAppPath + 'MENIURI;' + ;
|
||||
gcAppPath + 'PROGRAME;' + ;
|
||||
gcAppPath + 'RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN;' + ;
|
||||
gcAppPath + 'COMUN\CLASE;' + ;
|
||||
gcAppPath + 'COMUN\FERESTRE;' + ;
|
||||
gcAppPath + 'COMUN\PROGRAME;' + ;
|
||||
gcAppPath + 'COMUN\GRAFICE;' + ;
|
||||
gcAppPath + 'COMUN\RAPOARTE;' + ;
|
||||
gcAppPath + 'COMUN\MENIURI;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\CTL32;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\WEB;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
|
||||
gcAppPath + 'COMUN\UTILE\NFJSON;' + ;
|
||||
Addbs(Substr(gcAppPath,1,Rat([\],gcAppPath,2)))+[COMUNROA\]
|
||||
SET PATH TO &lcPath ADDITIVE
|
||||
|
||||
Local lcMainClassLib
|
||||
lcMainClassLib = gcAppPath + "comun\clase\appwiz"
|
||||
SET CLASSLIB TO (lcMainClassLib) ADDITIVE
|
||||
SET CLASSLIB TO GESTIUNI ADDITIVE
|
||||
SET CLASSLIB TO CAUT ADDITIVE
|
||||
SET CLASSLIB TO BAZA ADDITIVE
|
||||
SET CLASSLIB TO comun ADDITIVE
|
||||
SET CLASSLIB TO accessibility.vcx ADDITIVE
|
||||
SET CLASSLIB TO messagebox ADDITIVE
|
||||
SET CLASSLIB TO registry ADDITIVE
|
||||
SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
|
||||
SET CLASSLIB TO DECABAZA ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare ADDITIVE
|
||||
SET CLASSLIB TO stocuri.vcx ADDITIVE
|
||||
SET CLASSLIB TO rulaje.vcx ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri_web ADDITIVE
|
||||
SET CLASSLIB TO ointroduceri_depozit ADDITIVE
|
||||
SET CLASSLIB TO overificari ADDITIVE
|
||||
SET CLASSLIB TO ferestre_oracle ADDITIVE
|
||||
SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
|
||||
SET CLASSLIB TO configurare.vcx ADDITIVE
|
||||
SET CLASSLIB TO serii_numere.vcx ADDITIVE
|
||||
SET CLASSLIB TO omodificari.vcx ADDITIVE
|
||||
SET CLASSLIB TO ocompensari.vcx ADDITIVE
|
||||
SET CLASSLIB TO caut_ora ADDITIVE
|
||||
SET CLASSLIB TO onote_contabile ADDITIVE
|
||||
SET CLASSLIB TO otoolbar ADDITIVE
|
||||
SET CLASSLIB TO bon_fisc ADDITIVE
|
||||
SET CLASSLIB TO onom_articole ADDITIVE
|
||||
SET CLASSLIB TO onom_retete ADDITIVE
|
||||
Set Classlib To oinventar ADDITIVE
|
||||
SET CLASSLIB TO orapoarte ADDITIVE
|
||||
SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
|
||||
SET CLASSLIB TO orapoarte_parametri ADDITIVE
|
||||
SET CLASSLIB TO ONOM_CURS ADDITIVE
|
||||
SET CLASSLIB TO ctl32_statusbar_fals.vcx additive
|
||||
SET CLASSLIB TO ctl32_common.vcx additive
|
||||
SET CLASSLIB TO ctl32_structs.vcx additive
|
||||
SET CLASSLIB TO ctl32_progressbar.vcx additive
|
||||
SET CLASSLIB TO ctl32_balloontip.vcx additive
|
||||
SET CLASSLIB TO ocriterii.vcx ADDITIVE
|
||||
SET CLASSLIB TO oavize.vcx ADDITIVE
|
||||
SET CLASSLIB TO onomenclatoare2 ADDITIVE
|
||||
Set Classlib To oschimbare_pret.vcx additive
|
||||
SET CLASSLIB TO wwdialogs.vcx additive
|
||||
SET CLASSLIB TO oimportxml.vcx additive
|
||||
SET CLASSLIB TO excelxml.vcx ADDITIVE
|
||||
SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
|
||||
SET CLASSLIB TO locale ADDITIVE
|
||||
|
||||
SET PROCEDURE TO PROCEDURI ADDITIVE
|
||||
SET PROCEDURE TO acces_meniu ADDITIVE
|
||||
SET PROCEDURE TO cauta_alfa ADDITIVE
|
||||
SET PROCEDURE TO pmenu ADDITIVE
|
||||
SET PROCEDURE TO proceduri_comune ADDITIVE
|
||||
SET PROCEDURE TO quitapp ADDITIVE
|
||||
SET PROCEDURE TO init_program ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
|
||||
SET PROCEDURE TO orapoarte.prg ADDITIVE
|
||||
SET PROCEDURE TO mesaje ADDITIVE
|
||||
SET PROCEDURE TO oserii_numere.prg ADDITIVE
|
||||
SET PROCEDURE TO oexport.prg ADDITIVE
|
||||
SET PROCEDURE TO wwConfig.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_rapoarte.prg additive
|
||||
SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
|
||||
Set procedure to orapoarte_dinamice.prg additive
|
||||
SET PROCEDURE TO validare.prg additive
|
||||
SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
|
||||
SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
|
||||
SET PROCEDURE TO updateserver.prg ADDITIVE
|
||||
SET PROCEDURE TO oinainte_de.prg ADDITIVE
|
||||
SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
|
||||
SET PROCEDURE TO Ocompensari.PRG ADDITIVE
|
||||
SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_rulaje additive
|
||||
SET PROCEDURE TO oproceduri_stocuri additive
|
||||
SET PROCEDURE TO OINTRODUCERI ADDITIVE
|
||||
SET PROCEDURE TO oHeader.prg ADDITIVE
|
||||
SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
|
||||
SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
|
||||
SET PROCEDURE TO osecurity ADDITIVE
|
||||
SET PROCEDURE TO ocautare ADDITIVE
|
||||
SET PROCEDURE TO orefaceri ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
|
||||
SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_util.prg ADDITIVE
|
||||
SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
|
||||
SET PROCEDURE TO ini.prg ADDITIVE
|
||||
SET PROCEDURE TO odocumente.prg ADDITIVE
|
||||
SET PROCEDURE TO regex.prg ADDITIVE
|
||||
SET PROCEDURE TO wwutils.prg ADDITIVE
|
||||
SET PROCEDURE TO inchidere_k ADDITIVE
|
||||
Set procedure to oschimbare_pret.prg additive
|
||||
SET PROCEDURE TO iniacces.prg ADDITIVE
|
||||
SET PROCEDURE TO oupdate.prg additive
|
||||
SET PROCEDURE TO procese.prg additive
|
||||
SET PROCEDURE TO version.prg additive
|
||||
SET PROCEDURE TO xmlaccess.prg additive
|
||||
SET PROCEDURE TO xmlparser.prg additive
|
||||
SET PROCEDURE TO filebringer.prg additive
|
||||
SET PROCEDURE TO wwcodeupdate.prg additive
|
||||
SET PROCEDURE TO wwhttp.prg ADDITIVE
|
||||
Set Procedure To wwApi.prg Additive
|
||||
SET PROCEDURE TO xdate.prg Additive
|
||||
SET PROCEDURE TO ofacturare.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
|
||||
SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
|
||||
SET PROCEDURE TO email.prg ADDITIVE
|
||||
|
||||
Declare Integer GetPrivateProfileString In WIN32API ;
|
||||
string, String, String, String @, Integer, String
|
||||
Declare Integer WritePrivateProfileString In Win32Api ;
|
||||
string, String, String, String
|
||||
Declare Integer CopyFile In WIN32API ;
|
||||
STRING lpExistingFileName, STRING lpNewFileName, INTEGER bFailIfExists
|
||||
Declare Integer PathFileExists In shlwapi STRING pszPath
|
||||
|
||||
If Type('goApi') = 'U'
|
||||
Public goApi
|
||||
goApi = Newobject("wwAPI", "wwAPI.prg")
|
||||
ENDIF
|
||||
|
||||
PUBLIC gnHandle, goExecutor, goConn, goFirma, goCalendar, poLog, goLog, goApp
|
||||
DIRGEN = [D:\ROA\]
|
||||
gcDirMare = DIRGEN
|
||||
gcBasePath = dirgen
|
||||
gcSecurityPath = DIRGEN + 'Security\'
|
||||
gcSecurityFile = gcSecurityPath + 'ROA_SECURITY.TXT'
|
||||
gcGeneralIniFile = DIRGEN + "settings.ini"
|
||||
gcSettingsFile = m.gcGeneralIniFile
|
||||
gcTempPath = Addbs(shortpath(goApi.GetTempPath())) + gcS + [\]
|
||||
If !Directory(gcTempPath)
|
||||
Md (gcTempPath)
|
||||
Endif
|
||||
gcAcces = [1;2;3;4;5;6;7;8;]
|
||||
|
||||
poLog = Newobject("Log_Mesaje","Log_Mesaje.prg")
|
||||
goLog = poLog
|
||||
goApp = Createobject("wzApplication")
|
||||
gnHandle = 0
|
||||
goExecutor = createobject("oExecutor")
|
||||
goConn = createobject("oConn")
|
||||
goConn.Connect(m.tcHost, m.tcSchema, m.tcPassword)
|
||||
IF m.gnHandle <= 0
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
LOCAL llSucces, lcSql
|
||||
goFirma = null
|
||||
llSucces = goExecutor.oExecuta("select * from syn_v_nom_firme where schema = ?gcS", "cFirma")
|
||||
IF m.llSucces
|
||||
SELECT cFirma
|
||||
gnIdFirma = id_firma
|
||||
gnIdSucursala = null
|
||||
gcFirma = ALLTRIM(firma)
|
||||
SCATTER NAME goFirma
|
||||
IF TYPE('goFirma.codfiscalfro') = 'U'
|
||||
ADDPROPERTY(goFirma, 'codfiscalfro', ALLTRIM(STRTRAN(ALLTRIM(NVL(goFirma.cod_fiscal, '')), 'RO', '')))
|
||||
ENDIF
|
||||
ELSE
|
||||
goFirma = CREATEOBJECT('custom')
|
||||
goFirma.addproperty('cod_fiscal', '')
|
||||
goFirma.addproperty('schema', m.gcS)
|
||||
goFirma.addproperty('firma', m.gcS)
|
||||
goFirma.addproperty('codfiscalfro', '')
|
||||
ENDIF
|
||||
USE IN (SELECT('cFirma'))
|
||||
|
||||
goCalendar = null
|
||||
llSucces = goExecutor.oExecuta('SELECT anul, luna, tva_incasare FROM calendar WHERE an*12+luna = (select MAX(an*12+luna) FROM calendar)', 'cCalendar')
|
||||
IF m.llSucces
|
||||
SELECT cCalendar
|
||||
GO TOP
|
||||
IF EMPTY(m.tnAn)
|
||||
gnAn = anul
|
||||
gnLuna = luna
|
||||
ENDIF
|
||||
SCATTER NAME goCalendar
|
||||
ENDIF
|
||||
USE IN (SELECT('cCalendar'))
|
||||
|
||||
CREATE CURSOR dual (dummy c(10))
|
||||
INSERT INTO dual (dummy) VALUES ("")
|
||||
|
||||
actualizeaza_optiuni()
|
||||
Do optiuni_firma IN oinit_optiuni.prg
|
||||
|
||||
lcSql = [begin pack_sesiune.set_Id_Util(?gnIdUtil); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_sesiune.setluna(?gnLuna); pack_sesiune.setan(?gnAn); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_sesiune.setlunabal(?gnLuna); pack_sesiune.setanbal(?gnAn); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_contafin.SET_DATA_RON(?gcS); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_sesiune.set_data_ron(?gcS); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_contafin.set_id_sucursala(?gnIdSucursala); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
lcSql = [begin pack_contafin.set_id_firma(?gnIdFirma); end;]
|
||||
llSucces = goExecutor.oExecuta(lcSql)
|
||||
|
||||
RETURN .T.
|
||||
14
utile/Teste/watchdog_selftest.prg
Normal file
14
utile/Teste/watchdog_selftest.prg
Normal file
@@ -0,0 +1,14 @@
|
||||
* watchdog_selftest.prg - caz banal pentru validarea watchdog_vfp.ps1: afiseaza un MESSAGEBOX
|
||||
* nativ (OK/Cancel) si asteapta. Foloseste doar pentru testarea utilitarului, nu face parte
|
||||
* din nicio suita de regresie.
|
||||
SET SAFETY OFF
|
||||
SET TALK OFF
|
||||
|
||||
LOCAL lcLog
|
||||
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\watchdog_selftest_log.txt'
|
||||
STRTOFILE('start' + CHR(13) + CHR(10), lcLog)
|
||||
|
||||
= MESSAGEBOX('Mesaj de test watchdog_vfp.ps1', 1, 'Watchdog selftest')
|
||||
|
||||
STRTOFILE('done' + CHR(13) + CHR(10), lcLog, 1)
|
||||
QUIT
|
||||
390
utile/Teste/watchdog_vfp.ps1
Normal file
390
utile/Teste/watchdog_vfp.ps1
Normal file
@@ -0,0 +1,390 @@
|
||||
# watchdog_vfp.ps1 - lanseaza un test VFP headless si detecteaza dialoguri native blocante
|
||||
# (mesaje Windows, "View Parameter", erori modale) care nu apar in logul scris de script si
|
||||
# nu sunt prinse de ON ERROR / mock-uri - cazul clasic de proces "agatat" cu CPU~0.
|
||||
#
|
||||
# Ce face: sterge .fxp-ul vechi, lanseaza `vfp9.exe -A -T "<script>"`, apoi polleaza la interval
|
||||
# scurt ferestrele TOP-LEVEL ale procesului (EnumWindows + GetWindowThreadProcessId). Fereastra
|
||||
# principala VFP se identifica prin Process.MainWindowHandle (.NET) - NU dupa numele clasei:
|
||||
# VFP inregistreaza clase diferite prefixate "vfp9..." atat pentru shell-ul principal cat si
|
||||
# pentru dialogurile proprii (ex. "View Parameter"), deci clasificarea pe clasa e nesigura.
|
||||
# Orice fereastra NOUA, diferita de MainWindowHandle, e tratata ca dialog blocant.
|
||||
#
|
||||
# Pentru fiecare dialog detectat: captura PNG (PrintWindow, fallback CopyFromScreen daca iese
|
||||
# neagra) + dump text (titlu, clasa, si textul/clasa fiecarui control copil via WM_GETTEXT - se
|
||||
# citesc controale native Windows chiar daca apartin unui proces strain pe alta arhitectura).
|
||||
#
|
||||
# INTERZIS: watchdog-ul NU are voie sa foloseasca input real de tastatura/mouse (keybd_event,
|
||||
# SetForegroundWindow, SendInput, mouse_event) - masina e PARTAJATA cu utilizatorul, iar un
|
||||
# ESCAPE/click injectat la nivel de sistem ajunge in orice fereastra are focus in acel moment,
|
||||
# nu neaparat in dialogul tintit (verificat: a ajuns in IDE-ul VFP al utilizatorului aflat in
|
||||
# lucru in paralel, intrerupandu-l). -AutoDismiss foloseste STRICT mesaje Windows tintite pe
|
||||
# handle-ul dialogului: buton copil cu text Cancel/Anulare/Renunta -> BM_CLICK; altfel
|
||||
# WM_COMMAND IDCANCEL -> ESCAPE ca mesaj (WM_KEYDOWN/WM_KEYUP, nu input real) -> WM_CLOSE, in
|
||||
# ordine, primul care inchide fereastra castiga. Dialogurile proprii VFP owner-drawn (ex.
|
||||
# "View Parameter" - butoanele sunt desenate, nu HWND-uri reale) pot sa NU raspunda la niciunul -
|
||||
# atunci dismiss-ul ESUEAZA CINSTIT (ramane deschis pana la timeout), nu se cade pe input real.
|
||||
# Captura (PNG+dump text) e intotdeauna de incredere, indiferent de rezultatul dismiss-ului.
|
||||
# Continua polling-ul dupa fiecare dismiss reusit, ca sa prinda si eventuale dialoguri urmatoare
|
||||
# (pana la -MaxDialogs). Fara -AutoDismiss: captureaza primul dialog gasit, apoi opreste
|
||||
# polling-ul (nu-l atinge).
|
||||
#
|
||||
# Procesul e omorat mereu la iesire (finally) - nu ramane niciodata viu.
|
||||
#
|
||||
# Utilizare:
|
||||
# powershell -ExecutionPolicy Bypass -File watchdog_vfp.ps1 -Script "D:\...\test_x.prg" -AutoDismiss
|
||||
# powershell -ExecutionPolicy Bypass -File watchdog_vfp.ps1 -Script "D:\...\test_x.prg" -TimeoutSec 60 -OutDir "D:\...\out"
|
||||
#
|
||||
# Parametri:
|
||||
# -Script cale completa la .prg de rulat (obligatoriu)
|
||||
# -Vfp cale la vfp9.exe (implicit instalarea standard x86)
|
||||
# -TimeoutSec timeout total de polling (implicit 90)
|
||||
# -OutDir folder pentru PNG-uri + log text (implicit "<folderul scriptului>\watchdog_out")
|
||||
# -AutoDismiss inchide automat dialogurile gasite (Cancel/WM_CLOSE) si continua polling-ul
|
||||
# -MaxDialogs cate dialoguri succesive sa trateze cu -AutoDismiss (implicit 10)
|
||||
#
|
||||
# Iesire: rezumat pe stdout (numar dialoguri, textul fiecaruia, caile PNG, exit code-ul
|
||||
# procesului) + acelasi continut scris in "<Script>_watchdog.log" din -OutDir.
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Script,
|
||||
[string]$Vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe',
|
||||
[int]$TimeoutSec = 90,
|
||||
[string]$OutDir,
|
||||
[switch]$AutoDismiss,
|
||||
[int]$MaxDialogs = 10
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path $Script)) { throw "Nu gasesc scriptul: $Script" }
|
||||
$Script = (Resolve-Path $Script).Path
|
||||
$ScriptDir = [System.IO.Path]::GetDirectoryName($Script)
|
||||
$ScriptBase = [System.IO.Path]::GetFileNameWithoutExtension($Script)
|
||||
if (-not $OutDir) { $OutDir = Join-Path $ScriptDir 'watchdog_out' }
|
||||
if (-not (Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null }
|
||||
$LogPath = Join-Path $OutDir ($ScriptBase + '_watchdog.log')
|
||||
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
Add-Type @"
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class WdWin32 {
|
||||
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool IsWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
|
||||
public static extern IntPtr SendMessageText(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT { public int Left, Top, Right, Bottom; }
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, uint nFlags);
|
||||
}
|
||||
"@
|
||||
|
||||
$WM_GETTEXT = 0x000D
|
||||
$WM_CLOSE = 0x0010
|
||||
$BM_CLICK = 0x00F5
|
||||
|
||||
function Get-TopWindowsForPid([int]$ProcId) {
|
||||
$result = New-Object System.Collections.Generic.List[IntPtr]
|
||||
$cb = {
|
||||
param($hWnd, $lParam)
|
||||
$owner = 0
|
||||
[void][WdWin32]::GetWindowThreadProcessId($hWnd, [ref]$owner)
|
||||
if ($owner -eq $ProcId -and [WdWin32]::IsWindowVisible($hWnd)) { $result.Add($hWnd) }
|
||||
return $true
|
||||
}
|
||||
[WdWin32]::EnumWindows($cb, [IntPtr]::Zero) | Out-Null
|
||||
return $result
|
||||
}
|
||||
|
||||
function Get-ChildWindowsOf([IntPtr]$hWndParent) {
|
||||
$result = New-Object System.Collections.Generic.List[IntPtr]
|
||||
$cb = {
|
||||
param($hWnd, $lParam)
|
||||
$result.Add($hWnd)
|
||||
return $true
|
||||
}
|
||||
[WdWin32]::EnumChildWindows($hWndParent, $cb, [IntPtr]::Zero) | Out-Null
|
||||
return $result
|
||||
}
|
||||
|
||||
# WM_GETTEXT (nu GetWindowText) - citeste text de la controale ale unui proces strain, indiferent
|
||||
# de arhitectura (32/64 bit); GetWindowText poate esua tacut pe controale custom VFP.
|
||||
function Get-WmText([IntPtr]$hWnd, [int]$MaxLen = 1024) {
|
||||
$sb = New-Object System.Text.StringBuilder $MaxLen
|
||||
[WdWin32]::SendMessageText($hWnd, $WM_GETTEXT, $MaxLen, $sb) | Out-Null
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
function Get-WinClassName([IntPtr]$hWnd) {
|
||||
$sb = New-Object System.Text.StringBuilder 256
|
||||
[WdWin32]::GetClassName($hWnd, $sb, $sb.Capacity) | Out-Null
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
function Test-BitmapAllBlack([System.Drawing.Bitmap]$bmp) {
|
||||
$w = $bmp.Width; $h = $bmp.Height
|
||||
if ($w -le 0 -or $h -le 0) { return $true }
|
||||
for ($i = 0; $i -lt 9; $i++) {
|
||||
$x = [Math]::Min($w - 1, [int]($w * (($i % 3) + 0.5) / 3))
|
||||
$y = [Math]::Min($h - 1, [int]($h * ([Math]::Floor($i / 3) + 0.5) / 3))
|
||||
$px = $bmp.GetPixel($x, $y)
|
||||
if ($px.R -ne 0 -or $px.G -ne 0 -or $px.B -ne 0) { return $false }
|
||||
}
|
||||
return $true
|
||||
}
|
||||
|
||||
# PrintWindow direct pe handle; fallback CopyFromScreen daca iese neagra (fereastra themed/GDI+
|
||||
# care nu se randeaza corect prin PrintWindow). Foloseste doar pentru dialoguri surprinse
|
||||
# on-screen - nu se muta off-screen aici (spre deosebire de vfp_ui_harness.ps1), fiindca scopul
|
||||
# e sa surprindem exact dialogul care blocheaza, o singura data.
|
||||
function Save-DialogScreenshot([IntPtr]$hWnd, [string]$Path) {
|
||||
$rect = New-Object WdWin32+RECT
|
||||
[WdWin32]::GetWindowRect($hWnd, [ref]$rect) | Out-Null
|
||||
$w = $rect.Right - $rect.Left
|
||||
$h = $rect.Bottom - $rect.Top
|
||||
if ($w -le 0 -or $h -le 0) { return $false }
|
||||
$bmp = New-Object System.Drawing.Bitmap $w, $h
|
||||
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
$hdc = $g.GetHdc()
|
||||
$ok = [WdWin32]::PrintWindow($hWnd, $hdc, 2)
|
||||
$g.ReleaseHdc($hdc)
|
||||
$g.Dispose()
|
||||
if ((-not $ok) -or (Test-BitmapAllBlack $bmp)) {
|
||||
$bmp.Dispose()
|
||||
$bmp = New-Object System.Drawing.Bitmap $w, $h
|
||||
$g2 = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
try { $g2.CopyFromScreen($rect.Left, $rect.Top, 0, 0, (New-Object System.Drawing.Size $w, $h)) } catch {}
|
||||
$g2.Dispose()
|
||||
}
|
||||
$bmp.Save($Path, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||
$bmp.Dispose()
|
||||
return $true
|
||||
}
|
||||
|
||||
function Get-DialogDump([IntPtr]$hWnd, [System.Collections.Generic.List[IntPtr]]$children) {
|
||||
$title = Get-WmText $hWnd
|
||||
$class = Get-WinClassName $hWnd
|
||||
$lines = New-Object System.Collections.Generic.List[string]
|
||||
$lines.Add("dialog hwnd=$hWnd class='$class' title='$title'")
|
||||
foreach ($c in $children) {
|
||||
$ct = (Get-WmText $c 512).Trim()
|
||||
$cc = Get-WinClassName $c
|
||||
if ($ct -or $cc) { $lines.Add(" child hwnd=$c class='$cc' text='$ct'") }
|
||||
}
|
||||
# unary comma obligatoriu: fara ea, un List[string] cu UN SINGUR element (dialog fara copii,
|
||||
# ex. "View Parameter") e "descompus" de PowerShell la scalar string simplu la return, iar
|
||||
# indexarea ulterioara $dumpLines[0] citeste primul CARACTER, nu primul rand - prins la testul
|
||||
# pe test_page3_articole.prg (rezumatul arata titlul "d" in loc de linia intreaga)
|
||||
return , $lines.ToArray()
|
||||
}
|
||||
|
||||
function Find-DismissButton([System.Collections.Generic.List[IntPtr]]$children) {
|
||||
foreach ($c in $children) {
|
||||
if ((Get-WinClassName $c) -ne 'Button') { continue }
|
||||
$txt = ((Get-WmText $c 256) -replace '&', '').Trim()
|
||||
if ($txt -ieq 'Cancel' -or $txt -ieq 'Anulare' -or $txt -ieq 'Renunta' -or $txt -ieq 'Renunță') { return $c }
|
||||
}
|
||||
return [IntPtr]::Zero
|
||||
}
|
||||
|
||||
$WM_COMMAND = 0x0111
|
||||
$WM_KEYDOWN = 0x0100
|
||||
$WM_KEYUP = 0x0101
|
||||
$VK_ESCAPE = 0x1B
|
||||
$IDCANCEL = 2
|
||||
|
||||
# INTERZIS: input real de tastatura/mouse (keybd_event, SetForegroundWindow, SendInput,
|
||||
# mouse_event). Masina e PARTAJATA cu utilizatorul - un ESCAPE injectat la nivel de sistem
|
||||
# ajunge in orice fereastra are focus in acel moment, INDIFERENT carui proces ii apartine
|
||||
# (verificat: a ajuns in IDE-ul VFP al utilizatorului, aflat in lucru in paralel, intrerupandu-l
|
||||
# cu o eroare + "Execution was canceled by the user"). Foloseste STRICT mesaje Windows tintite pe
|
||||
# HANDLE-ul dialogului (PostMessage/SendMessage: WM_COMMAND IDCANCEL, WM_KEYDOWN/WM_KEYUP
|
||||
# VK_ESCAPE, WM_CLOSE, BM_CLICK) - astea nu ating focusul/inputul global, raman izolate la
|
||||
# fereastra tintita. Dialogurile native VFP proprii (ex. "View Parameter") NU au controale copil
|
||||
# reale (owner-drawn) si pot sa NU raspunda la niciunul dintre mesajele de mai jos - in acel caz
|
||||
# dismiss-ul ESUEAZA CINSTIT (dialogul ramane deschis, procesul e omorat la timeout de finally),
|
||||
# nu se cade pe input real. Captura (PNG+dump text) ramane oricum de incredere, indiferent de
|
||||
# rezultatul dismiss-ului.
|
||||
function Dismiss-Dialog([IntPtr]$hWnd, [System.Collections.Generic.List[IntPtr]]$children) {
|
||||
$btn = Find-DismissButton $children
|
||||
if ($btn -ne [IntPtr]::Zero) {
|
||||
[WdWin32]::SendMessage($btn, $BM_CLICK, [IntPtr]::Zero, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'click Cancel/Anulare' }
|
||||
return 'NEREUSIT: BM_CLICK pe Cancel/Anulare nu a inchis dialogul'
|
||||
}
|
||||
|
||||
[WdWin32]::SendMessage($hWnd, $WM_COMMAND, [IntPtr]$IDCANCEL, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'WM_COMMAND IDCANCEL' }
|
||||
|
||||
[WdWin32]::SendMessage($hWnd, $WM_KEYDOWN, [IntPtr]$VK_ESCAPE, [IntPtr]::Zero) | Out-Null
|
||||
[WdWin32]::SendMessage($hWnd, $WM_KEYUP, [IntPtr]$VK_ESCAPE, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'tasta ESCAPE trimisa cu SendMessage (mesaj, nu input real)' }
|
||||
|
||||
[WdWin32]::SendMessage($hWnd, $WM_CLOSE, [IntPtr]::Zero, [IntPtr]::Zero) | Out-Null
|
||||
Start-Sleep -Milliseconds 300
|
||||
if (-not [WdWin32]::IsWindow($hWnd)) { return 'WM_CLOSE' }
|
||||
|
||||
$motiv = if ($children.Count -eq 0) { 'fara controale copil (owner-drawn) si niciun mesaj tintit nu a functionat' } else { 'niciun mesaj tintit (WM_COMMAND/ESCAPE mesaj/WM_CLOSE) nu a functionat' }
|
||||
return "NEREUSIT: dialogul a ramas deschis ($motiv) - fara input real, per regula masinii partajate"
|
||||
}
|
||||
|
||||
# omoara doar vfp9 lansate pe ACEST script (linia de comanda contine calea lui), nu instante straine
|
||||
function Stop-VfpForScript([string]$ScriptPath) {
|
||||
Get-CimInstance Win32_Process -Filter "Name='vfp9.exe'" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
if ($_.CommandLine -and $_.CommandLine.ToLower().Contains($ScriptPath.ToLower())) {
|
||||
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- pregatire ---
|
||||
$Fxp = [System.IO.Path]::ChangeExtension($Script, 'fxp')
|
||||
if (Test-Path $Fxp) { Remove-Item $Fxp -Force }
|
||||
Stop-VfpForScript $Script
|
||||
Start-Sleep -Milliseconds 300
|
||||
|
||||
$log = New-Object System.Collections.Generic.List[string]
|
||||
function Log([string]$s) { Write-Host $s; $log.Add($s) }
|
||||
|
||||
Log "watchdog_vfp: lansez $Vfp -A -T `"$Script`""
|
||||
$proc = Start-Process -FilePath $Vfp -ArgumentList @('-A', '-T', "`"$Script`"") -PassThru
|
||||
|
||||
$dialogs = New-Object System.Collections.Generic.List[object]
|
||||
$exitCode = $null
|
||||
|
||||
try {
|
||||
# Fereastra principala = Process.MainWindowHandle (.NET), latch-uita o singura data. NU se
|
||||
# poate distinge dupa numele clasei: VFP inregistreaza clase diferite prefixate "vfp9..." atat
|
||||
# pentru shell-ul principal ("vfp99400000") CAT SI pentru dialoguri native proprii precum
|
||||
# "View Parameter" ("vfp994000002") - verificat empiric, clasificarea pe clasa a lasat
|
||||
# "View Parameter" nedetectat. MainWindowHandle e acelasi mecanism folosit deja cu succes in
|
||||
# vfp_ui_harness.ps1 (Wait-MainWindowHandle) pentru shell-ul VFP.
|
||||
$mainHwnd = [IntPtr]::Zero
|
||||
$mwDeadline = (Get-Date).AddSeconds(20)
|
||||
while ($mainHwnd -eq [IntPtr]::Zero -and (Get-Date) -lt $mwDeadline) {
|
||||
$proc.Refresh()
|
||||
if ($proc.HasExited) { break }
|
||||
if ($proc.MainWindowHandle -ne [IntPtr]::Zero) { $mainHwnd = $proc.MainWindowHandle }
|
||||
else { Start-Sleep -Milliseconds 200 }
|
||||
}
|
||||
if ($mainHwnd -ne [IntPtr]::Zero) {
|
||||
Log ("fereastra principala VFP: hwnd={0} class='{1}' title='{2}'" -f $mainHwnd, (Get-WinClassName $mainHwnd), (Get-WmText $mainHwnd))
|
||||
} else {
|
||||
Log "ATENTIE: MainWindowHandle nu a aparut in 20s - orice fereastra gasita va fi tratata ca dialog."
|
||||
}
|
||||
|
||||
$knownWindows = New-Object System.Collections.Generic.HashSet[IntPtr]
|
||||
if ($mainHwnd -ne [IntPtr]::Zero) { [void]$knownWindows.Add($mainHwnd) }
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
$stop = $false
|
||||
|
||||
while (-not $stop -and (Get-Date) -lt $deadline) {
|
||||
$proc.Refresh()
|
||||
if ($proc.HasExited) { Log "proces terminat singur (exit code $($proc.ExitCode))"; break }
|
||||
|
||||
# daca MainWindowHandle inca nu era prins, incearca din nou (fereastra principala poate
|
||||
# aparea mai tarziu decat asteptarea initiala de 20s in cazuri lente)
|
||||
if ($mainHwnd -eq [IntPtr]::Zero -and $proc.MainWindowHandle -ne [IntPtr]::Zero) {
|
||||
$mainHwnd = $proc.MainWindowHandle
|
||||
[void]$knownWindows.Add($mainHwnd)
|
||||
Log ("fereastra principala VFP (intarziata): hwnd={0} class='{1}' title='{2}'" -f $mainHwnd, (Get-WinClassName $mainHwnd), (Get-WmText $mainHwnd))
|
||||
}
|
||||
|
||||
$windows = Get-TopWindowsForPid $proc.Id
|
||||
|
||||
foreach ($w in $windows) {
|
||||
if ($knownWindows.Contains($w)) { continue }
|
||||
[void]$knownWindows.Add($w)
|
||||
|
||||
if ($w -eq $mainHwnd) { continue }
|
||||
|
||||
$children = Get-ChildWindowsOf $w
|
||||
$dumpLines = Get-DialogDump $w $children
|
||||
$idx = $dialogs.Count
|
||||
$png = Join-Path $OutDir ("{0}_dialog{1}.png" -f $ScriptBase, $idx)
|
||||
Save-DialogScreenshot $w $png | Out-Null
|
||||
|
||||
Log "=== DIALOG $idx detectat ==="
|
||||
foreach ($l in $dumpLines) { Log $l }
|
||||
Log " screenshot: $png"
|
||||
|
||||
$dismissMethod = $null
|
||||
if ($AutoDismiss) {
|
||||
$dismissMethod = Dismiss-Dialog $w $children
|
||||
Log " dismiss: $dismissMethod"
|
||||
}
|
||||
|
||||
$dialogs.Add([pscustomobject]@{
|
||||
Index = $idx
|
||||
Title = ($dumpLines[0])
|
||||
Png = $png
|
||||
Dismiss = $dismissMethod
|
||||
DumpText = ($dumpLines -join "`r`n")
|
||||
})
|
||||
|
||||
if ($dialogs.Count -ge $MaxDialogs) { Log "MaxDialogs ($MaxDialogs) atins."; $stop = $true; break }
|
||||
if (-not $AutoDismiss) { Log "AutoDismiss oprit - opresc polling-ul dupa primul dialog."; $stop = $true; break }
|
||||
}
|
||||
|
||||
if (-not $stop) { Start-Sleep -Milliseconds 700 }
|
||||
}
|
||||
|
||||
if (-not $proc.HasExited -and (Get-Date) -ge $deadline) {
|
||||
Log "TIMEOUT (${TimeoutSec}s) - procesul e inca viu, il opresc."
|
||||
}
|
||||
|
||||
$proc.Refresh()
|
||||
if ($proc.HasExited) { $exitCode = $proc.ExitCode }
|
||||
}
|
||||
finally {
|
||||
if ($proc -and -not $proc.HasExited) {
|
||||
try { $proc.Kill() } catch {}
|
||||
}
|
||||
Stop-VfpForScript $Script
|
||||
}
|
||||
|
||||
# --- rezumat ---
|
||||
Log ""
|
||||
Log "=== REZUMAT ==="
|
||||
Log ("dialoguri detectate: {0}" -f $dialogs.Count)
|
||||
foreach ($d in $dialogs) {
|
||||
Log (" [{0}] {1}" -f $d.Index, $d.Title)
|
||||
Log (" png: {0}" -f $d.Png)
|
||||
if ($d.Dismiss) { Log (" dismiss: {0}" -f $d.Dismiss) }
|
||||
}
|
||||
Log ("exit code proces: {0}" -f ($(if ($null -ne $exitCode) { $exitCode } else { '(omorat de watchdog, nu s-a terminat singur)' })))
|
||||
Log ("log complet: {0}" -f $LogPath)
|
||||
|
||||
[System.IO.File]::WriteAllLines($LogPath, $log)
|
||||
103
utile/citeste_email.ps1
Normal file
103
utile/citeste_email.ps1
Normal file
@@ -0,0 +1,103 @@
|
||||
# Citeste emailurile din mbox-urile Thunderbird Portable (fara conectorul Gmail).
|
||||
# citeste_email.ps1 [-Cauta <text>] [-Cont <nume>] [-Ultimele <n>] -> lista mesaje
|
||||
# citeste_email.ps1 -Nr <linie> [-Linii <n>] -> corpul unui mesaj
|
||||
param(
|
||||
[string]$Cauta = '',
|
||||
[string]$Cont = '',
|
||||
[int]$Ultimele = 20,
|
||||
[int]$Nr = 0,
|
||||
[int]$Linii = 200,
|
||||
[string]$Radacina = 'D:\UTIL\portable\PortableApps\ThunderbirdPortable\Data\profile\ImapMail'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Get-Mboxuri {
|
||||
param([string]$Cont)
|
||||
$c = if ($Cont) { $Cont } else { '*' }
|
||||
Get-ChildItem $Radacina -Directory -Filter $c |
|
||||
ForEach-Object { Join-Path $_.FullName 'INBOX' } |
|
||||
Where-Object { Test-Path $_ } |
|
||||
Where-Object { (Get-Item $_).LastWriteTime -gt (Get-Date).AddYears(-2) }
|
||||
}
|
||||
|
||||
function Deschide-Fisier {
|
||||
param([string]$Cale)
|
||||
# Thunderbird tine fisierul deschis -> FileShare ReadWrite obligatoriu
|
||||
$fs = New-Object IO.FileStream($Cale, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::ReadWrite)
|
||||
New-Object IO.StreamReader($fs, [Text.Encoding]::GetEncoding(28591))
|
||||
}
|
||||
|
||||
function Decodeaza-Subiect {
|
||||
param([string]$S)
|
||||
$rx = [regex]'=\?([^?]+)\?([BbQq])\?([^?]*)\?='
|
||||
$rx.Replace($S, {
|
||||
param($m)
|
||||
$enc = [Text.Encoding]::GetEncoding($m.Groups[1].Value)
|
||||
$txt = $m.Groups[3].Value
|
||||
if ($m.Groups[2].Value -match '[Bb]') {
|
||||
$enc.GetString([Convert]::FromBase64String($txt))
|
||||
} else {
|
||||
$b = New-Object Collections.Generic.List[byte]
|
||||
for ($i = 0; $i -lt $txt.Length; $i++) {
|
||||
if ($txt[$i] -eq '=') { $b.Add([Convert]::ToByte($txt.Substring($i + 1, 2), 16)); $i += 2 }
|
||||
elseif ($txt[$i] -eq '_') { $b.Add(32) }
|
||||
else { $b.Add([byte][char]$txt[$i]) }
|
||||
}
|
||||
$enc.GetString($b.ToArray())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
# ---- corpul unui mesaj: de la linia data pana la urmatorul separator mbox ----
|
||||
if ($Nr -gt 0) {
|
||||
foreach ($f in Get-Mboxuri -Cont $Cont) {
|
||||
$r = Deschide-Fisier $f
|
||||
try {
|
||||
$i = 0; $scris = 0; $pornit = $false
|
||||
while ($null -ne ($l = $r.ReadLine())) {
|
||||
$i++
|
||||
if ($i -lt $Nr) { continue }
|
||||
# linia ceruta trebuie sa fie inceput de mesaj, altfel e alt cont
|
||||
if ($i -eq $Nr -and $l -notmatch '^From - \w\w\w \w\w\w ') { break }
|
||||
if ($pornit -and $l -match '^From - \w\w\w \w\w\w ') { break }
|
||||
$pornit = $true
|
||||
$l
|
||||
if (++$scris -ge $Linii) { "... (taiat la $Linii linii, mareste cu -Linii)"; break }
|
||||
}
|
||||
if ($pornit) { return }
|
||||
} finally { $r.Dispose() }
|
||||
}
|
||||
Write-Warning "Linia $Nr nu exista in mbox-urile cautate."
|
||||
return
|
||||
}
|
||||
|
||||
# ---- lista de mesaje ----
|
||||
$mesaje = @()
|
||||
foreach ($f in Get-Mboxuri -Cont $Cont) {
|
||||
$cont = Split-Path (Split-Path $f -Parent) -Leaf
|
||||
$r = Deschide-Fisier $f
|
||||
try {
|
||||
$i = 0; $inAntet = $false; $m = $null
|
||||
while ($null -ne ($l = $r.ReadLine())) {
|
||||
$i++
|
||||
if ($l -match '^From - \w\w\w \w\w\w ') {
|
||||
if ($m) { $mesaje += $m }
|
||||
$m = [pscustomobject]@{ Cont = $cont; Linie = $i; Data = ''; De_la = ''; Subiect = '' }
|
||||
$inAntet = $true
|
||||
continue
|
||||
}
|
||||
if (-not $inAntet -or -not $m) { continue }
|
||||
if ($l -eq '') { $inAntet = $false; continue }
|
||||
if ($l -like 'Date: *' -and -not $m.Data) { $m.Data = $l.Substring(6).Trim() }
|
||||
elseif ($l -like 'From: *' -and -not $m.De_la) { $m.De_la = $l.Substring(6).Trim() }
|
||||
elseif ($l -like 'Subject: *' -and -not $m.Subiect) { $m.Subiect = Decodeaza-Subiect $l.Substring(9).Trim() }
|
||||
}
|
||||
if ($m) { $mesaje += $m }
|
||||
} finally { $r.Dispose() }
|
||||
}
|
||||
|
||||
if ($Cauta) {
|
||||
$mesaje = $mesaje | Where-Object { $_.Subiect -like "*$Cauta*" -or $_.De_la -like "*$Cauta*" }
|
||||
}
|
||||
$mesaje | Select-Object -Last $Ultimele | Format-Table -AutoSize -Wrap
|
||||
@@ -19,7 +19,9 @@ if (-not $TranscriptPath) {
|
||||
try { $TranscriptPath = (ConvertFrom-Json $stdin).transcript_path } catch { }
|
||||
}
|
||||
}
|
||||
if (-not $TranscriptPath -or -not (Test-Path $TranscriptPath)) {
|
||||
# la primul mesaj al unei sesiuni noi transcriptul inca nu e creat: fara fallback, ca sa nu raporteze alta sesiune
|
||||
if ($TranscriptPath -and -not (Test-Path $TranscriptPath)) { exit 0 }
|
||||
if (-not $TranscriptPath) {
|
||||
$dir = Join-Path $env:USERPROFILE ".claude\projects\$((Get-Location).Path -replace '[:\\/]','-')"
|
||||
if (Test-Path $dir) {
|
||||
$f = Get-ChildItem "$dir\*.jsonl" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
|
||||
@@ -42,8 +42,8 @@ function Adauga($cale, $tipare, $recursiv, $director) {
|
||||
$docs = Join-Path $ProjectRoot 'docs'
|
||||
$teste = @((Join-Path $comun 'utile\Teste'), (Join-Path $ProjectRoot 'utile\Teste')) | Where-Object { Test-Path $_ }
|
||||
|
||||
# patch-uri de review, handoff-uri, planuri de runda
|
||||
Adauga $docs @('diff_runda*.patch', 'handoff*.md', 'plan_runda*.md', 'runda*.md') $false $false
|
||||
# patch-uri de review, handoff-uri, planuri de runda, propuneri implementate
|
||||
Adauga $docs @('diff_runda*.patch', 'handoff*.md', 'plan_runda*.md', 'runda*.md', 'propuneri_*.md') $false $false
|
||||
# backup-uri de runda si de cache text
|
||||
Adauga $ProjectRoot @('*.pre_runda*.bak') $true $false
|
||||
Adauga $CacheRoot @('*.pre_runda*.bak', '*.vc2.bak', '*.sc2.bak') $true $false
|
||||
|
||||
529
utile/diag_actualizare.ps1
Normal file
529
utile/diag_actualizare.ps1
Normal file
@@ -0,0 +1,529 @@
|
||||
# diag_actualizare.ps1 - depanare PACK_UPDATE (actualizare ROA) pe serverul unui client.
|
||||
# Urmareste pasii din COMUN\docs\depanare-pack-update.md: test conexiune, UPD_ISTORIC, UPD_LOG,
|
||||
# script_master.log/script_master2.log (UTL_FILE pe directorul Oracle DMPDIR), versiuni aplicate
|
||||
# pe fiecare schema, spatiu tablespace (detaliu + cat mai poate creste + top segmente pe cele
|
||||
# blocate), spatiu disc pe server (optional, -Disc), jobul UPDATEROA_ZILNIC.
|
||||
# STRICT READ-ONLY: doar select si UTL_FILE in mod 'R'. Nu apeleaza IncheiereActualizare, nu
|
||||
# relanseaza actualizarea, nu face DDL/DML. Comenzile de deblocare/marire sunt doar AFISATE ca
|
||||
# sugestie. Singura exceptie e -Disc: scrie un .ps1 temporar in DMPDIR pe server (prin
|
||||
# sys.ExecuteScriptOS) ca sa citeasca spatiul liber pe discuri, si il sterge la final.
|
||||
# Parola implicita (ROMFASTSOFT) e cea de dezvoltare, aceeasi folosita si pe serverele de client.
|
||||
#
|
||||
# Utilizare:
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_ROMCONSTRUCT -Tail 120
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA -User contafin_oracle -Password ...
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA -DoarLog # doar script_master.log
|
||||
# powershell -File COMUN\utile\diag_actualizare.ps1 -Alias ROA_SIGMA -Disc # + spatiu liber pe discurile serverului
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Alias,
|
||||
[string]$User = 'contafin_oracle',
|
||||
[string]$Password = 'ROMFASTSOFT',
|
||||
[int]$Tail = 60,
|
||||
[string]$SqlPlus = 'D:\ROA\instantclient_19_18\sqlplus.exe',
|
||||
[switch]$DoarLog,
|
||||
[switch]$Disc
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path $SqlPlus)) {
|
||||
Write-Output ('EROARE: nu gasesc sqlplus la ' + $SqlPlus)
|
||||
exit 1
|
||||
}
|
||||
|
||||
$env:TNS_ADMIN = Split-Path $SqlPlus -Parent
|
||||
$ConnStr = $User + '/' + $Password + '@' + $Alias
|
||||
|
||||
$TempDir = Join-Path $env:TEMP ('diag_actualizare_' + [guid]::NewGuid().ToString('N'))
|
||||
New-Item -ItemType Directory -Force -Path $TempDir | Out-Null
|
||||
|
||||
function Remove-TempDir {
|
||||
if (Test-Path $TempDir) { Remove-Item -LiteralPath $TempDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
function Invoke-Sql {
|
||||
param([string]$Sql)
|
||||
$sqlFile = Join-Path $TempDir ('q_' + [guid]::NewGuid().ToString('N') + '.sql')
|
||||
[System.IO.File]::WriteAllText($sqlFile, $Sql, [System.Text.Encoding]::ASCII)
|
||||
try {
|
||||
$out = & $SqlPlus -L -S $ConnStr ('@' + $sqlFile) 2>&1
|
||||
$code = $LASTEXITCODE
|
||||
} catch {
|
||||
$out = 'EROARE lansare sqlplus: ' + $_.Exception.Message
|
||||
$code = -1
|
||||
}
|
||||
Remove-Item -LiteralPath $sqlFile -Force -ErrorAction SilentlyContinue
|
||||
[PSCustomObject]@{ Text = ($out -join "`n"); Code = $code }
|
||||
}
|
||||
|
||||
function Show-Section {
|
||||
param([string]$Title, [string]$Text)
|
||||
Write-Output ''
|
||||
Write-Output ('===== ' + $Title + ' =====')
|
||||
Write-Output $Text
|
||||
if ($Text -match 'ORA-00942|ORA-01031') {
|
||||
Write-Output '[AVERTISMENT] lipsesc probabil drepturi de acces (ORA-00942/ORA-01031) - pasul de mai sus poate fi incomplet cu acest utilizator.'
|
||||
}
|
||||
}
|
||||
|
||||
function Wait-RemoteFile {
|
||||
# asteapta aparitia unui fisier scris de sys.ExecuteScriptOS (asincron) - polling, nu instant
|
||||
param([string]$Directory, [string]$FileName, [int]$TimeoutSec = 60)
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
$r = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
select dbms_lob.fileexists(bfilename('$Directory','$FileName')) from dual;
|
||||
exit
|
||||
"@
|
||||
if ($r.Text -match '1') { return $true }
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
# ---------- 1. Test conexiune ----------
|
||||
Write-Output '===== 1. TEST CONEXIUNE ====='
|
||||
Write-Output ('Alias=' + $Alias + ' User=' + $User + ' TNS_ADMIN=' + $env:TNS_ADMIN)
|
||||
$r1 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'CONEXIUNE_OK' from dual;
|
||||
select 'VERSIUNE DB: ' || banner from v`$version where rownum = 1;
|
||||
select 'SCHEMA CONECTATA: ' || sys_context('userenv','session_user') || ' DB: ' || sys_context('userenv','db_name') from dual;
|
||||
exit
|
||||
"@
|
||||
Write-Output $r1.Text
|
||||
if ($r1.Code -ne 0 -or $r1.Text -notmatch 'CONEXIUNE_OK') {
|
||||
Write-Output ''
|
||||
Write-Output 'EROARE: conexiunea a esuat. Verifica:'
|
||||
Write-Output ' - tunelul SSH pe 1521 e deschis?'
|
||||
Write-Output (' - aliasul TNS ' + $Alias + ' exista in ' + $env:TNS_ADMIN + '\tnsnames.ora si tinteste 127.0.0.1?')
|
||||
Write-Output ' - user/parola corecte? (implicit contafin_oracle/ROMFASTSOFT)'
|
||||
Remove-TempDir
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ---------- 2. UPD_ISTORIC ----------
|
||||
if (-not $DoarLog) {
|
||||
$r2 = Invoke-Sql -Sql @"
|
||||
set pagesize 200 linesize 200 trimspool on feedback off
|
||||
column dataora_start format a19
|
||||
column dataora_end format a30
|
||||
column stare_text format a26
|
||||
select * from (
|
||||
select to_char(dataora_start,'yyyy-mm-dd hh24:mi:ss') dataora_start,
|
||||
nvl(to_char(dataora_end,'yyyy-mm-dd hh24:mi:ss'), '<<< NEINCHEIATA >>>') dataora_end,
|
||||
decode(stare, 0,'0-pornire', 1,'1-descarcare aplicatii', 2,'2-generare scripturi',
|
||||
3,'3-aplicare scripturi', 4,'4-incheiat', 'necunoscuta(' || stare || ')') stare_text
|
||||
from upd_istoric
|
||||
order by dataora_start desc
|
||||
) where rownum <= 10;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '2. UPD_ISTORIC (ultimele 10 rulari)' -Text $r2.Text
|
||||
|
||||
# ---------- 3. UPD_LOG (rularea curenta) ----------
|
||||
$r3 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off long 32000 longchunksize 32000
|
||||
select 'AVERTISMENT: UPD_LOG se goleste la fiecare rulare; erorile din etapa 3 (aplicare scripturi in SQL*Plus extern) NU ajung aici - vezi script_master.log mai jos.' from dual;
|
||||
select '-------------------------------------------' from dual;
|
||||
select 'SECV ' || secventa || ' SCHEMA=' || nvl(schema,'-') || ' SCRIPT=' || nvl(script,'-') ||
|
||||
' ' || to_char(dataora,'yyyy-mm-dd hh24:mi:ss') || chr(10) ||
|
||||
nvl(explicatie,'(fara explicatie)') || chr(10) || '-------------------------------------------'
|
||||
from upd_log
|
||||
where dataora_start = (select max(dataora_start) from upd_log)
|
||||
order by secventa;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3. UPD_LOG (rularea curenta)' -Text $r3.Text
|
||||
}
|
||||
|
||||
# ---------- 4. script_master.log / script_master2.log (UTL_FILE pe DMPDIR) ----------
|
||||
foreach ($logFile in @('script_master.log', 'script_master2.log')) {
|
||||
$r4 = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
ln_n pls_integer := $Tail;
|
||||
la_buf dbms_sql.varchar2a;
|
||||
ln_idx pls_integer := 0;
|
||||
ln_cnt pls_integer := 0;
|
||||
lc_line varchar2(32767);
|
||||
lf utl_file.file_type;
|
||||
lc_path all_directories.directory_path%type;
|
||||
begin
|
||||
begin
|
||||
select directory_path into lc_path from all_directories where directory_name = 'DMPDIR';
|
||||
exception when no_data_found then lc_path := '(directorul Oracle DMPDIR nu exista)';
|
||||
end;
|
||||
dbms_output.put_line('Director DMPDIR -> ' || lc_path || ' fisier: $logFile');
|
||||
lf := utl_file.fopen('DMPDIR', '$logFile', 'R', 32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
ln_idx := mod(ln_cnt, ln_n) + 1;
|
||||
la_buf(ln_idx) := lc_line;
|
||||
ln_cnt := ln_cnt + 1;
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
dbms_output.put_line('total linii citite: ' || ln_cnt || ' (ultimele ' || ln_n || ' afisate mai jos)');
|
||||
dbms_output.put_line('-------------------------------------------');
|
||||
if ln_cnt <= ln_n then
|
||||
for i in 1 .. ln_cnt loop dbms_output.put_line(la_buf(i)); end loop;
|
||||
else
|
||||
for i in 0 .. ln_n - 1 loop dbms_output.put_line(la_buf(mod(ln_cnt + i, ln_n) + 1)); end loop;
|
||||
end if;
|
||||
exception
|
||||
when others then
|
||||
if utl_file.is_open(lf) then utl_file.fclose(lf); end if;
|
||||
if sqlcode = -29280 then
|
||||
dbms_output.put_line('EROARE: directorul Oracle DMPDIR nu exista sau alias gresit (ORA-29280).');
|
||||
elsif sqlcode = -29283 then
|
||||
dbms_output.put_line('EROARE: fisierul $logFile nu exista in DMPDIR sau nu poate fi citit (ORA-29283). Normal daca actualizarea nu a ajuns inca la etapa 3, sau pentru script_master2.log daca rularea a picat inainte de pasii finali.');
|
||||
else
|
||||
dbms_output.put_line('EROARE: ' || sqlerrm);
|
||||
end if;
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title ('4. ' + $logFile) -Text $r4.Text
|
||||
}
|
||||
|
||||
if ($DoarLog) { Remove-TempDir; exit 0 }
|
||||
|
||||
# ---------- 5. Versiuni per schema ----------
|
||||
$rSchemas = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 200 trimspool on feedback off heading off
|
||||
select owner from all_tables where table_name = 'VERSIUNE' order by owner;
|
||||
exit
|
||||
"@
|
||||
$schemas = @($rSchemas.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ -match '^[A-Z_][A-Z0-9_]*$' })
|
||||
|
||||
if ($schemas.Count -eq 0) {
|
||||
Show-Section -Title '5. VERSIUNI PE SCHEMA' -Text ('Nu am gasit nicio schema cu tabela VERSIUNE (all_tables).' + "`n" + $rSchemas.Text)
|
||||
} else {
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
[void]$sb.AppendLine('set pagesize 0 linesize 250 trimspool on feedback off heading off')
|
||||
foreach ($sch in $schemas) {
|
||||
$prefix = if ($sch -eq 'CONTAFIN_ORACLE') { 'CO' } else { 'FF' }
|
||||
[void]$sb.AppendLine(@"
|
||||
select 'ULTIMA [$sch] ' || tip_script || ' data=' || to_char(data_script,'yyyy-mm-dd') || ' seq=' || seq_script
|
||||
from (select tip_script, data_script, seq_script from $sch.VERSIUNE order by data_script desc, seq_script desc)
|
||||
where rownum = 1;
|
||||
"@)
|
||||
[void]$sb.AppendLine(@"
|
||||
select 'CANDIDAT [$sch] ' || msg from (
|
||||
select msg, ord from (
|
||||
select script_name || ' (data=' || to_char(script_date,'yyyy-mm-dd') || ' seq=' || script_seq || ')' msg, 1 ord
|
||||
from (
|
||||
select d.script_name, d.script_date, d.script_seq
|
||||
from upd_database d,
|
||||
(select data_script mx_date, seq_script mx_seq from (
|
||||
select data_script, seq_script from $sch.VERSIUNE order by data_script desc, seq_script desc
|
||||
) where rownum = 1) w
|
||||
where d.script_name like '$prefix\_%' escape '\'
|
||||
and (d.script_date > w.mx_date or (d.script_date = w.mx_date and d.script_seq > w.mx_seq))
|
||||
order by d.script_date, d.script_seq
|
||||
) where rownum = 1
|
||||
union all
|
||||
select '(la zi - niciun script $prefix neaplicat gasit dupa ultima versiune)' msg, 2 ord from dual
|
||||
) order by ord
|
||||
) where rownum = 1;
|
||||
"@)
|
||||
}
|
||||
[void]$sb.AppendLine('exit')
|
||||
$r5 = Invoke-Sql -Sql $sb.ToString()
|
||||
Show-Section -Title '5. VERSIUNI PE SCHEMA (ultima aplicata / prima neaplicata - candidat)' -Text $r5.Text
|
||||
}
|
||||
|
||||
# ---------- 6. Spatiu tablespace: detaliu pe datafile + cat mai poate creste ----------
|
||||
$r6 = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column tablespace_name format a15
|
||||
column file_name format a55
|
||||
column autoext format a4
|
||||
select f.tablespace_name, f.file_name,
|
||||
round(f.bytes/1048576) mb_curent,
|
||||
round(f.maxbytes/1048576) mb_max,
|
||||
f.autoextensible autoext,
|
||||
round(f.increment_by * t.block_size / 1048576) mb_increment
|
||||
from dba_data_files f, dba_tablespaces t
|
||||
where f.tablespace_name = t.tablespace_name
|
||||
order by f.tablespace_name, f.file_name;
|
||||
column tablespace_name format a15
|
||||
column stare format a26
|
||||
with ts_free as (
|
||||
select tablespace_name, sum(bytes) free_bytes from dba_free_space group by tablespace_name
|
||||
), agg as (
|
||||
select f.tablespace_name, sum(f.bytes) alocat_bytes, sum(f.maxbytes) max_bytes,
|
||||
sum(greatest(f.maxbytes - f.bytes, 0)) creste_bytes
|
||||
from dba_data_files f
|
||||
group by f.tablespace_name
|
||||
)
|
||||
select a.tablespace_name,
|
||||
round(a.alocat_bytes/1048576) mb_alocat,
|
||||
round(a.max_bytes/1048576) mb_max,
|
||||
round(nvl(tf.free_bytes,0)/1048576) mb_liber,
|
||||
round((nvl(tf.free_bytes,0) + a.creste_bytes)/1048576) mb_poate_creste,
|
||||
case when a.max_bytes > 0 and (nvl(tf.free_bytes,0) + a.creste_bytes) < 1048576
|
||||
then 'ATENTIE: MAXBYTES ATINS' end stare
|
||||
from agg a, ts_free tf
|
||||
where a.tablespace_name = tf.tablespace_name(+)
|
||||
order by a.tablespace_name;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '6. SPATIU TABLESPACE (detaliu pe datafile + cat mai poate creste)' -Text ('mb_poate_creste = liber curent + (maxbytes - alocat) - spatiul real disponibil inainte de ORA-01653, nu doar liberul de acum.' + "`n`n" + $r6.Text)
|
||||
|
||||
# tablespace-urile cu maxbytes efectiv atins - identificate separat, pentru top segmente mai jos
|
||||
$r6m = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
with ts_free as (
|
||||
select tablespace_name, sum(bytes) free_bytes from dba_free_space group by tablespace_name
|
||||
), agg as (
|
||||
select f.tablespace_name, sum(f.maxbytes) max_bytes, sum(greatest(f.maxbytes - f.bytes, 0)) creste_bytes
|
||||
from dba_data_files f
|
||||
group by f.tablespace_name
|
||||
)
|
||||
select 'TS_ATENTIE|' || a.tablespace_name
|
||||
from agg a, ts_free tf
|
||||
where a.tablespace_name = tf.tablespace_name(+)
|
||||
and a.max_bytes > 0
|
||||
and (nvl(tf.free_bytes,0) + a.creste_bytes) < 1048576;
|
||||
exit
|
||||
"@
|
||||
$tsProblema = @($r6m.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('TS_ATENTIE|') } | ForEach-Object { $_.Substring(11) } | Where-Object { $_ -match '^[A-Z0-9_]+$' })
|
||||
|
||||
if ($tsProblema.Count -gt 0) {
|
||||
$sbSeg = New-Object System.Text.StringBuilder
|
||||
[void]$sbSeg.AppendLine('set pagesize 0 linesize 250 trimspool on feedback off heading off')
|
||||
foreach ($ts in $tsProblema) {
|
||||
[void]$sbSeg.AppendLine("select 'Tablespace $ts - top 15 segmente:' from dual;")
|
||||
[void]$sbSeg.AppendLine(@"
|
||||
select rpad(owner,20) || rpad(segment_name,35) || rpad(segment_type,18) || round(bytes/1048576) || ' MB'
|
||||
from (select owner, segment_name, segment_type, bytes from dba_segments where tablespace_name = '$ts' order by bytes desc)
|
||||
where rownum <= 15;
|
||||
"@)
|
||||
if ($ts -eq 'SYSTEM') {
|
||||
[void]$sbSeg.AppendLine("select 'NOTA: privilegiile ANY (ex. DROP ANY TABLE/TRUNCATE ANY TABLE) nu se aplica pe obiecte din schema SYS cand O7_DICTIONARY_ACCESSIBILITY=FALSE - curatarea unui tabel din SYS cere conectare SYSDBA, nu contafin_oracle.' from dual;")
|
||||
}
|
||||
}
|
||||
[void]$sbSeg.AppendLine('exit')
|
||||
$r6s = Invoke-Sql -Sql $sbSeg.ToString()
|
||||
Write-Output ''
|
||||
Write-Output ('--- Top segmente pe tablespace-urile marcate ATENTIE (' + ($tsProblema -join ', ') + ') ---')
|
||||
Write-Output $r6s.Text
|
||||
}
|
||||
|
||||
# ---------- 7. Spatiu disc pe server (optional, scrie un .ps1 temporar in DMPDIR) ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 7. SPATIU DISC (server) ====='
|
||||
if (-not $Disc) {
|
||||
Write-Output 'Sarit implicit - ruleaza cu -Disc pentru spatiul liber pe discurile fizice ale serverului.'
|
||||
Write-Output 'Este singura parte a scriptului care NU e strict read-only: scrie un .ps1 temporar in DMPDIR (prin sys.ExecuteScriptOS) si il sterge la final.'
|
||||
} else {
|
||||
$rPaths = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'DATAFILE_PATH|' || file_name from dba_data_files order by file_name;
|
||||
exit
|
||||
"@
|
||||
$datafilePaths = @($rPaths.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('DATAFILE_PATH|') } | ForEach-Object { $_.Substring(14) })
|
||||
|
||||
$psTemplate = @'
|
||||
$dOut = 'C:\DMPDIR\diag_disc_out.txt'
|
||||
Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {
|
||||
$pct = 0
|
||||
if ($_.Size -gt 0) { $pct = [math]::Round($_.FreeSpace/$_.Size*100,1) }
|
||||
"DISC {0} {1} {2} {3}" -f $_.DeviceID, [math]::Round($_.Size/1GB,2), [math]::Round($_.FreeSpace/1GB,2), $pct
|
||||
} | Out-File -Encoding ascii $dOut
|
||||
__DATAFILES__
|
||||
'@
|
||||
$fileLines = foreach ($p in $datafilePaths) {
|
||||
$escaped = $p.Replace("'", "''")
|
||||
'Get-Item ''' + $escaped + ''' -ErrorAction SilentlyContinue | ForEach-Object { "FISIER {0} {1}" -f $_.FullName, $_.Length } | Out-File -Encoding ascii -Append $dOut'
|
||||
}
|
||||
$psScript = $psTemplate.Replace('__DATAFILES__', ([string]::Join("`n", $fileLines)))
|
||||
$psScriptSql = $psScript.Replace("'", "''")
|
||||
|
||||
$rLaunch = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lcPS server_info.value%type;
|
||||
begin
|
||||
select value into lcPS from server_info where upper(name) = 'POWERSHELLPATH';
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc.ps1'); exception when others then null; end;
|
||||
pack_utils_file.clob2fileX('$psScriptSql', 'DMPDIR', 'diag_disc.ps1');
|
||||
sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\diag_disc.ps1');
|
||||
dbms_output.put_line('Lansat pe server (' || lcPS || '), astept rezultatul...');
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE la lansare: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Write-Output $rLaunch.Text
|
||||
|
||||
if ($rLaunch.Text -notmatch 'EROARE la lansare') {
|
||||
$gata = Wait-RemoteFile -Directory 'DMPDIR' -FileName 'diag_disc_out.txt' -TimeoutSec 60
|
||||
if (-not $gata) {
|
||||
Write-Output 'EROARE: rezultatul nu a aparut in 60s. Posibile cauze: server_info.POWERSHELLPATH gresit, politica de executie PowerShell blocheaza scriptul, sau sys.ExecuteScriptOS nu are drept de executie. Verifica manual C:\DMPDIR\diag_disc.ps1 pe server.'
|
||||
} else {
|
||||
$rRead = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lf utl_file.file_type;
|
||||
lc_line varchar2(32767);
|
||||
begin
|
||||
lf := utl_file.fopen('DMPDIR','diag_disc_out.txt','R',32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
dbms_output.put_line(lc_line);
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_disc.ps1'); exception when others then null; end;
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE citire: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
$discLines = @()
|
||||
$fileLinesOut = @()
|
||||
foreach ($line in ($rRead.Text -split "`r?`n")) {
|
||||
if ($line -match '^DISC\s+(\S+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)') {
|
||||
$discLines += (' disc {0}: total {1} GB, liber {2} GB ({3}%)' -f $Matches[1], $Matches[2], $Matches[3], $Matches[4])
|
||||
} elseif ($line -match '^FISIER\s+(\S+)\s+(\d+)') {
|
||||
$mb = [math]::Round(([double]$Matches[2]) / 1048576, 1)
|
||||
$fileLinesOut += (' {0}: {1} MB pe disc' -f $Matches[1], $mb)
|
||||
} elseif ($line -match '\S') {
|
||||
$discLines += (' ' + $line)
|
||||
}
|
||||
}
|
||||
Write-Output 'Discuri fixe:'
|
||||
Write-Output ($discLines -join "`n")
|
||||
Write-Output 'Dimensiune reala pe disc a datafile-urilor:'
|
||||
Write-Output ($fileLinesOut -join "`n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- 8. Job UPDATEROA_ZILNIC ----------
|
||||
$r8 = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column log_date format a20
|
||||
column additional_info format a90 word_wrapped
|
||||
select * from (
|
||||
select to_char(log_date,'yyyy-mm-dd hh24:mi:ss') log_date, status, additional_info
|
||||
from dba_scheduler_job_run_details
|
||||
where job_name = 'UPDATEROA_ZILNIC'
|
||||
order by log_date desc
|
||||
) where rownum <= 10;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '8. JOB UPDATEROA_ZILNIC (ultimele 10 rulari)' -Text ('AVERTISMENT: additional_info e frecvent falsa - la orice esec se apeleaza EmailLog, iar daca SMTP-ul e picat ridica ORA-20000 care masca eroarea reala. Cauza adevarata e in UPD_LOG / script_master.log de mai sus.' + "`n`n" + $r8.Text)
|
||||
|
||||
# ---------- 9. Verdict ----------
|
||||
$r9 = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
ln_stare upd_istoric.stare%type;
|
||||
ld_end upd_istoric.dataora_end%type;
|
||||
ld_start upd_istoric.dataora_start%type;
|
||||
lc_stare_text varchar2(50);
|
||||
lc_line varchar2(32767);
|
||||
lf utl_file.file_type;
|
||||
lc_errs varchar2(4000);
|
||||
ln_errcnt pls_integer := 0;
|
||||
lb_spatiu boolean := false;
|
||||
lc_tspatiu varchar2(100);
|
||||
lc_match varchar2(200);
|
||||
lc_datafile varchar2(400);
|
||||
begin
|
||||
select stare, dataora_end, dataora_start into ln_stare, ld_end, ld_start
|
||||
from (select stare, dataora_end, dataora_start from upd_istoric order by dataora_start desc)
|
||||
where rownum = 1;
|
||||
|
||||
lc_stare_text := case ln_stare
|
||||
when 0 then '0-pornire' when 1 then '1-descarcare aplicatii' when 2 then '2-generare scripturi'
|
||||
when 3 then '3-aplicare scripturi' when 4 then '4-incheiat cu succes'
|
||||
else 'necunoscuta(' || ln_stare || ')' end;
|
||||
|
||||
dbms_output.put_line('Ultima rulare: ' || to_char(ld_start,'yyyy-mm-dd hh24:mi:ss') || ' stare=' || lc_stare_text ||
|
||||
case when ld_end is null then ' <<< NEINCHEIATA >>>' else ' incheiata ' || to_char(ld_end,'yyyy-mm-dd hh24:mi:ss') end);
|
||||
|
||||
if ld_end is null and ln_stare = 3 then
|
||||
dbms_output.put_line('Rularea a ramas la aplicarea scripturilor (etapa 3, SQL*Plus extern). Cauza reala e in script_master.log, NU in UPD_LOG.');
|
||||
elsif ld_end is null then
|
||||
dbms_output.put_line('Rularea nu s-a incheiat (stare ' || lc_stare_text || ').');
|
||||
else
|
||||
dbms_output.put_line('Ultima rulare s-a incheiat normal.');
|
||||
end if;
|
||||
|
||||
begin
|
||||
lf := utl_file.fopen('DMPDIR', 'script_master.log', 'R', 32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
if instr(lc_line,'ORA-06512') = 0 and (instr(upper(lc_line), 'ORA-') > 0 or instr(lc_line, 'ERROR') > 0) then
|
||||
ln_errcnt := ln_errcnt + 1;
|
||||
lc_errs := lc_errs || chr(10) || lc_line;
|
||||
if regexp_like(lc_line, 'ORA-016[0-9][0-9]|ORA-30036') then
|
||||
lb_spatiu := true;
|
||||
lc_match := regexp_substr(upper(lc_line), 'TABLESPACE [A-Z0-9_]+', 1, 1);
|
||||
if lc_match is not null then lc_tspatiu := ltrim(substr(lc_match, 11)); end if;
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
exception when others then
|
||||
if utl_file.is_open(lf) then utl_file.fclose(lf); end if;
|
||||
end;
|
||||
|
||||
if ln_errcnt > 0 then
|
||||
dbms_output.put_line('script_master.log contine erori (' || ln_errcnt || '):' || lc_errs);
|
||||
else
|
||||
dbms_output.put_line('Nu s-a gasit "ORA-"/"ERROR" in script_master.log.');
|
||||
end if;
|
||||
|
||||
if lb_spatiu then
|
||||
dbms_output.put_line('=== PROBLEMA DE SPATIU, NU DE SQL === tablespace implicat: ' || nvl(lc_tspatiu,'necunoscut'));
|
||||
if lc_tspatiu is not null then
|
||||
begin
|
||||
select file_name into lc_datafile
|
||||
from (select file_name from dba_data_files where tablespace_name = lc_tspatiu order by file_name)
|
||||
where rownum = 1;
|
||||
dbms_output.put_line('Sugestie (NU se executa automat): ALTER DATABASE DATAFILE ''' || lc_datafile ||
|
||||
''' AUTOEXTEND ON NEXT 50M MAXSIZE <valoare mai mare>;');
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
end if;
|
||||
dbms_output.put_line('Pe XE limita de 11GB e pe datele utilizator, nu pe SYSTEM - un maxbytes mic pe SYSTEM (sau alt tablespace de sistem) e o setare de instalare, se poate mari.');
|
||||
end if;
|
||||
|
||||
dbms_output.put_line('Vezi sectiunea 4 pentru context complet in log, sectiunea 5 pentru scriptul candidat per schema, sectiunea 6 pentru spatiul pe tablespace/segmente.');
|
||||
dbms_output.put_line('Daca rularea a ramas blocata (stare < 4 de peste o ora) si problema de mai sus e reparata, deblocarea (NU se executa automat de acest script):');
|
||||
dbms_output.put_line(' exec contafin_oracle.pack_update.IncheiereActualizare;');
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '9. VERDICT' -Text $r9.Text
|
||||
if ($r9.Text -match 'PROBLEMA DE SPATIU' -and -not $Disc) {
|
||||
Write-Output 'Sugestie: reruleaza cu -Disc pentru spatiul liber pe discurile fizice ale serverului (poate lipsi spatiu pe disc pentru crestere, nu doar maxbytes).'
|
||||
}
|
||||
|
||||
Remove-TempDir
|
||||
exit 0
|
||||
672
utile/diag_spatiu.ps1
Normal file
672
utile/diag_spatiu.ps1
Normal file
@@ -0,0 +1,672 @@
|
||||
# diag_spatiu.ps1 - diagnostic de spatiu pe serverul Oracle al unui client ROA.
|
||||
# Raspunde "cat spatiu mai am si ce ocupa unde": tablespace/datafile (cat mai poate creste),
|
||||
# plafonul de date al editiei XE, audit Oracle (tabele + fisiere .aud), alert log/trace/ADR,
|
||||
# archivelog/FRA, spatiu pe discurile
|
||||
# fizice ale serverului, si alti mancatori de spatiu (recyclebin, UNDO, istoric statistici/
|
||||
# scheduler, TEMP, top segmente generic - fara nume de tabele ROA hardcodate).
|
||||
# STRICT READ-ONLY pe baza: doar select/agregate si UTL_FILE in mod 'R'. Actiunile de curatare
|
||||
# din verdict sunt doar AFISATE ca sugestie, niciodata executate (niciun purge/truncate/alter).
|
||||
# Singura scriere e sub -Disc: un .ps1 temporar in DMPDIR pe server (prin sys.ExecuteScriptOS),
|
||||
# sters la final cu verificare.
|
||||
# -SysPassword e optional, fara valoare implicita, nesalvat nicaieri (parola SYS difera per
|
||||
# server). Sectiunile care o cer (MAX_PDB_STORAGE din CDB$ROOT, audit intern sys.aud$/fga_log$,
|
||||
# recyclebin la nivel de baza) se sar curat, cu mesaj, daca nu e data - diagnosticul de baza
|
||||
# merge complet fara ea.
|
||||
#
|
||||
# Utilizare:
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA -Disc
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA -SysPassword ...
|
||||
# powershell -File COMUN\utile\diag_spatiu.ps1 -Alias ROA_SIGMA -Top 30 -Disc
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Alias,
|
||||
[string]$User = 'contafin_oracle',
|
||||
[string]$Password = 'ROMFASTSOFT',
|
||||
[string]$SysPassword,
|
||||
[string]$SqlPlus = 'D:\ROA\instantclient_19_18\sqlplus.exe',
|
||||
[switch]$Disc,
|
||||
[int]$Top = 20
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# praguri de alerta, aceleasi ca in PACK_DIAG_SPATIU (jobul zilnic de la clienti): tablespace-ul
|
||||
# intra in atentie sub pragul absolut SAU sub procentul din maximul lui, ca sa existe timp de reactie
|
||||
$PragTsMb = 2048
|
||||
$PragTsPct = 15
|
||||
$PragFraPct = 75
|
||||
|
||||
if (-not (Test-Path $SqlPlus)) {
|
||||
Write-Output ('EROARE: nu gasesc sqlplus la ' + $SqlPlus)
|
||||
exit 1
|
||||
}
|
||||
|
||||
$env:TNS_ADMIN = Split-Path $SqlPlus -Parent
|
||||
$ConnStr = $User + '/' + $Password + '@' + $Alias
|
||||
$ConnStrSys = if ($SysPassword) { 'sys/' + $SysPassword + '@' + $Alias + ' as sysdba' } else { $null }
|
||||
|
||||
$TempDir = Join-Path $env:TEMP ('diag_spatiu_' + [guid]::NewGuid().ToString('N'))
|
||||
New-Item -ItemType Directory -Force -Path $TempDir | Out-Null
|
||||
|
||||
function Remove-TempDir {
|
||||
if (Test-Path $TempDir) { Remove-Item -LiteralPath $TempDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
function Invoke-SqlAs {
|
||||
param([string]$Sql, [string]$Connect)
|
||||
$sqlFile = Join-Path $TempDir ('q_' + [guid]::NewGuid().ToString('N') + '.sql')
|
||||
[System.IO.File]::WriteAllText($sqlFile, $Sql, [System.Text.Encoding]::ASCII)
|
||||
try {
|
||||
$out = & $SqlPlus -L -S $Connect ('@' + $sqlFile) 2>&1
|
||||
$code = $LASTEXITCODE
|
||||
} catch {
|
||||
$out = 'EROARE lansare sqlplus: ' + $_.Exception.Message
|
||||
$code = -1
|
||||
}
|
||||
Remove-Item -LiteralPath $sqlFile -Force -ErrorAction SilentlyContinue
|
||||
[PSCustomObject]@{ Text = ($out -join "`n"); Code = $code }
|
||||
}
|
||||
|
||||
function Invoke-Sql {
|
||||
param([string]$Sql)
|
||||
Invoke-SqlAs -Sql $Sql -Connect $ConnStr
|
||||
}
|
||||
|
||||
function Invoke-SqlSys {
|
||||
# ruleaza doar daca -SysPassword a fost dat; altfel intoarce $null (apelantul trebuie sa verifice)
|
||||
param([string]$Sql)
|
||||
if (-not $ConnStrSys) { return $null }
|
||||
Invoke-SqlAs -Sql $Sql -Connect $ConnStrSys
|
||||
}
|
||||
|
||||
function Show-Section {
|
||||
param([string]$Title, [string]$Text)
|
||||
Write-Output ''
|
||||
Write-Output ('===== ' + $Title + ' =====')
|
||||
Write-Output $Text
|
||||
if ($Text -match 'ORA-00942|ORA-01031') {
|
||||
Write-Output '[AVERTISMENT] lipsesc probabil drepturi de acces (ORA-00942/ORA-01031) - pasul de mai sus poate fi incomplet cu acest utilizator.'
|
||||
}
|
||||
}
|
||||
|
||||
function Wait-RemoteFile {
|
||||
# asteapta aparitia unui fisier scris de sys.ExecuteScriptOS (asincron) - polling, nu instant
|
||||
param([string]$Directory, [string]$FileName, [int]$TimeoutSec = 60)
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
$r = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
select dbms_lob.fileexists(bfilename('$Directory','$FileName')) from dual;
|
||||
exit
|
||||
"@
|
||||
if ($r.Text -match '1') { return $true }
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
# ---------- 1. Test conexiune + versiune + CDB/PDB ----------
|
||||
Write-Output '===== 1. TEST CONEXIUNE ====='
|
||||
Write-Output ('Alias=' + $Alias + ' User=' + $User + ' TNS_ADMIN=' + $env:TNS_ADMIN)
|
||||
$r1 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'CONEXIUNE_OK' from dual;
|
||||
select 'VERSIUNE DB: ' || banner from v`$version where rownum = 1;
|
||||
select 'SCHEMA CONECTATA: ' || sys_context('userenv','session_user') || ' DB: ' || sys_context('userenv','db_name') from dual;
|
||||
exit
|
||||
"@
|
||||
Write-Output $r1.Text
|
||||
if ($r1.Code -ne 0 -or $r1.Text -notmatch 'CONEXIUNE_OK') {
|
||||
Write-Output ''
|
||||
Write-Output 'EROARE: conexiunea a esuat. Verifica:'
|
||||
Write-Output ' - tunelul SSH pe 1521 e deschis?'
|
||||
Write-Output (' - aliasul TNS ' + $Alias + ' exista in ' + $env:TNS_ADMIN + '\tnsnames.ora si tinteste 127.0.0.1?')
|
||||
Write-Output ' - user/parola corecte? (implicit contafin_oracle/ROMFASTSOFT)'
|
||||
Remove-TempDir
|
||||
exit 1
|
||||
}
|
||||
|
||||
$verMajor = 0
|
||||
if ($r1.Text -match 'Release\s+(\d+)\.') { $verMajor = [int]$Matches[1] }
|
||||
elseif ($r1.Text -match 'Database\s+(\d+)[gc]\b') { $verMajor = [int]$Matches[1] }
|
||||
if ($verMajor -eq 0) {
|
||||
Write-Output '[AVERTISMENT] nu am putut determina versiunea majora din banner - presupun 11 (fara facilitati 12c+).'
|
||||
$verMajor = 11
|
||||
}
|
||||
$ver12plus = ($verMajor -ge 12)
|
||||
$ver11plus = ($verMajor -ge 11)
|
||||
Write-Output ('Versiune majora detectata: ' + $verMajor + ' (CDB/PDB si unified_audit_trail: ' + $(if ($ver12plus) {'da'} else {'nu, sarite mai jos'}) + ')')
|
||||
|
||||
if ($ver12plus) {
|
||||
$rCdb = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 200 trimspool on feedback off heading off
|
||||
select 'CDB=' || cdb from v`$database;
|
||||
select 'CONTAINER ' || con_id || ' ' || name || ' ' || open_mode from v`$containers order by con_id;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '1b. CDB/PDB' -Text $rCdb.Text
|
||||
} else {
|
||||
Write-Output ''
|
||||
Write-Output '===== 1b. CDB/PDB ====='
|
||||
Write-Output 'Sarit - baza sub versiunea 12c (CDB/PDB nu se aplica pe 10.2/11g).'
|
||||
}
|
||||
|
||||
# ---------- 2. Tablespace / datafile ----------
|
||||
$r2 = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column tablespace_name format a15
|
||||
column file_name format a55
|
||||
column autoext format a4
|
||||
select f.tablespace_name, f.file_name,
|
||||
round(f.bytes/1048576) mb_curent,
|
||||
round(f.maxbytes/1048576) mb_max,
|
||||
f.autoextensible autoext,
|
||||
round(f.increment_by * t.block_size / 1048576) mb_increment
|
||||
from dba_data_files f, dba_tablespaces t
|
||||
where f.tablespace_name = t.tablespace_name
|
||||
order by f.tablespace_name, f.file_name;
|
||||
column tablespace_name format a15
|
||||
column stare format a26
|
||||
with ts_free as (
|
||||
select tablespace_name, sum(bytes) free_bytes from dba_free_space group by tablespace_name
|
||||
), agg as (
|
||||
select f.tablespace_name, sum(f.bytes) alocat_bytes, sum(f.maxbytes) max_bytes,
|
||||
sum(greatest(f.maxbytes - f.bytes, 0)) creste_bytes
|
||||
from dba_data_files f
|
||||
group by f.tablespace_name
|
||||
)
|
||||
select a.tablespace_name,
|
||||
round(a.alocat_bytes/1048576) mb_alocat,
|
||||
round(a.max_bytes/1048576) mb_max,
|
||||
round(nvl(tf.free_bytes,0)/1048576) mb_liber,
|
||||
round((nvl(tf.free_bytes,0) + a.creste_bytes)/1048576) mb_poate_creste,
|
||||
case when a.max_bytes > 0 and (nvl(tf.free_bytes,0) + a.creste_bytes) <
|
||||
greatest($PragTsMb * 1048576, a.max_bytes * $PragTsPct / 100)
|
||||
then 'ATENTIE: APROAPE FARA LOC' end stare
|
||||
from agg a, ts_free tf
|
||||
where a.tablespace_name = tf.tablespace_name(+)
|
||||
order by a.tablespace_name;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '2. SPATIU TABLESPACE (detaliu pe datafile + cat mai poate creste)' -Text ('mb_poate_creste = liber curent + (maxbytes - alocat) - spatiul real disponibil inainte de ORA-01653, nu doar liberul de acum.' + "`n" + ('Prag de atentie: sub ' + $PragTsMb + ' MB ramasi sau sub ' + $PragTsPct + '% din maximul tablespace-ului.') + "`n`n" + $r2.Text)
|
||||
|
||||
# tablespace-urile care au trecut pragul de atentie - top segmente acolo
|
||||
$r2m = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
with ts_free as (
|
||||
select tablespace_name, sum(bytes) free_bytes from dba_free_space group by tablespace_name
|
||||
), agg as (
|
||||
select f.tablespace_name, sum(f.maxbytes) max_bytes, sum(greatest(f.maxbytes - f.bytes, 0)) creste_bytes
|
||||
from dba_data_files f
|
||||
group by f.tablespace_name
|
||||
)
|
||||
select 'TS_ATENTIE|' || a.tablespace_name
|
||||
from agg a, ts_free tf
|
||||
where a.tablespace_name = tf.tablespace_name(+)
|
||||
and a.max_bytes > 0
|
||||
and (nvl(tf.free_bytes,0) + a.creste_bytes) <
|
||||
greatest($PragTsMb * 1048576, a.max_bytes * $PragTsPct / 100);
|
||||
exit
|
||||
"@
|
||||
$tsProblema = @($r2m.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('TS_ATENTIE|') } | ForEach-Object { $_.Substring(11) } | Where-Object { $_ -match '^[A-Z0-9_]+$' })
|
||||
|
||||
if ($tsProblema.Count -gt 0) {
|
||||
$sbSeg = New-Object System.Text.StringBuilder
|
||||
[void]$sbSeg.AppendLine('set pagesize 0 linesize 250 trimspool on feedback off heading off')
|
||||
foreach ($ts in $tsProblema) {
|
||||
[void]$sbSeg.AppendLine("select 'Tablespace $ts - top $Top segmente:' from dual;")
|
||||
[void]$sbSeg.AppendLine(@"
|
||||
select rpad(owner,20) || rpad(segment_name,35) || rpad(segment_type,18) || round(bytes/1048576) || ' MB'
|
||||
from (select owner, segment_name, segment_type, bytes from dba_segments where tablespace_name = '$ts' order by bytes desc)
|
||||
where rownum <= $Top;
|
||||
"@)
|
||||
if ($ts -eq 'SYSTEM') {
|
||||
[void]$sbSeg.AppendLine("select 'NOTA: privilegiile ANY (ex. DROP ANY TABLE/TRUNCATE ANY TABLE) nu se aplica pe obiecte din schema SYS cand O7_DICTIONARY_ACCESSIBILITY=FALSE - curatarea unui tabel din SYS cere conectare SYSDBA, nu contafin_oracle.' from dual;")
|
||||
}
|
||||
}
|
||||
[void]$sbSeg.AppendLine('exit')
|
||||
$r2s = Invoke-Sql -Sql $sbSeg.ToString()
|
||||
Write-Output ''
|
||||
Write-Output ('--- Top segmente pe tablespace-urile marcate ATENTIE (' + ($tsProblema -join ', ') + ') ---')
|
||||
Write-Output $r2s.Text
|
||||
}
|
||||
|
||||
# MAX_PDB_STORAGE - doar daca CDB si -SysPassword dat
|
||||
Write-Output ''
|
||||
Write-Output '===== 2b. MAX_PDB_STORAGE (CDB$ROOT) ====='
|
||||
if (-not $ver12plus) {
|
||||
Write-Output 'Sarit - baza sub versiunea 12c, nu are CDB/PDB.'
|
||||
} elseif (-not $ConnStrSys) {
|
||||
Write-Output 'Sarit - necesita -SysPassword (conectare SYSDBA + alter session set container=CDB$ROOT; contafin_oracle nu vede limita din PDB).'
|
||||
} else {
|
||||
$rPdb = Invoke-SqlSys -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
begin
|
||||
execute immediate 'alter session set container = CDB`$ROOT';
|
||||
for r in (select con_id, name, open_mode from v`$pdbs order by con_id) loop
|
||||
dbms_output.put_line('PDB con_id=' || r.con_id || ' name=' || r.name || ' open_mode=' || r.open_mode);
|
||||
end loop;
|
||||
begin
|
||||
for r in (select p.con_id, p.name, round(nvl(c.max_size,0)/1048576) mb_max
|
||||
from v`$pdbs p, v`$containers c
|
||||
where p.con_id = c.con_id(+)
|
||||
order by p.con_id) loop
|
||||
dbms_output.put_line(' ' || r.name || ' MAX_PDB_STORAGE(MB)=' || case when r.mb_max = 0 then 'nelimitat/necunoscut' else to_char(r.mb_max) end);
|
||||
end loop;
|
||||
exception when others then
|
||||
dbms_output.put_line('MAX_PDB_STORAGE: interogare v`$containers.max_size esuata (' || sqlerrm || ').');
|
||||
dbms_output.put_line('Verifica manual: ALTER PLUGGABLE DATABASE <pdb> STORAGE; sau interogheaza dba_pdbs/v`$pdbs direct pe server.');
|
||||
end;
|
||||
exception
|
||||
when others then
|
||||
if sqlcode = -1031 then
|
||||
dbms_output.put_line('EROARE la comutarea pe CDB`$ROOT: ORA-01031 (privilegii insuficiente). Aliasul TNS dat tinteste probabil un serviciu de PDB (ex. XEPDB1), nu serviciul radacina al CDB - de pe un serviciu de PDB, SYSDBA nu poate comuta pe CDB`$ROOT. Necesita un alias/serviciu separat care tinteste radacina (de obicei numele instantei, nu al PDB-ului).');
|
||||
else
|
||||
dbms_output.put_line('EROARE la comutarea pe CDB`$ROOT: ' || sqlerrm);
|
||||
end if;
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Write-Output $rPdb.Text
|
||||
}
|
||||
|
||||
# ---------- 2c. Plafonul de date al editiei XE ----------
|
||||
# limita editiei, independenta de maxbytes-ul tablespace-urilor: extinderea poate fi refuzata cu
|
||||
# ORA-12952 desi tablespace-ul mai are loc
|
||||
Write-Output ''
|
||||
Write-Output '===== 2c. PLAFON DE DATE XE ====='
|
||||
$xeCritic = $false
|
||||
if ($r1.Text -notmatch 'Express Edition') {
|
||||
Write-Output 'Sarit - editia nu e Express Edition, nu exista plafon de date pe editie.'
|
||||
} else {
|
||||
$xePlafonGb = if ($verMajor -le 10) { 4 } elseif ($verMajor -eq 11) { 11 } else { 12 }
|
||||
$rXe = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 200 trimspool on feedback off heading off
|
||||
select 'XEFOLOSIT|' || round(nvl(sum(f.bytes),0)/1048576, 2)
|
||||
from dba_data_files f
|
||||
where f.tablespace_name not in ('SYSTEM','SYSAUX')
|
||||
and f.tablespace_name not in (select t.tablespace_name from dba_tablespaces t
|
||||
where t.contents in ('UNDO','TEMPORARY'));
|
||||
exit
|
||||
"@
|
||||
$xeFolositMb = $null
|
||||
foreach ($line in ($rXe.Text -split "`r?`n")) {
|
||||
if ($line.Trim() -match '^XEFOLOSIT\|([\d.]+)$') { $xeFolositMb = [double]$Matches[1] }
|
||||
}
|
||||
if ($null -eq $xeFolositMb) {
|
||||
Write-Output 'Nu am putut masura datele de utilizator (dba_data_files) - vezi erorile de mai sus.'
|
||||
Write-Output $rXe.Text
|
||||
} else {
|
||||
$xePlafonMb = $xePlafonGb * 1024
|
||||
$xeLiberMb = $xePlafonMb - $xeFolositMb
|
||||
$xePragMb = [math]::Max($PragTsMb, $xePlafonMb * $PragTsPct / 100)
|
||||
$xeCritic = ($xeLiberMb -lt $xePragMb)
|
||||
Write-Output ('Editie Express, plafon de date ' + $xePlafonGb + ' GB (masurat pe dba_data_files, fara SYSTEM/SYSAUX/UNDO/TEMP).')
|
||||
Write-Output (' folosit = ' + [math]::Round($xeFolositMb/1024, 2) + ' GB liber pana la plafon = ' + [math]::Round($xeLiberMb, 0) + ' MB')
|
||||
if ($xeCritic) {
|
||||
Write-Output ('[ATENTIE] sub pragul de ' + [math]::Round($xePragMb, 0) + ' MB. Cand plafonul e atins, baza refuza extinderea cu ORA-12952 si nu se mai poate face nimic din baza - elibereaza date sau treci pe alta editie.')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- 3. Audit Oracle ----------
|
||||
$r3 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'AUD`$ (contafin_oracle): ' || count(*) from sys.aud`$;
|
||||
select 'FGA_LOG`$ (contafin_oracle): ' || count(*) from sys.fga_log`$;
|
||||
select 'audit_file_dest = ' || value from v`$parameter where name = 'audit_file_dest';
|
||||
select 'audit_trail = ' || value from v`$parameter where name = 'audit_trail';
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3. AUDIT ORACLE (tabele, din contafin_oracle)' -Text $r3.Text
|
||||
|
||||
if ($ver12plus) {
|
||||
$r3u = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'unified_audit_trail: ' || count(*) || ' randuri' from unified_audit_trail;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3b. UNIFIED AUDIT TRAIL' -Text $r3u.Text
|
||||
} else {
|
||||
Write-Output ''
|
||||
Write-Output '===== 3b. UNIFIED AUDIT TRAIL ====='
|
||||
Write-Output 'Sarit - baza sub versiunea 12c, nu are unified auditing.'
|
||||
}
|
||||
|
||||
if (-not $ConnStrSys) {
|
||||
Write-Output ''
|
||||
Write-Output '===== 3c. AUDIT INTERN (SYSDBA) ====='
|
||||
Write-Output 'Sarit - necesita -SysPassword. sys.aud$/fga_log$ sunt obiecte SYS: privilegiile ANY nu se aplica pe ele (O7_DICTIONARY_ACCESSIBILITY=FALSE), deci contafin_oracle poate primi ORA-01031 mai sus chiar daca are rol DBA.'
|
||||
} else {
|
||||
$r3s = Invoke-SqlSys -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'AUD`$ (sysdba): ' || count(*) from sys.aud`$;
|
||||
select 'FGA_LOG`$ (sysdba): ' || count(*) from sys.fga_log`$;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '3c. AUDIT INTERN (rezultat garantat, conectat SYSDBA)' -Text $r3s.Text
|
||||
}
|
||||
Write-Output 'Fisierele fizice .aud din audit_file_dest (numar + MB reale): vezi sectiunea 6 (-Disc).'
|
||||
Write-Output 'Curatare (doar sugestie, niciodata executata automat): oprire viitoare = alter system set audit_trail=NONE scope=spfile (cere restart instanta); golire sys.aud$/fga_log$ = DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL sau delete direct, ambele SYSDBA; fisierele .aud se pot sterge direct de pe disc (independente de dictionar).'
|
||||
|
||||
# ---------- 4. Alert log / trace / ADR ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 4. ALERT LOG / TRACE / ADR (cai) ====='
|
||||
$diagPaths = @()
|
||||
if ($ver11plus) {
|
||||
$r4 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'DIAG|' || name || '|' || value from v`$diag_info where name in ('Diag Trace','Diag Alert','Diag Incident','Diag Cdump');
|
||||
exit
|
||||
"@
|
||||
Write-Output $r4.Text
|
||||
$diagPaths = @($r4.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('DIAG|') } | ForEach-Object {
|
||||
$parts = $_.Substring(5) -split '\|', 2
|
||||
[PSCustomObject]@{ Label = ('DIAG_' + ($parts[0] -replace '[^A-Za-z0-9]','_')).ToUpper(); Path = $parts[1] }
|
||||
})
|
||||
} else {
|
||||
$r4 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'DIAG|BACKGROUND|' || value from v`$parameter where name = 'background_dump_dest';
|
||||
select 'DIAG|USER|' || value from v`$parameter where name = 'user_dump_dest';
|
||||
select 'DIAG|CORE|' || value from v`$parameter where name = 'core_dump_dest';
|
||||
exit
|
||||
"@
|
||||
Write-Output '(baza sub 11g - fara ADR/diagnostic_dest, foloseste background_dump_dest/user_dump_dest/core_dump_dest)'
|
||||
Write-Output $r4.Text
|
||||
$diagPaths = @($r4.Text -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_.StartsWith('DIAG|') } | ForEach-Object {
|
||||
$parts = $_.Substring(5) -split '\|', 2
|
||||
[PSCustomObject]@{ Label = ('DIAG_' + $parts[0]); Path = $parts[1] }
|
||||
})
|
||||
}
|
||||
Write-Output 'Marimea reala a acestor foldere (alert log, trace, incident, cdump): vezi sectiunea 6 (-Disc) - SQL nu vede sistemul de fisiere.'
|
||||
Write-Output 'Curatare (doar sugestie): adrci exec="set homepath <path>; purge -age <minute> -type ALERT/INCIDENT/TRACE" rulat ca proces extern (prin ExecuteScriptOS) - purjeaza doar diagnostic vechi, nu afecteaza baza.'
|
||||
|
||||
# ---------- 5. Archivelog / Fast Recovery Area ----------
|
||||
$r5 = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'log_mode = ' || log_mode from v`$database;
|
||||
select 'db_recovery_file_dest = ' || nvl(value,'(neconfigurat)') from v`$parameter where name = 'db_recovery_file_dest';
|
||||
select 'db_recovery_file_dest_size(MB) = ' || round(to_number(value)/1048576) from v`$parameter where name = 'db_recovery_file_dest_size';
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '5. ARCHIVELOG / FAST RECOVERY AREA' -Text $r5.Text
|
||||
|
||||
$r5b = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column name format a60
|
||||
select round(space_limit/1048576) mb_limita, round(space_used/1048576) mb_folosit,
|
||||
round(space_reclaimable/1048576) mb_recuperabil, number_of_files
|
||||
from v`$recovery_file_dest;
|
||||
column file_type format a20
|
||||
select file_type, percent_space_used, percent_space_reclaimable, number_of_files
|
||||
from v`$flash_recovery_area_usage
|
||||
order by percent_space_used desc;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '5b. FRA - utilizare pe tip de fisier' -Text $r5b.Text
|
||||
|
||||
# linie separata, fara ambiguitate de coloane, doar pentru pragul de alarma (nu pentru afisare)
|
||||
$r5c = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 100 trimspool on feedback off heading off
|
||||
select 'FRAPCT|' || round(space_used*100/nullif(space_limit,0),1) from v`$recovery_file_dest;
|
||||
exit
|
||||
"@
|
||||
$fraCritic = $false
|
||||
foreach ($line in ($r5c.Text -split "`r?`n")) {
|
||||
if ($line.Trim() -match '^FRAPCT\|([\d.]+)$') {
|
||||
if ([double]$Matches[1] -ge $PragFraPct) { $fraCritic = $true }
|
||||
}
|
||||
}
|
||||
if ($fraCritic) {
|
||||
Write-Output ''
|
||||
Write-Output ('[ATENTIE] FRA peste ' + $PragFraPct + '% din spatiul alocat. Daca log_mode=ARCHIVELOG si FRA se umple complet, baza se blocheaza pe scriere (ORA-19809/ORA-00257).')
|
||||
Write-Output 'Ce se poate face fara backup: marire db_recovery_file_dest_size (daca discul are loc) - imediat, fara pierdere.'
|
||||
Write-Output 'Ce NU se face fara backup real: sterge archivelog-uri neaplicate-la-backup ar rupe recuperarea (RMAN DELETE ARCHIVELOG ... BACKED UP 1 TIMES TO DISK, doar daca exista backup real configurat).'
|
||||
}
|
||||
|
||||
# ---------- 6. Spatiu pe discurile serverului (optional, scrie un .ps1 temporar in DMPDIR) ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 6. SPATIU DISC (server) ====='
|
||||
if (-not $Disc) {
|
||||
Write-Output 'Sarit implicit - ruleaza cu -Disc pentru spatiul liber pe discurile fizice si marimea reala a folderelor oradata/audit/diag/DMPDIR/FRA.'
|
||||
Write-Output 'Este singura parte a scriptului care NU e strict read-only: scrie un .ps1 temporar in DMPDIR (prin sys.ExecuteScriptOS) si il sterge la final.'
|
||||
} else {
|
||||
$rFolders = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 300 trimspool on feedback off heading off
|
||||
select 'ORADATA|' || substr(file_name,1,instr(file_name,'\',-1)-1)
|
||||
from (select distinct substr(file_name,1,instr(file_name,'\',-1)-1) file_name from dba_data_files);
|
||||
select 'AUDITDIR|' || value from v`$parameter where name = 'audit_file_dest';
|
||||
select 'DMPDIR|' || directory_path from all_directories where directory_name = 'DMPDIR';
|
||||
select 'FRADIR|' || value from v`$parameter where name = 'db_recovery_file_dest' and value is not null;
|
||||
exit
|
||||
"@
|
||||
$folders = New-Object System.Collections.ArrayList
|
||||
$seen = New-Object 'System.Collections.Generic.HashSet[string]' ([StringComparer]::OrdinalIgnoreCase)
|
||||
foreach ($line in ($rFolders.Text -split "`r?`n")) {
|
||||
$line = $line.Trim()
|
||||
foreach ($prefix in @('ORADATA','AUDITDIR','DMPDIR','FRADIR')) {
|
||||
if ($line.StartsWith($prefix + '|')) {
|
||||
$p = $line.Substring($prefix.Length + 1).Trim()
|
||||
if ($p -and $seen.Add($prefix + '::' + $p.ToUpper())) {
|
||||
[void]$folders.Add([PSCustomObject]@{ Label = $prefix; Path = $p })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($dp in $diagPaths) {
|
||||
if ($dp.Path -and $seen.Add($dp.Label + '::' + $dp.Path.ToUpper())) {
|
||||
[void]$folders.Add($dp)
|
||||
}
|
||||
}
|
||||
|
||||
$psTemplate = @'
|
||||
$dOut = 'C:\DMPDIR\diag_spatiu_out.txt'
|
||||
Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {
|
||||
$pct = 0
|
||||
if ($_.Size -gt 0) { $pct = [math]::Round($_.FreeSpace/$_.Size*100,1) }
|
||||
"DISC {0} {1} {2} {3}" -f $_.DeviceID, [math]::Round($_.Size/1GB,2), [math]::Round($_.FreeSpace/1GB,2), $pct
|
||||
} | Out-File -Encoding ascii $dOut
|
||||
__FOLDERS__
|
||||
'@
|
||||
$folderLines = foreach ($f in $folders) {
|
||||
$escaped = $f.Path.Replace("'", "''")
|
||||
$lbl = $f.Label
|
||||
@"
|
||||
if (Test-Path -LiteralPath '$escaped') {
|
||||
`$items = Get-ChildItem -LiteralPath '$escaped' -Recurse -File -ErrorAction SilentlyContinue
|
||||
`$cnt = @(`$items).Count
|
||||
`$sum = (`$items | Measure-Object -Property Length -Sum).Sum
|
||||
if (-not `$sum) { `$sum = 0 }
|
||||
"FOLDER $lbl|$escaped|{0}|{1}" -f `$cnt, [math]::Round(`$sum/1MB,1) | Out-File -Encoding ascii -Append `$dOut
|
||||
`$aud = @(`$items | Where-Object { `$_.Extension -ieq '.aud' })
|
||||
if (`$aud.Count -gt 0) {
|
||||
`$audSum = (`$aud | Measure-Object -Property Length -Sum).Sum
|
||||
"AUDFILES $lbl|{0}|{1}" -f `$aud.Count, [math]::Round(`$audSum/1MB,1) | Out-File -Encoding ascii -Append `$dOut
|
||||
}
|
||||
} else {
|
||||
"FOLDER $lbl|$escaped|MISSING" | Out-File -Encoding ascii -Append `$dOut
|
||||
}
|
||||
"@
|
||||
}
|
||||
$psScript = $psTemplate.Replace('__FOLDERS__', ([string]::Join("`n", $folderLines)))
|
||||
$psScriptSql = $psScript.Replace("'", "''")
|
||||
|
||||
$rLaunch = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lcPS server_info.value%type;
|
||||
begin
|
||||
select value into lcPS from server_info where upper(name) = 'POWERSHELLPATH';
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu.ps1'); exception when others then null; end;
|
||||
pack_utils_file.clob2fileX('$psScriptSql', 'DMPDIR', 'diag_spatiu.ps1');
|
||||
sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\diag_spatiu.ps1');
|
||||
dbms_output.put_line('Lansat pe server (' || lcPS || '), astept rezultatul...');
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE la lansare: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
Write-Output $rLaunch.Text
|
||||
|
||||
if ($rLaunch.Text -notmatch 'EROARE la lansare') {
|
||||
$gata = Wait-RemoteFile -Directory 'DMPDIR' -FileName 'diag_spatiu_out.txt' -TimeoutSec 60
|
||||
if (-not $gata) {
|
||||
Write-Output 'EROARE: rezultatul nu a aparut in 60s. Posibile cauze: server_info.POWERSHELLPATH gresit, politica de executie PowerShell blocheaza scriptul, sys.ExecuteScriptOS nu are drept de executie, sau serverul nu e Windows (DMPDIR pe cale Linux - mecanismul ExecuteScriptOS e specific Windows/PowerShell). Verifica manual C:\DMPDIR\diag_spatiu.ps1 pe server.'
|
||||
Invoke-Sql -Sql @"
|
||||
set feedback off
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu.ps1'); exception when others then null; end;
|
||||
/
|
||||
exit
|
||||
"@ | Out-Null
|
||||
Write-Output 'Curatare: am incercat oricum stergerea diag_spatiu.ps1 din DMPDIR (best-effort, fara confirmare de succes daca serverul nu a raspuns).'
|
||||
} else {
|
||||
$rRead = Invoke-Sql -Sql @"
|
||||
set serveroutput on size 1000000
|
||||
set feedback off
|
||||
declare
|
||||
lf utl_file.file_type;
|
||||
lc_line varchar2(32767);
|
||||
begin
|
||||
lf := utl_file.fopen('DMPDIR','diag_spatiu_out.txt','R',32767);
|
||||
begin
|
||||
loop
|
||||
utl_file.get_line(lf, lc_line, 32767);
|
||||
dbms_output.put_line(lc_line);
|
||||
end loop;
|
||||
exception when no_data_found then null;
|
||||
end;
|
||||
utl_file.fclose(lf);
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu_out.txt'); exception when others then null; end;
|
||||
begin pack_utils_file.filedelete('DMPDIR','diag_spatiu.ps1'); exception when others then null; end;
|
||||
exception when others then
|
||||
dbms_output.put_line('EROARE citire: ' || sqlerrm);
|
||||
end;
|
||||
/
|
||||
exit
|
||||
"@
|
||||
$discLines = @()
|
||||
$folderLinesOut = @()
|
||||
foreach ($line in ($rRead.Text -split "`r?`n")) {
|
||||
if ($line -match '^DISC\s+(\S+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)') {
|
||||
$discLines += (' disc {0}: total {1} GB, liber {2} GB ({3}%)' -f $Matches[1], $Matches[2], $Matches[3], $Matches[4])
|
||||
} elseif ($line -match '^FOLDER\s+(\S+)\|(.+)\|MISSING\s*$') {
|
||||
$folderLinesOut += (' {0} ({1}): nu exista pe server' -f $Matches[1], $Matches[2])
|
||||
} elseif ($line -match '^FOLDER\s+(\S+)\|(.+)\|(\d+)\|([\d.]+)\s*$') {
|
||||
$folderLinesOut += (' {0} ({1}): {2} fisiere, {3} MB' -f $Matches[1], $Matches[2], $Matches[3], $Matches[4])
|
||||
} elseif ($line -match '^AUDFILES\s+(\S+)\|(\d+)\|([\d.]+)\s*$') {
|
||||
$folderLinesOut += (' din care .aud: {0} fisiere, {1} MB' -f $Matches[2], $Matches[3])
|
||||
} elseif ($line -match '\S') {
|
||||
$discLines += (' ' + $line)
|
||||
}
|
||||
}
|
||||
Write-Output 'Discuri fixe:'
|
||||
Write-Output ($discLines -join "`n")
|
||||
Write-Output 'Foldere (oradata / audit / diag / DMPDIR / FRA):'
|
||||
Write-Output ($folderLinesOut -join "`n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- 7. Alti mancatori de spatiu ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 7. ALTI MANCATORI DE SPATIU ====='
|
||||
|
||||
$r7a = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'user_recyclebin (schema ' || sys_context('userenv','session_user') || '): ' || count(*) || ' obiecte, ' ||
|
||||
round(sum(space)*8192/1048576) || ' MB (aprox, space in blocuri)'
|
||||
from user_recyclebin;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7a. RECYCLEBIN (schema conectata)' -Text $r7a.Text
|
||||
|
||||
if ($ConnStrSys) {
|
||||
$r7as = Invoke-SqlSys -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'dba_recyclebin (toata baza): ' || count(*) || ' obiecte, ' ||
|
||||
round(sum(space)*8192/1048576) || ' MB (aprox)'
|
||||
from dba_recyclebin;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7a-bis. RECYCLEBIN (toata baza, SYSDBA)' -Text $r7as.Text
|
||||
} else {
|
||||
Write-Output 'RECYCLEBIN la nivel de baza (dba_recyclebin): sarit - necesita -SysPassword.'
|
||||
}
|
||||
|
||||
$r7b = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'UNDO tablespace = ' || value from v`$parameter where name = 'undo_tablespace';
|
||||
select 'UNDO alocat(MB) = ' || round(sum(bytes)/1048576)
|
||||
from dba_data_files
|
||||
where tablespace_name = (select value from v`$parameter where name = 'undo_tablespace');
|
||||
select 'tranzactii active = ' || count(*) from v`$transaction;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7b. UNDO' -Text ($r7b.Text + "`nResize UNDO poate da ORA-03297 daca extenturile nu au expirat inca - de incercat doar dupa ce activitatea scade, niciodata automat.")
|
||||
|
||||
$r7c = Invoke-Sql -Sql @"
|
||||
set pagesize 0 linesize 250 trimspool on feedback off heading off
|
||||
select 'dba_tab_stats_history: ' || count(*) || ' randuri, cel mai vechi = ' || to_char(min(stats_update_time),'yyyy-mm-dd')
|
||||
from dba_tab_stats_history;
|
||||
select 'dba_scheduler_job_run_details: ' || count(*) || ' randuri, cel mai vechi = ' || to_char(min(log_date),'yyyy-mm-dd')
|
||||
from dba_scheduler_job_run_details;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7c. ISTORIC STATISTICI / SCHEDULER' -Text ($r7c.Text + "`nCuratare (doar sugestie): DBMS_STATS.PURGE_STATS(<data>); DBMS_SCHEDULER.PURGE_LOG(log_history => <zile>).")
|
||||
|
||||
$r7d = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column tablespace_name format a20
|
||||
select tablespace_name, round(sum(bytes)/1048576) mb_alocat from dba_temp_files group by tablespace_name;
|
||||
column tablespace_name format a20
|
||||
select tablespace_name, round(sum(bytes_used)/1048576) mb_folosit, round(sum(bytes_free)/1048576) mb_liber
|
||||
from v`$temp_space_header group by tablespace_name;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title '7d. TEMP (alocat vs folosit)' -Text $r7d.Text
|
||||
|
||||
$r7e = Invoke-Sql -Sql @"
|
||||
set pagesize 100 linesize 250 trimspool on feedback off
|
||||
column owner format a20
|
||||
column segment_name format a35
|
||||
column segment_type format a18
|
||||
column tablespace_name format a15
|
||||
select * from (
|
||||
select owner, segment_name, segment_type, tablespace_name, round(bytes/1048576) mb
|
||||
from dba_segments
|
||||
order by bytes desc
|
||||
) where rownum <= $Top;
|
||||
exit
|
||||
"@
|
||||
Show-Section -Title ('7e. TOP ' + $Top + ' SEGMENTE DIN TOATA BAZA (generic, fara nume hardcodate)') -Text $r7e.Text
|
||||
|
||||
# ---------- 8. Verdict ----------
|
||||
Write-Output ''
|
||||
Write-Output '===== 8. VERDICT ====='
|
||||
if ($tsProblema.Count -gt 0) {
|
||||
Write-Output ('Tablespace-uri aproape fara loc: ' + ($tsProblema -join ', ') + '. Vezi sectiunea 2 pentru top segmente acolo - candidatii de curatare/crestere maxbytes sunt acolo.')
|
||||
} else {
|
||||
Write-Output ('Niciun tablespace sub pragul de atentie (' + $PragTsMb + ' MB sau ' + $PragTsPct + '% din maxim, sectiunea 2).')
|
||||
}
|
||||
if ($xeCritic) {
|
||||
Write-Output ('Plafonul de date al editiei XE e aproape atins (sectiunea 2c) - la ORA-12952 nu se mai poate face nimic din baza. Prioritate maxima: eliberare de date sau trecere pe alta editie.')
|
||||
}
|
||||
if ($fraCritic) {
|
||||
Write-Output ('FRA peste ' + $PragFraPct + '% din spatiul alocat (sectiunea 5b) - risc de blocaj pe scriere daca log_mode=ARCHIVELOG. Prioritate: verifica arhivarea/backup-ul inainte sa se umple complet.')
|
||||
}
|
||||
Write-Output 'Ordine tipica de curatare (cea mai sigura primul): fisiere .aud vechi din audit_file_dest (sters direct pe disc, fara privilegii DB) -> adrci purge pe alert/trace/incident vechi -> istoric statistici/scheduler (DBMS_STATS.PURGE_STATS / DBMS_SCHEDULER.PURGE_LOG) -> recyclebin -> resize UNDO dupa ce scade activitatea -> curatare SYS.aud$/fga_log$ sau alte tabele interne (cere SYSDBA) -> ca ultima solutie, recreare PDB (export/import).'
|
||||
if (-not $ConnStrSys) {
|
||||
Write-Output 'Fara -SysPassword: sectiunile 2b (MAX_PDB_STORAGE), 3c (audit intern sys.aud$/fga_log$) si 7a-bis (dba_recyclebin) au fost sarite - ruleaza cu -SysPassword daca ai parola SYS a acestui client pentru imaginea completa.'
|
||||
}
|
||||
if (-not $Disc) {
|
||||
Write-Output 'Fara -Disc: marimile reale pe disc (audit_file_dest, alert/trace/ADR, oradata, FRA, discuri fizice) nu au fost masurate - ruleaza cu -Disc pentru ele.'
|
||||
}
|
||||
|
||||
Remove-TempDir
|
||||
exit 0
|
||||
406
utile/livrare.ps1
Normal file
406
utile/livrare.ps1
Normal file
@@ -0,0 +1,406 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Lantul complet de dinaintea si din timpul unui commit: sync text VFP, curatenie,
|
||||
verificari de livrare, stare repo-uri, commit + push.
|
||||
|
||||
.DESCRIPTION
|
||||
1. Sincronizare, aleasa dupa starea arborelui (git status --porcelain) in AMBELE repo-uri:
|
||||
- tree curat (inceput de sesiune, nimic necomis) -> COMUN\scripts\roa_sync.ps1 -ProjectRoot
|
||||
<root>: svn update (inclusiv externalul COMUN) + git_sync (texte .??2) + commit
|
||||
"sync SVN rN" + reconciliere cu origin. Prinde aici non-fast-forward-ul cu origin (nu abia
|
||||
la push, pasul 5). Daca roa_sync.ps1 lipseste, fallback pe git_sync.ps1 (doar text, fara
|
||||
SVN), cu avertisment.
|
||||
- tree murdar (cazul normal la livrare, cu modificari necomise pe disc) -> DOAR git_sync.ps1:
|
||||
roa_sync ar face `git add -A` + commit "sync SVN" pe main peste munca in curs, inglobind-o
|
||||
intr-un commit etichetat gresit (fluxul_svn_git.md: "sync pe main doar din stare curata").
|
||||
Iesire nenula -> opreste tot. Se sare cu -FaraSync; doar partea SVN se sare cu -FaraSvn
|
||||
(roa_sync -GitOnly, aplicabil doar cand tree-ul e curat). NU ruleaza nimic in -DryRun (roa_sync
|
||||
face svn update real si poate comite/impinge) - doar anunta ce s-ar alege si de ce.
|
||||
2. curatenie.ps1 -ProjectRoot <root> - sterge artefactele de lucru (neurmarite de git).
|
||||
3. Verificari de livrare (avertismente, neblocante): changelog neatins, fisiere de runda
|
||||
ramase, binare VFP fara perechea text in modificari, fisiere ce urmeaza sa intre in git
|
||||
dar sunt necunoscute SVN-ului ("?" la svn status - munca reala trebuie sa treaca intai
|
||||
prin SVN, vezi fluxul_svn_git.md).
|
||||
4. Stare repo proiect si repo COMUN (separat, partajat de toate aplicatiile ROA): git fetch +
|
||||
compara HEAD cu origin/<ramura> (semnaleaza daca ramura locala e in urma), apoi
|
||||
git status --short + git diff --stat.
|
||||
5. Commit + push. Proiectul implicit; COMUN doar cu -Comun explicit (altfel doar raportat).
|
||||
Push respins non-fast-forward (frecvent pe COMUN, comun tuturor aplicatiilor ROA): fetch +
|
||||
rebase peste origin + reincercare o singura data. Conflicte la rebase -> rebase --abort,
|
||||
mesaj clar, exit nenul (nu lasa repo-ul in rebase in curs). Niciodata push --force
|
||||
(nici --force-with-lease). Comite pe ramura curenta, nu creeaza alta.
|
||||
6. -DryRun: ruleaza pasii 2-4 (curatenia in -DryRun; pasul 1 doar anuntat, nu executat) si se
|
||||
opreste inainte de commit.
|
||||
|
||||
.PARAMETER ProjectRoot
|
||||
Radacina proiectului (implicit dedus, ca la curatenie.ps1 - doua nivele deasupra acestui script).
|
||||
|
||||
.PARAMETER Mesaj
|
||||
Mesajul de commit. Obligatoriu la o rulare reala (fara -DryRun).
|
||||
|
||||
.PARAMETER Comun
|
||||
Comite si impinge si repo-ul COMUN (implicit doar proiectul).
|
||||
|
||||
.PARAMETER FaraSync
|
||||
Sare peste tot pasul 1 (roa_sync/git_sync) - util cand nu s-a atins niciun binar VFP si nici
|
||||
SVN-ul nu trebuie adus la zi.
|
||||
|
||||
.PARAMETER FaraSvn
|
||||
Cand tree-ul e curat (altfel se ruleaza oricum doar git_sync): ruleaza roa_sync.ps1 -GitOnly,
|
||||
fara svn update si fara regenerarea textelor, doar commit sync + reconciliere origin +
|
||||
inchidere branch-uri claude/*. Util cand SVN nu e disponibil sau nu s-a atins nimic in SVN.
|
||||
Ignorat daca roa_sync.ps1 lipseste (fallback-ul pe git_sync.ps1 nu are oricum pas SVN).
|
||||
|
||||
.PARAMETER FaraPush
|
||||
Doar commit local, fara push.
|
||||
|
||||
.PARAMETER DryRun
|
||||
Nu modifica nimic - arata ce s-ar comite si unde. Pasul 1 nu se executa (roa_sync ar face svn
|
||||
update real si poate comite/impinge) - doar anunta ce s-ar alege (roa_sync sau git_sync) si de ce.
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -DryRun
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -Mesaj "achizitie import: rebindare ControlSource"
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -Mesaj "conventie noua in COMUN" -Comun
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -Mesaj "doar .prg, fara binare" -FaraSync -FaraPush
|
||||
|
||||
.EXAMPLE
|
||||
powershell -File COMUN\utile\livrare.ps1 -Mesaj "SVN indisponibil acum" -FaraSvn
|
||||
#>
|
||||
param(
|
||||
[string]$ProjectRoot,
|
||||
[string]$Mesaj,
|
||||
[switch]$Comun,
|
||||
[switch]$FaraSync,
|
||||
[switch]$FaraSvn,
|
||||
[switch]$FaraPush,
|
||||
[switch]$DryRun
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not $ProjectRoot) { $ProjectRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent }
|
||||
$comunPath = Join-Path $ProjectRoot 'COMUN'
|
||||
$roaSync = Join-Path $ProjectRoot 'COMUN\scripts\roa_sync.ps1'
|
||||
$gitSync = 'D:\ROA\UTIL\foxbin2prg\git_sync.ps1'
|
||||
$curatenie = Join-Path $PSScriptRoot 'curatenie.ps1'
|
||||
|
||||
if (-not $DryRun -and -not $Mesaj) {
|
||||
Write-Output 'livrare: -Mesaj este obligatoriu (sau ruleaza cu -DryRun)'
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Output ('livrare: ProjectRoot=' + $ProjectRoot)
|
||||
|
||||
# --- tree curat in ambele repo-uri? roa_sync e unealta de inceput de sesiune (stare curata),
|
||||
# nu de livrare cu modificari necomise pe disc (fluxul_svn_git.md) ---
|
||||
function Test-TreeCurat($repoPath) {
|
||||
if (-not (Test-Path (Join-Path $repoPath '.git'))) { return $true }
|
||||
return (@(& git -C $repoPath status --porcelain).Count -eq 0)
|
||||
}
|
||||
$treeCurat = (Test-TreeCurat $ProjectRoot) -and (Test-TreeCurat $comunPath)
|
||||
|
||||
function Ruleaza-GitSync {
|
||||
if (-not (Test-Path $gitSync)) {
|
||||
Write-Output ('[1] git_sync: NU s-a gasit ' + $gitSync)
|
||||
exit 2
|
||||
}
|
||||
& powershell -ExecutionPolicy Bypass -File $gitSync -ProjectRoot $ProjectRoot
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output ('[1] git_sync: ESUAT (cod ' + $LASTEXITCODE + ') - opresc tot, nu se comite')
|
||||
exit 2
|
||||
}
|
||||
Write-Output '[1] git_sync: OK'
|
||||
}
|
||||
|
||||
# --- pas 1: tree curat -> roa_sync (fallback git_sync daca lipseste); tree murdar -> doar git_sync ---
|
||||
if ($FaraSync) {
|
||||
Write-Output '[1] sincronizare: sarita (-FaraSync)'
|
||||
} elseif ($DryRun) {
|
||||
# roa_sync face svn update real si poate comite/impinge (chiar si cu -GitOnly) - nu ruleaza in -DryRun.
|
||||
if (-not $treeCurat) {
|
||||
Write-Output ('[1] sincronizare: sarita (-DryRun) - modificari necomise, ar rula doar ' + $gitSync + ' (roa_sync ar ingloba munca in curs intr-un commit "sync SVN")')
|
||||
} elseif (Test-Path $roaSync) {
|
||||
$variantaGO = if ($FaraSvn) { ' -GitOnly' } else { '' }
|
||||
Write-Output ('[1] sincronizare: sarita (-DryRun) - tree curat, ar rula ' + $roaSync + $variantaGO)
|
||||
} else {
|
||||
Write-Output ('[1] sincronizare: sarita (-DryRun) - tree curat, roa_sync.ps1 lipseste, ar rula fallback ' + $gitSync)
|
||||
}
|
||||
} elseif (-not $treeCurat) {
|
||||
Write-Output '[1] sincronizare: modificari necomise -> rulez doar git_sync (roa_sync ar ingloba munca in curs intr-un commit "sync SVN")'
|
||||
Ruleaza-GitSync
|
||||
} elseif (Test-Path $roaSync) {
|
||||
$rsArgs = @('-ProjectRoot', $ProjectRoot)
|
||||
if ($FaraSvn) { $rsArgs += '-GitOnly' }
|
||||
& powershell -ExecutionPolicy Bypass -File $roaSync @rsArgs
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output ('[1] roa_sync: ESUAT (cod ' + $LASTEXITCODE + ') - opresc tot, nu se comite')
|
||||
exit 2
|
||||
}
|
||||
Write-Output '[1] roa_sync: OK'
|
||||
} else {
|
||||
Write-Output ('[1] roa_sync: NU s-a gasit (' + $roaSync + ') - fallback pe git_sync.ps1')
|
||||
Ruleaza-GitSync
|
||||
}
|
||||
|
||||
# --- pas 2: curatenie ---
|
||||
$curArgs = @('-ProjectRoot', $ProjectRoot)
|
||||
if ($DryRun) { $curArgs += '-DryRun' }
|
||||
Write-Output '[2] curatenie:'
|
||||
& powershell -ExecutionPolicy Bypass -File $curatenie @curArgs | ForEach-Object { Write-Output (' ' + $_) }
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Output ('[2] curatenie: cod neasteptat ' + $LASTEXITCODE + ' (continui)')
|
||||
}
|
||||
|
||||
# --- fisiere modificate per repo (dupa curatenie) ---
|
||||
function Get-ChangedFiles($repoPath) {
|
||||
if (-not (Test-Path (Join-Path $repoPath '.git'))) { return @() }
|
||||
$rezultat = New-Object System.Collections.ArrayList
|
||||
foreach ($linie in (& git -C $repoPath status --porcelain --untracked-files=all)) {
|
||||
if (-not $linie) { continue }
|
||||
$cale = $linie.Substring(3)
|
||||
if ($cale -match ' -> ') { $cale = ($cale -split ' -> ')[1] }
|
||||
$cale = $cale.Trim('"')
|
||||
[void]$rezultat.Add($cale)
|
||||
}
|
||||
return $rezultat
|
||||
}
|
||||
|
||||
$modifProiect = Get-ChangedFiles $ProjectRoot
|
||||
$modifComun = Get-ChangedFiles $comunPath
|
||||
|
||||
# --- pas 3: verificari de livrare (avertismente, neblocante) ---
|
||||
$avertismente = New-Object System.Collections.ArrayList
|
||||
|
||||
# fisiere din $modif care apar cu "?" (necunoscut) la svn status - munca reala trebuie sa treaca
|
||||
# intai prin SVN (fluxul_svn_git.md). Fara svn sau folder ce nu e working copy -> tacere.
|
||||
function Get-SvnNeurmarite($repoPath, $modif) {
|
||||
if ($modif.Count -eq 0) { return @() }
|
||||
if (-not (Get-Command svn -ErrorAction SilentlyContinue)) { return @() }
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$iesire = & svn status $repoPath 2>$null
|
||||
if ($LASTEXITCODE -ne 0) { return @() }
|
||||
$necunoscute = New-Object System.Collections.Generic.HashSet[string] ([StringComparer]::OrdinalIgnoreCase)
|
||||
foreach ($linie in $iesire) {
|
||||
if ($linie -match '^\?\s+(.+)$') {
|
||||
$cale = $Matches[1].Trim()
|
||||
if ($cale.StartsWith($repoPath, [System.StringComparison]::OrdinalIgnoreCase)) {
|
||||
$cale = $cale.Substring($repoPath.Length).TrimStart('\', '/')
|
||||
}
|
||||
[void]$necunoscute.Add(($cale -replace '\\', '/'))
|
||||
}
|
||||
}
|
||||
return @($modif | Where-Object { $necunoscute.Contains($_) })
|
||||
}
|
||||
|
||||
function Verifica-Livrare($modif, $repoPath, $eticheta) {
|
||||
$codExt = @('.prg', '.vc2', '.sc2', '.ps1')
|
||||
$areCod = $modif | Where-Object { $ext = [System.IO.Path]::GetExtension($_).ToLower(); $codExt -contains $ext }
|
||||
$areChangelog = $modif | Where-Object { $_ -match 'changelog.*\.txt$' }
|
||||
if ($areCod -and -not $areChangelog -and $eticheta -eq 'proiect') {
|
||||
[void]$script:avertismente.Add('changelog neatins (' + $eticheta + ') desi s-a modificat cod')
|
||||
}
|
||||
|
||||
foreach ($f in $modif) {
|
||||
$ext = [System.IO.Path]::GetExtension($f).ToLower()
|
||||
if ($ext -eq '.vcx') { $pereche = [System.IO.Path]::ChangeExtension($f, '.vc2') }
|
||||
elseif ($ext -eq '.scx') { $pereche = [System.IO.Path]::ChangeExtension($f, '.sc2') }
|
||||
else { continue }
|
||||
if ($modif -notcontains $pereche) {
|
||||
[void]$script:avertismente.Add('binar fara text sincronizat in modificari (' + $eticheta + '): ' + $f)
|
||||
}
|
||||
}
|
||||
|
||||
$docsPath = Join-Path $repoPath 'docs'
|
||||
if (Test-Path $docsPath) {
|
||||
$ramase = Get-ChildItem -Path $docsPath -Include @('propuneri_*.md', 'handoff*.md', 'runda*.md') -Recurse -ErrorAction SilentlyContinue
|
||||
foreach ($r in $ramase) {
|
||||
[void]$script:avertismente.Add('fisier de runda ramas (' + $eticheta + '): docs\' + $r.Name)
|
||||
}
|
||||
}
|
||||
|
||||
$neurmarite = Get-SvnNeurmarite $repoPath $modif
|
||||
foreach ($f in $neurmarite) {
|
||||
[void]$script:avertismente.Add('fisier necunoscut SVN (' + $eticheta + '), fa svn add + svn commit intai: ' + $f)
|
||||
}
|
||||
}
|
||||
|
||||
Verifica-Livrare $modifProiect $ProjectRoot 'proiect'
|
||||
Verifica-Livrare $modifComun $comunPath 'COMUN'
|
||||
|
||||
Write-Output '[3] verificari de livrare:'
|
||||
if ($avertismente.Count -eq 0) {
|
||||
Write-Output ' fara avertismente'
|
||||
} else {
|
||||
foreach ($a in $avertismente) { Write-Output (' ATENTIE: ' + $a) }
|
||||
}
|
||||
|
||||
# --- ramura locala vs origin (fetch + numarare ahead/behind) ---
|
||||
function Get-StareFetch($repoPath) {
|
||||
# ErrorActionPreference local 'Continue': altfel 2>$null pe un exe extern (chiar la iesire 0,
|
||||
# git scrie mesaje normale pe stderr) devine NativeCommandError terminal sub preferinta 'Stop'.
|
||||
$ErrorActionPreference = 'Continue'
|
||||
if (-not (Test-Path (Join-Path $repoPath '.git'))) { return $null }
|
||||
$remote = & git -C $repoPath remote
|
||||
if (-not $remote) { return @{ AreRemote = $false } }
|
||||
& git -C $repoPath fetch --quiet 2>$null | Out-Null
|
||||
$fetchOk = ($LASTEXITCODE -eq 0)
|
||||
$upstream = (& git -C $repoPath rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>$null)
|
||||
if ($LASTEXITCODE -ne 0 -or -not $upstream) {
|
||||
return @{ AreRemote = $true; FetchOk = $fetchOk; AreUpstream = $false }
|
||||
}
|
||||
$numere = (& git -C $repoPath rev-list --left-right --count "$upstream...HEAD" 2>$null) -split '\s+' | Where-Object { $_ -ne '' }
|
||||
return @{ AreRemote = $true; FetchOk = $fetchOk; AreUpstream = $true; Upstream = $upstream; Behind = [int]$numere[0]; Ahead = [int]$numere[1] }
|
||||
}
|
||||
|
||||
function Scrie-StareFetch($stare) {
|
||||
if (-not $stare) { return }
|
||||
if (-not $stare.AreRemote) { return }
|
||||
if (-not $stare.FetchOk) { Write-Output ' (fetch esuat, sar verificarea fata de origin)'; return }
|
||||
if (-not $stare.AreUpstream) { return }
|
||||
if ($stare.Behind -gt 0) {
|
||||
Write-Output (' ramura locala e in urma cu ' + $stare.Behind + ' commit-uri fata de ' + $stare.Upstream)
|
||||
}
|
||||
}
|
||||
|
||||
# --- pas 4: stare repo-uri ---
|
||||
Write-Output '[4] stare repo proiect:'
|
||||
$stareProiect = Get-StareFetch $ProjectRoot
|
||||
Scrie-StareFetch $stareProiect
|
||||
& git -C $ProjectRoot status --short | ForEach-Object { Write-Output (' ' + $_) }
|
||||
& git -C $ProjectRoot diff --stat HEAD | ForEach-Object { Write-Output (' ' + $_) }
|
||||
|
||||
Write-Output '[4] stare repo COMUN:'
|
||||
if (Test-Path (Join-Path $comunPath '.git')) {
|
||||
$stareComun = Get-StareFetch $comunPath
|
||||
Scrie-StareFetch $stareComun
|
||||
& git -C $comunPath status --short | ForEach-Object { Write-Output (' ' + $_) }
|
||||
& git -C $comunPath diff --stat HEAD | ForEach-Object { Write-Output (' ' + $_) }
|
||||
} else {
|
||||
Write-Output ' (fara repo git in COMUN)'
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Output '[5] commit/push: sarit (-DryRun)'
|
||||
if ($modifProiect.Count -gt 0) {
|
||||
Write-Output (' ar comite in proiect (' + $modifProiect.Count + ' fisiere)')
|
||||
} else {
|
||||
Write-Output ' proiect: nimic de comis'
|
||||
}
|
||||
if ($modifComun.Count -gt 0) {
|
||||
if ($Comun) {
|
||||
Write-Output (' ar comite in COMUN (' + $modifComun.Count + ' fisiere)')
|
||||
} else {
|
||||
Write-Output (' COMUN are ' + $modifComun.Count + ' fisiere necomise - nu se comite fara -Comun')
|
||||
}
|
||||
} else {
|
||||
Write-Output ' COMUN: nimic de comis'
|
||||
}
|
||||
exit 0
|
||||
}
|
||||
|
||||
# --- pas 5: commit + push ---
|
||||
$exitCode = 0
|
||||
|
||||
# push, si daca e respins non-fast-forward: fetch + rebase peste upstream + o singura reincercare.
|
||||
# Conflicte la rebase -> rebase --abort (nu lasa repo-ul in rebase in curs) + esec, fara push --force.
|
||||
function Invoke-PushCuRebaseRetry($repoPath, $eticheta) {
|
||||
# ErrorActionPreference local 'Continue': vezi motivul in Get-StareFetch.
|
||||
$ErrorActionPreference = 'Continue'
|
||||
# | Out-Null pe fiecare apel git: stdout-ul lui n-ar trebui sa ajunga in valoarea
|
||||
# intoarsa de functie (rezultatul e capturat de apelant) - vezi Comite-Si-Impinge.
|
||||
& git -C $repoPath push | Out-Null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': push OK')
|
||||
return 0
|
||||
}
|
||||
& git -C $repoPath fetch --quiet 2>$null | Out-Null
|
||||
$upstream = (& git -C $repoPath rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>$null)
|
||||
if ($LASTEXITCODE -ne 0 -or -not $upstream) {
|
||||
Write-Host ('[5] ' + $eticheta + ': PUSH ESUAT (fara upstream de comparat)')
|
||||
return 1
|
||||
}
|
||||
$numere = (& git -C $repoPath rev-list --left-right --count "$upstream...HEAD" 2>$null) -split '\s+' | Where-Object { $_ -ne '' }
|
||||
$behind = [int]$numere[0]
|
||||
if ($behind -eq 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': PUSH ESUAT (nu e in urma fata de ' + $upstream + ', alta cauza)')
|
||||
return 1
|
||||
}
|
||||
Write-Host ('[5] ' + $eticheta + ': push respins, ramura in urma cu ' + $behind + ' fata de ' + $upstream + ' - rebase')
|
||||
& git -C $repoPath rebase $upstream | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
& git -C $repoPath rebase --abort 2>$null | Out-Null
|
||||
Write-Host ('[5] ' + $eticheta + ': REBASE CU CONFLICTE - abort facut, e nevoie de interventie manuala')
|
||||
return 1
|
||||
}
|
||||
Write-Host ('[5] ' + $eticheta + ': rebase OK, reincerc push')
|
||||
& git -C $repoPath push | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': PUSH ESUAT si dupa rebase')
|
||||
return 1
|
||||
}
|
||||
Write-Host ('[5] ' + $eticheta + ': push OK dupa rebase')
|
||||
return 0
|
||||
}
|
||||
|
||||
function Comite-Si-Impinge($repoPath, $eticheta, $faraPush, $mesajFile) {
|
||||
# mesajele folosesc Write-Host (nu Write-Output): functia e apelata cu rezultatul
|
||||
# capturat intr-o variabila, iar Write-Output ar ajunge in valoarea returnata.
|
||||
if (-not (Test-Path (Join-Path $repoPath '.git'))) {
|
||||
Write-Host ('[5] ' + $eticheta + ': fara repo git, sarit')
|
||||
return 0
|
||||
}
|
||||
& git -C $repoPath add -A | Out-Null
|
||||
& git -C $repoPath diff --cached --quiet
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': nimic de comis')
|
||||
return 0
|
||||
}
|
||||
$ramura = (& git -C $repoPath rev-parse --abbrev-ref HEAD)
|
||||
# -F <fisier>, nu -m $Mesaj: PowerShell 5.1 nu escapeaza ghilimele/backtick/$ cand paseaza
|
||||
# argumente catre un exe nativ - un mesaj cu ghilimele duble ("sync SVN") sparge -m $Mesaj.
|
||||
& git -C $repoPath commit -F $mesajFile | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host ('[5] ' + $eticheta + ': COMMIT ESUAT pe ramura ' + $ramura)
|
||||
return 1
|
||||
}
|
||||
Write-Host ('[5] ' + $eticheta + ': commit OK pe ramura ' + $ramura)
|
||||
if ($faraPush) {
|
||||
Write-Host ('[5] ' + $eticheta + ': push sarit (-FaraPush)')
|
||||
return 0
|
||||
}
|
||||
return (Invoke-PushCuRebaseRetry $repoPath $eticheta)
|
||||
}
|
||||
|
||||
# mesajul de commit trece printr-un fisier temporar (nu ca argument -m): singurul mod sigur
|
||||
# de a duce prin PowerShell->exe nativ un text cu ghilimele/backtick/$/linii multiple/"-" la
|
||||
# inceput de linie fara sa fie interpretat sau trunchiat. Sters mereu, inclusiv pe esec.
|
||||
$mesajDir = $null
|
||||
try {
|
||||
$mesajDir = Join-Path ([System.IO.Path]::GetTempPath()) ('livrare_' + [guid]::NewGuid().ToString('N'))
|
||||
New-Item -ItemType Directory -Path $mesajDir | Out-Null
|
||||
$mesajFile = Join-Path $mesajDir 'mesaj_commit.txt'
|
||||
# UTF8Encoding($false): fara BOM - Out-File -Encoding utf8 scrie BOM in PS 5.1, iar git
|
||||
# il baga in mesajul de commit ca prim caracter (U+FEFF) daca-l citim cu -F.
|
||||
[System.IO.File]::WriteAllText($mesajFile, $Mesaj, (New-Object System.Text.UTF8Encoding $false))
|
||||
|
||||
$exitCode += (Comite-Si-Impinge $ProjectRoot 'proiect' $FaraPush $mesajFile)
|
||||
|
||||
if ($Comun) {
|
||||
$exitCode += (Comite-Si-Impinge $comunPath 'COMUN' $FaraPush $mesajFile)
|
||||
} elseif ($modifComun.Count -gt 0) {
|
||||
Write-Output ('[5] COMUN: ' + $modifComun.Count + ' fisiere necomise - nu se comite fara -Comun')
|
||||
}
|
||||
} finally {
|
||||
if ($mesajDir -and (Test-Path $mesajDir)) { Remove-Item -LiteralPath $mesajDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
if ($exitCode -gt 0) { exit 3 }
|
||||
Write-Output 'livrare: OK'
|
||||
exit 0
|
||||
689
utile/publicare_scripturi.ps1
Normal file
689
utile/publicare_scripturi.ps1
Normal file
@@ -0,0 +1,689 @@
|
||||
# publicare_scripturi.ps1 - publica scripturile de migrare .sql catre clientii ROA.
|
||||
# Doi pasi, exact ca formularul din tasks.exe (clase\generare_script.vcx):
|
||||
# 1. import - scrie fiecare .sql in CONTAFIN_ORACLE.UPD_DATABASE de pe ROA_CENTRAL
|
||||
# (script_order = 0, un rand = un script intreg); daca script_name exista deja,
|
||||
# face update pe id, ca sa se republice continutul corectat;
|
||||
# 2. arhiva - regenereaza database_<luna>.zip / databasen_<luna>.zip si indexii
|
||||
# roa_database.xml / roa_databasen.xml in Y:\ROAUPDATE\_UPDATE.
|
||||
# Continutul din arhiva se citeste INAPOI din baza, nu de pe disc, si se compara octet cu octet cu
|
||||
# fisierul sursa - deci arhiva contine exact ce vor primi clientii. Optional (implicit pornit),
|
||||
# arhiva generata se citeste inapoi prin zip_util_pkg, cititorul Oracle al clientului.
|
||||
#
|
||||
# Configurarea se citeste din settings.ini-ul lui tasks.exe (aceleasi chei pe care le foloseste
|
||||
# formularul): [connection] host_database/username_database/password_database, [folder]
|
||||
# script_folder (\SCRIPTURI\ -> \SCRIPTURI_CLAR\), roa_output (+ _UPDATE) si sqlplus_exe, [script]
|
||||
# prefixele valide. Aliasul TNS se ia din DSN-ul ODBC numit in host_database (cheia ServerName din
|
||||
# registri). Orice parametru dat explicit are prioritate fata de ini.
|
||||
#
|
||||
# Utilizare:
|
||||
# powershell -File COMUN\utile\publicare_scripturi.ps1 -DryRun
|
||||
# powershell -File COMUN\utile\publicare_scripturi.ps1 -Fisier a.sql,b.sql
|
||||
# powershell -File COMUN\utile\publicare_scripturi.ps1 -Luna 2026-08
|
||||
# powershell -File COMUN\utile\publicare_scripturi.ps1 -Luna 2026-08 -DoarArhiva
|
||||
param(
|
||||
[string[]]$Fisier,
|
||||
[string]$Luna,
|
||||
[string]$Settings = 'D:\PROIECTE\fox\tasks\settings.ini',
|
||||
[string]$DirScripturi,
|
||||
[string]$ZipPath,
|
||||
[string]$BackupPath,
|
||||
[switch]$DoarImport,
|
||||
[switch]$DoarArhiva,
|
||||
[switch]$Toate,
|
||||
[switch]$FaraVerificareZip,
|
||||
[switch]$DryRun,
|
||||
[switch]$PastreazaTemp,
|
||||
[string]$Alias,
|
||||
[string]$User,
|
||||
[string]$Password,
|
||||
[string]$SqlPlus
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
|
||||
# octeti per bucata trimisa/citita ca hexazecimal (2 caractere per octet, sub limita de linie sqlplus)
|
||||
$BUCATA = 900
|
||||
# bucati per bloc PL/SQL (sursa unui bloc trebuie sa ramana sub ~64k)
|
||||
$BUCATI_PER_BLOC = 15
|
||||
|
||||
function Scrie-Titlu {
|
||||
param([string]$Text)
|
||||
Write-Output ''
|
||||
Write-Output ('===== ' + $Text + ' =====')
|
||||
}
|
||||
|
||||
function Opreste {
|
||||
param([string]$Mesaj)
|
||||
Write-Output ''
|
||||
Write-Output ('EROARE: ' + $Mesaj)
|
||||
Curata-Temp
|
||||
exit 1
|
||||
}
|
||||
|
||||
function Curata-Temp {
|
||||
if ($PastreazaTemp) {
|
||||
if (Test-Path $TempDir) { Write-Output ('Temp pastrat: ' + $TempDir) }
|
||||
return
|
||||
}
|
||||
if (Test-Path $TempDir) { Remove-Item -LiteralPath $TempDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
function Invoke-SqlPlus {
|
||||
# ruleaza un script sqlplus; intoarce textul si codul de iesire (whenever sqlerror => cod <> 0)
|
||||
param([string]$Sql, [string]$Nume = 'q')
|
||||
$f = Join-Path $TempDir ($Nume + '_' + [guid]::NewGuid().ToString('N') + '.sql')
|
||||
$antet = "whenever sqlerror exit failure rollback`r`nwhenever oserror exit failure`r`nset define off`r`nset feedback off`r`n"
|
||||
[System.IO.File]::WriteAllText($f, ($antet + $Sql), [System.Text.Encoding]::ASCII)
|
||||
try {
|
||||
$out = & $SqlPlus -L -S $ConnStr ('@' + $f) 2>&1
|
||||
$cod = $LASTEXITCODE
|
||||
} catch {
|
||||
$out = 'EROARE lansare sqlplus: ' + $_.Exception.Message
|
||||
$cod = -1
|
||||
}
|
||||
if (-not $PastreazaTemp) { Remove-Item -LiteralPath $f -Force -ErrorAction SilentlyContinue }
|
||||
$text = ($out | ForEach-Object { [string]$_ }) -join "`n"
|
||||
[PSCustomObject]@{ Text = $text; Cod = $cod }
|
||||
}
|
||||
|
||||
function Test-Rezultat {
|
||||
param($R, [string]$Context)
|
||||
if ($R.Cod -ne 0 -or $R.Text -match 'ORA-\d{5}|SP2-\d{4}|PLS-\d{5}') {
|
||||
Write-Output $R.Text
|
||||
Opreste ($Context + ' - sqlplus a raportat eroare (cod ' + $R.Cod + ').')
|
||||
}
|
||||
}
|
||||
|
||||
function ConvertTo-Hex {
|
||||
param([byte[]]$Octeti)
|
||||
if ($Octeti.Length -eq 0) { return '' }
|
||||
[System.BitConverter]::ToString($Octeti).Replace('-', '')
|
||||
}
|
||||
|
||||
function ConvertFrom-Hex {
|
||||
param([string]$Hex)
|
||||
$n = [int]($Hex.Length / 2)
|
||||
$b = New-Object byte[] $n
|
||||
for ($i = 0; $i -lt $n; $i++) { $b[$i] = [Convert]::ToByte($Hex.Substring($i * 2, 2), 16) }
|
||||
,$b
|
||||
}
|
||||
|
||||
function Citeste-Ini {
|
||||
param([string]$Cale)
|
||||
$ini = @{}
|
||||
$sectiune = ''
|
||||
foreach ($linie in [System.IO.File]::ReadAllLines($Cale, [System.Text.Encoding]::GetEncoding(1252))) {
|
||||
$linie = $linie.Trim()
|
||||
if (-not $linie -or $linie.StartsWith(';') -or $linie.StartsWith('#')) { continue }
|
||||
if ($linie -match '^\[(.+)\]$') {
|
||||
$sectiune = $Matches[1].ToLower()
|
||||
if (-not $ini.ContainsKey($sectiune)) { $ini[$sectiune] = @{} }
|
||||
continue
|
||||
}
|
||||
$p = $linie.IndexOf('=')
|
||||
if ($p -lt 1 -or -not $sectiune) { continue }
|
||||
$ini[$sectiune][$linie.Substring(0, $p).Trim().ToLower()] = $linie.Substring($p + 1).Trim()
|
||||
}
|
||||
$ini
|
||||
}
|
||||
|
||||
function Ia-Cheie {
|
||||
param($Ini, [string]$Sectiune, [string]$Cheie)
|
||||
$s = $Sectiune.ToLower()
|
||||
$c = $Cheie.ToLower()
|
||||
if ($Ini.ContainsKey($s) -and $Ini[$s].ContainsKey($c)) { return $Ini[$s][$c] }
|
||||
''
|
||||
}
|
||||
|
||||
function Rezolva-Alias {
|
||||
# numele din host_database e un DSN ODBC; aliasul TNS e in cheia ServerName a DSN-ului
|
||||
param([string]$Dsn)
|
||||
foreach ($radacina in @('HKCU:\SOFTWARE\ODBC\ODBC.INI', 'HKLM:\SOFTWARE\ODBC\ODBC.INI', 'HKLM:\SOFTWARE\WOW6432Node\ODBC\ODBC.INI')) {
|
||||
$cale = Join-Path $radacina $Dsn
|
||||
if (Test-Path $cale) {
|
||||
$v = (Get-ItemProperty -Path $cale -Name 'ServerName' -ErrorAction SilentlyContinue).ServerName
|
||||
if ($v) { return $v }
|
||||
}
|
||||
}
|
||||
# nu e DSN ODBC - il tratam ca alias TNS direct
|
||||
$Dsn
|
||||
}
|
||||
|
||||
function Compara-Octeti {
|
||||
param([byte[]]$A, [byte[]]$B)
|
||||
if ($null -eq $A -or $null -eq $B) { return $false }
|
||||
if ($A.Length -ne $B.Length) { return $false }
|
||||
for ($i = 0; $i -lt $A.Length; $i++) { if ($A[$i] -ne $B[$i]) { return $false } }
|
||||
$true
|
||||
}
|
||||
|
||||
function Split-Hex {
|
||||
# taie un sir hexazecimal in bucati de $BUCATA octeti
|
||||
param([string]$Hex)
|
||||
$l = New-Object System.Collections.ArrayList
|
||||
$pas = $BUCATA * 2
|
||||
for ($i = 0; $i -lt $Hex.Length; $i += $pas) {
|
||||
[void]$l.Add($Hex.Substring($i, [Math]::Min($pas, $Hex.Length - $i)))
|
||||
}
|
||||
,$l
|
||||
}
|
||||
|
||||
function Parseaza-NumeScript {
|
||||
# <prefix>_YYYY_MM_DD_NN_<tip>.sql -> obiect cu elementele componente (ca parsescriptname din VFP)
|
||||
param([string]$Cale)
|
||||
$stem = [System.IO.Path]::GetFileNameWithoutExtension($Cale)
|
||||
if ($stem -notmatch '^([A-Za-z]+)_(\d{4})_(\d{2})_(\d{2})_(\d+)(?:_(.+))?$') { return $null }
|
||||
$an = [int]$Matches[2]; $luna = [int]$Matches[3]; $zi = [int]$Matches[4]
|
||||
try { $data = Get-Date -Year $an -Month $luna -Day $zi -Hour 0 -Minute 0 -Second 0 } catch { return $null }
|
||||
$tip = ''
|
||||
if ($Matches[6]) { $tip = $Matches[6].ToUpper() }
|
||||
[PSCustomObject]@{
|
||||
Cale = $Cale
|
||||
NumeScript = ($stem.ToUpper() + '.SQL')
|
||||
Stem = $stem.ToUpper()
|
||||
Prefix = $Matches[1].ToUpper()
|
||||
Data = $data
|
||||
DataYmd = $data.ToString('yyyyMMdd')
|
||||
Secventa = [int]$Matches[5]
|
||||
Tip = $tip
|
||||
}
|
||||
}
|
||||
|
||||
function Citeste-MetadateLuna {
|
||||
# metadatele scripturilor intregi (script_order = 0) din luna, in ordinea din arhiva
|
||||
param([datetime]$Inceput, [datetime]$Sfarsit)
|
||||
$sql = @"
|
||||
set pagesize 0 linesize 600 trimspool on heading off
|
||||
select 'M|' || id || '|' || script_name || '|' || script_type || '|' || to_char(script_date,'yyyymmdd') ||
|
||||
'|' || to_char(script_seq) || '|' || to_char(script_order) || '|' || nvl(script_appver,'') ||
|
||||
'|' || nvl(length(script_content),0)
|
||||
from upd_database
|
||||
where script_order = 0
|
||||
and script_date between to_date('$($Inceput.ToString('yyyyMMdd'))','yyyymmdd') and to_date('$($Sfarsit.ToString('yyyyMMdd'))','yyyymmdd')
|
||||
order by script_name, id;
|
||||
exit
|
||||
"@
|
||||
$r = Invoke-SqlPlus -Sql $sql -Nume 'meta'
|
||||
Test-Rezultat -R $r -Context 'citire metadate din UPD_DATABASE'
|
||||
$l = New-Object System.Collections.ArrayList
|
||||
foreach ($linie in ($r.Text -split "`r?`n")) {
|
||||
$linie = $linie.Trim()
|
||||
if (-not $linie.StartsWith('M|')) { continue }
|
||||
$c = $linie.Substring(2) -split '\|'
|
||||
if ($c.Count -lt 8) { continue }
|
||||
[void]$l.Add([PSCustomObject]@{
|
||||
Id = [int]$c[0]
|
||||
NumeScript = $c[1].Trim()
|
||||
Stem = [System.IO.Path]::GetFileNameWithoutExtension($c[1].Trim())
|
||||
Tip = $c[2].Trim()
|
||||
DataYmd = $c[3].Trim()
|
||||
Secventa = [int]$c[4]
|
||||
Ordine = [int]$c[5]
|
||||
AppVer = $c[6].Trim()
|
||||
Lungime = [int]$c[7]
|
||||
})
|
||||
}
|
||||
,$l
|
||||
}
|
||||
|
||||
function Citeste-Continut {
|
||||
# citeste inapoi CLOB-urile ca octeti CP1252 (hexazecimal), pentru toate id-urile date
|
||||
param($Metadate)
|
||||
$rezultat = @{}
|
||||
if ($Metadate.Count -eq 0) { return $rezultat }
|
||||
$maxBucati = 1
|
||||
foreach ($m in $Metadate) {
|
||||
$rezultat[$m.Id] = New-Object System.Text.StringBuilder
|
||||
$b = [Math]::Ceiling($m.Lungime / $BUCATA)
|
||||
if ($b -gt $maxBucati) { $maxBucati = [int]$b }
|
||||
}
|
||||
$toateId = @($Metadate | ForEach-Object { $_.Id })
|
||||
$grupuri = New-Object System.Collections.ArrayList
|
||||
for ($i = 0; $i -lt $toateId.Count; $i += 500) {
|
||||
[void]$grupuri.Add('c.id in (' + (($toateId[$i..([Math]::Min($i + 499, $toateId.Count - 1))]) -join ',') + ')')
|
||||
}
|
||||
$ids = $grupuri -join ' or '
|
||||
$sql = @"
|
||||
set pagesize 0 linesize 32767 long 2000000000 longchunksize 32767 trimspool on heading off arraysize 100
|
||||
select '#' || c.id || '#' || lpad(to_char(l.n),7,'0') || '#' ||
|
||||
rawtohex(utl_i18n.string_to_raw(dbms_lob.substr(c.script_content, $BUCATA, (l.n-1)*$BUCATA+1), 'WE8MSWIN1252'))
|
||||
from upd_database c,
|
||||
(select level n from dual connect by level <= $maxBucati) l
|
||||
where ($ids)
|
||||
and (l.n-1)*$BUCATA < nvl(length(c.script_content),0)
|
||||
order by c.id, l.n;
|
||||
exit
|
||||
"@
|
||||
$r = Invoke-SqlPlus -Sql $sql -Nume 'citire'
|
||||
Test-Rezultat -R $r -Context 'citire continut scripturi din UPD_DATABASE'
|
||||
foreach ($linie in ($r.Text -split "`r?`n")) {
|
||||
$linie = $linie.Trim()
|
||||
if (-not $linie.StartsWith('#')) { continue }
|
||||
$c = $linie.Substring(1) -split '#', 3
|
||||
if ($c.Count -lt 3) { continue }
|
||||
$id = [int]$c[0]
|
||||
if ($rezultat.ContainsKey($id)) { [void]$rezultat[$id].Append($c[2]) }
|
||||
}
|
||||
$final = @{}
|
||||
foreach ($k in $rezultat.Keys) { $final[$k] = ConvertFrom-Hex $rezultat[$k].ToString() }
|
||||
$final
|
||||
}
|
||||
|
||||
function Importa-Script {
|
||||
# insert sau update pe script_name existent; continutul se trimite hexazecimal, bucata cu bucata
|
||||
param($Info, [byte[]]$Octeti)
|
||||
$hex = ConvertTo-Hex $Octeti
|
||||
$bucati = Split-Hex $hex
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
[void]$sb.AppendLine('set serveroutput on size 1000000')
|
||||
[void]$sb.AppendLine('variable b_id number')
|
||||
[void]$sb.AppendLine('declare')
|
||||
[void]$sb.AppendLine(' l_id number;')
|
||||
[void]$sb.AppendLine('begin')
|
||||
[void]$sb.AppendLine(" select max(id) into l_id from upd_database where script_name = '$($Info.NumeScript)';")
|
||||
[void]$sb.AppendLine(' if l_id is null then')
|
||||
[void]$sb.AppendLine(' insert into upd_database')
|
||||
[void]$sb.AppendLine(' (script_name, script_type, script_date, script_seq, script_content, script_order, script_appver)')
|
||||
[void]$sb.AppendLine(" values ('$($Info.NumeScript)', '$($Info.Tip)', to_date('$($Info.DataYmd)','yyyymmdd'), $($Info.Secventa), empty_clob(), 0, null)")
|
||||
[void]$sb.AppendLine(' returning id into l_id;')
|
||||
[void]$sb.AppendLine(' else')
|
||||
[void]$sb.AppendLine(' update upd_database')
|
||||
[void]$sb.AppendLine(" set script_type = '$($Info.Tip)',")
|
||||
[void]$sb.AppendLine(" script_date = to_date('$($Info.DataYmd)','yyyymmdd'),")
|
||||
[void]$sb.AppendLine(" script_seq = $($Info.Secventa),")
|
||||
[void]$sb.AppendLine(' script_content = empty_clob(),')
|
||||
[void]$sb.AppendLine(' script_order = 0,')
|
||||
[void]$sb.AppendLine(' script_appver = null')
|
||||
[void]$sb.AppendLine(' where id = l_id;')
|
||||
[void]$sb.AppendLine(' end if;')
|
||||
[void]$sb.AppendLine(' :b_id := l_id;')
|
||||
[void]$sb.AppendLine(' commit;')
|
||||
[void]$sb.AppendLine(" dbms_output.put_line('IDSCRIPT=' || l_id);")
|
||||
[void]$sb.AppendLine('end;')
|
||||
[void]$sb.AppendLine('/')
|
||||
|
||||
for ($i = 0; $i -lt $bucati.Count; $i += $BUCATI_PER_BLOC) {
|
||||
[void]$sb.AppendLine('declare s varchar2(32767); l clob;')
|
||||
[void]$sb.AppendLine('begin')
|
||||
[void]$sb.AppendLine(' select script_content into l from upd_database where id = :b_id for update;')
|
||||
for ($j = $i; $j -lt [Math]::Min($i + $BUCATI_PER_BLOC, $bucati.Count); $j++) {
|
||||
[void]$sb.AppendLine(" s := utl_i18n.raw_to_char(hextoraw('$($bucati[$j])'),'WE8MSWIN1252'); dbms_lob.writeappend(l, length(s), s);")
|
||||
}
|
||||
[void]$sb.AppendLine(' commit;')
|
||||
[void]$sb.AppendLine('end;')
|
||||
[void]$sb.AppendLine('/')
|
||||
}
|
||||
[void]$sb.AppendLine('exit')
|
||||
|
||||
$r = Invoke-SqlPlus -Sql $sb.ToString() -Nume ('imp_' + $Info.Stem)
|
||||
Test-Rezultat -R $r -Context ('import ' + $Info.NumeScript)
|
||||
if ($r.Text -notmatch 'IDSCRIPT=(\d+)') { Opreste ('import ' + $Info.NumeScript + ' - nu am primit id-ul randului.') }
|
||||
[int]$Matches[1]
|
||||
}
|
||||
|
||||
function Scrie-XmlArhiva {
|
||||
# acelasi format ca CURSORTOXML din genereazadatabasexml2: Windows-1252, CRLF, tab-uri,
|
||||
# script_appver doar cand e completat, script_content gol (continutul e in fisierul separat)
|
||||
param($Metadate, [string]$Cale)
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
[void]$sb.Append("<?xml version = `"1.0`" encoding=`"Windows-1252`" standalone=`"yes`"?>`r`n")
|
||||
[void]$sb.Append("<VFPData>`r`n")
|
||||
foreach ($m in $Metadate) {
|
||||
[void]$sb.Append("`t<crsxml>`r`n")
|
||||
[void]$sb.Append("`t`t<id>$($m.Id)</id>`r`n")
|
||||
[void]$sb.Append("`t`t<script_name>$([System.Security.SecurityElement]::Escape($m.NumeScript))</script_name>`r`n")
|
||||
[void]$sb.Append("`t`t<script_type>$([System.Security.SecurityElement]::Escape($m.Tip))</script_type>`r`n")
|
||||
[void]$sb.Append("`t`t<script_date>$($m.DataYmd)</script_date>`r`n")
|
||||
[void]$sb.Append("`t`t<script_seq>$($m.Secventa)</script_seq>`r`n")
|
||||
[void]$sb.Append("`t`t<script_order>$($m.Ordine)</script_order>`r`n")
|
||||
if ($m.AppVer) {
|
||||
[void]$sb.Append("`t`t<script_appver>$([System.Security.SecurityElement]::Escape($m.AppVer))</script_appver>`r`n")
|
||||
}
|
||||
[void]$sb.Append("`t`t<script_extra_file>$($m.Stem).sql</script_extra_file>`r`n")
|
||||
[void]$sb.Append("`t`t<script_content></script_content>`r`n")
|
||||
[void]$sb.Append("`t</crsxml>`r`n")
|
||||
}
|
||||
[void]$sb.Append("</VFPData>`r`n")
|
||||
[System.IO.File]::WriteAllText($Cale, $sb.ToString(), [System.Text.Encoding]::GetEncoding(1252))
|
||||
}
|
||||
|
||||
function Scrie-Arhiva {
|
||||
# xml-ul primul, apoi scripturile in ordinea din xml (ca ZipOpen/ZipFile din VFP)
|
||||
param([string]$CaleZip, [string]$CaleXml, $Fisiere)
|
||||
if (Test-Path $CaleZip) { Remove-Item -LiteralPath $CaleZip -Force }
|
||||
$z = [System.IO.Compression.ZipFile]::Open($CaleZip, 'Create')
|
||||
try {
|
||||
[void][System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($z, $CaleXml, [System.IO.Path]::GetFileName($CaleXml), 'Optimal')
|
||||
foreach ($f in $Fisiere) {
|
||||
[void][System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($z, $f, [System.IO.Path]::GetFileName($f), 'Optimal')
|
||||
}
|
||||
} finally {
|
||||
$z.Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
function Scrie-IndexArhive {
|
||||
# roa_database.xml / roa_databasen.xml - lista arhivelor existente, sortata dupa nume de fisier
|
||||
param([string]$Prefix, [string]$Cale)
|
||||
$arhive = @(Get-ChildItem -LiteralPath $ZipPath -Filter ($Prefix + '_*.zip') -File |
|
||||
Where-Object { $_.Name -like ($Prefix + '_*.zip') } | Sort-Object Name)
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
[void]$sb.Append("<?xml version = `"1.0`" encoding=`"Windows-1252`" standalone=`"yes`"?>`r`n")
|
||||
[void]$sb.Append("<VFPData>`r`n")
|
||||
foreach ($a in $arhive) {
|
||||
$parti = [System.IO.Path]::GetFileNameWithoutExtension($a.Name) -split '_'
|
||||
if ($parti.Count -lt 3) { continue }
|
||||
[void]$sb.Append("`t<crsxml>`r`n")
|
||||
[void]$sb.Append("`t`t<url>|BASEPATH|/$($a.Name)</url>`r`n")
|
||||
[void]$sb.Append("`t`t<data1>$($parti[1])</data1>`r`n")
|
||||
[void]$sb.Append("`t`t<data2>$($parti[2])</data2>`r`n")
|
||||
[void]$sb.Append("`t</crsxml>`r`n")
|
||||
}
|
||||
[void]$sb.Append("</VFPData>`r`n")
|
||||
[System.IO.File]::WriteAllText($Cale, $sb.ToString(), [System.Text.Encoding]::GetEncoding(1252))
|
||||
}
|
||||
|
||||
function Verifica-ArhivaPrinOracle {
|
||||
# citeste arhiva inapoi cu cititorul clientului (pack_utils.decodebase64 + zip_util_pkg.get_file)
|
||||
# si compara lungimea + MD5 al fiecarui fisier extras cu cel de pe disc
|
||||
param([string]$CaleZip, $FisiereAsteptate)
|
||||
$octeti = [System.IO.File]::ReadAllBytes($CaleZip)
|
||||
$b64 = [Convert]::ToBase64String($octeti)
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
[void]$sb.AppendLine('set serveroutput on size unlimited')
|
||||
[void]$sb.AppendLine('set pagesize 0 linesize 400 trimspool on heading off')
|
||||
[void]$sb.AppendLine('variable b_z clob')
|
||||
[void]$sb.AppendLine('begin dbms_lob.createtemporary(:b_z, true); end;')
|
||||
[void]$sb.AppendLine('/')
|
||||
# bucati multiplu de 4, ca sirul base64 sa ramana valid oriunde s-ar taia
|
||||
$pas = 1920
|
||||
for ($i = 0; $i -lt $b64.Length; $i += $pas * $BUCATI_PER_BLOC) {
|
||||
[void]$sb.AppendLine('declare s varchar2(32767);')
|
||||
[void]$sb.AppendLine('begin')
|
||||
for ($j = $i; $j -lt [Math]::Min($i + $pas * $BUCATI_PER_BLOC, $b64.Length); $j += $pas) {
|
||||
$bucata = $b64.Substring($j, [Math]::Min($pas, $b64.Length - $j))
|
||||
[void]$sb.AppendLine(" s := '$bucata'; dbms_lob.writeappend(:b_z, length(s), s);")
|
||||
}
|
||||
[void]$sb.AppendLine('end;')
|
||||
[void]$sb.AppendLine('/')
|
||||
}
|
||||
[void]$sb.AppendLine('declare')
|
||||
[void]$sb.AppendLine(' l_zip blob; l_f blob;')
|
||||
[void]$sb.AppendLine('begin')
|
||||
[void]$sb.AppendLine(' l_zip := pack_utils.decodebase64(:b_z);')
|
||||
[void]$sb.AppendLine(" dbms_output.put_line('ZIP|' || dbms_lob.getlength(l_zip));")
|
||||
foreach ($f in $FisiereAsteptate) {
|
||||
[void]$sb.AppendLine(" l_f := zip_util_pkg.get_file(l_zip, '$f');")
|
||||
[void]$sb.AppendLine(" if l_f is null then dbms_output.put_line('LIPSA|$f');")
|
||||
[void]$sb.AppendLine(" else dbms_output.put_line('FIS|$f|' || dbms_lob.getlength(l_f) || '|' || rawtohex(dbms_crypto.hash(l_f, 2))); end if;")
|
||||
}
|
||||
[void]$sb.AppendLine('end;')
|
||||
[void]$sb.AppendLine('/')
|
||||
[void]$sb.AppendLine('exit')
|
||||
|
||||
$r = Invoke-SqlPlus -Sql $sb.ToString() -Nume 'verifzip'
|
||||
Test-Rezultat -R $r -Context ('verificare arhiva ' + [System.IO.Path]::GetFileName($CaleZip))
|
||||
$citite = @{}
|
||||
foreach ($linie in ($r.Text -split "`r?`n")) {
|
||||
$linie = $linie.Trim()
|
||||
if ($linie -match '^FIS\|([^|]+)\|(\d+)\|([0-9A-F]+)$') {
|
||||
$citite[$Matches[1]] = [PSCustomObject]@{ Lungime = [int]$Matches[2]; Md5 = $Matches[3] }
|
||||
} elseif ($linie -match '^LIPSA\|(.+)$') {
|
||||
Opreste ('verificare arhiva - zip_util_pkg nu gaseste ' + $Matches[1] + ' in ' + $CaleZip)
|
||||
}
|
||||
}
|
||||
$md5 = [System.Security.Cryptography.MD5]::Create()
|
||||
$erori = 0
|
||||
foreach ($f in $FisiereAsteptate) {
|
||||
if (-not $citite.ContainsKey($f)) { Write-Output (' LIPSA ' + $f); $erori++; continue }
|
||||
$local = Join-Path $TempDir $f
|
||||
$b = [System.IO.File]::ReadAllBytes($local)
|
||||
$h = (ConvertTo-Hex $md5.ComputeHash($b))
|
||||
if ($citite[$f].Lungime -eq $b.Length -and $citite[$f].Md5 -eq $h) {
|
||||
Write-Output (' ok ' + $f + ' (' + $b.Length + ' octeti)')
|
||||
} else {
|
||||
Write-Output (' DIFERIT ' + $f + ' - disc ' + $b.Length + '/' + $h + ', extras ' + $citite[$f].Lungime + '/' + $citite[$f].Md5)
|
||||
$erori++
|
||||
}
|
||||
}
|
||||
$md5.Dispose()
|
||||
if ($erori -gt 0) { Opreste ('verificare arhiva - ' + $erori + ' fisiere nu se citesc corect prin zip_util_pkg.') }
|
||||
}
|
||||
|
||||
# ---------- pregatire ----------
|
||||
$TempDir = Join-Path $env:TEMP ('publicare_scripturi_' + [guid]::NewGuid().ToString('N'))
|
||||
New-Item -ItemType Directory -Force -Path $TempDir | Out-Null
|
||||
|
||||
if (-not (Test-Path -LiteralPath $Settings)) { Opreste ('nu gasesc settings.ini la ' + $Settings + ' - da caile cu -DirScripturi/-ZipPath/-Alias/-User/-Password sau alt -Settings.') }
|
||||
$ini = Citeste-Ini $Settings
|
||||
|
||||
# parametrii dati explicit bat ini-ul
|
||||
if (-not $PSBoundParameters.ContainsKey('User')) { $User = Ia-Cheie $ini 'connection' 'username_database' }
|
||||
if (-not $PSBoundParameters.ContainsKey('Password')) { $Password = Ia-Cheie $ini 'connection' 'password_database' }
|
||||
if (-not $PSBoundParameters.ContainsKey('Alias')) {
|
||||
$dsn = Ia-Cheie $ini 'connection' 'host_database'
|
||||
if ($dsn) { $Alias = Rezolva-Alias $dsn }
|
||||
}
|
||||
if (-not $PSBoundParameters.ContainsKey('DirScripturi')) {
|
||||
$f = Ia-Cheie $ini 'folder' 'script_folder'
|
||||
if ($f) { $DirScripturi = ($f.TrimEnd('\') -replace '\\SCRIPTURI$', '\SCRIPTURI_CLAR') }
|
||||
}
|
||||
if (-not $PSBoundParameters.ContainsKey('ZipPath')) {
|
||||
$f = Ia-Cheie $ini 'folder' 'roa_output'
|
||||
if ($f) { $ZipPath = (Join-Path $f '_UPDATE') }
|
||||
}
|
||||
if (-not $PSBoundParameters.ContainsKey('SqlPlus')) { $SqlPlus = Ia-Cheie $ini 'folder' 'sqlplus_exe' }
|
||||
foreach ($p in @(@('User', $User), @('Password', $Password), @('Alias', $Alias), @('DirScripturi', $DirScripturi), @('ZipPath', $ZipPath), @('SqlPlus', $SqlPlus))) {
|
||||
if (-not $p[1]) { Opreste ('lipseste ' + $p[0] + ' - nu e in ' + $Settings + ' si nu a fost dat ca parametru.') }
|
||||
}
|
||||
# prefixele valide (o schema tinta per prefix), pentru validarea numelor de scripturi
|
||||
$prefixe = @()
|
||||
if ($ini.ContainsKey('script')) { $prefixe = @($ini['script'].Values | ForEach-Object { $_.TrimEnd('_').ToUpper() }) }
|
||||
|
||||
if (-not (Test-Path $SqlPlus)) { Opreste ('nu gasesc sqlplus la ' + $SqlPlus) }
|
||||
$env:TNS_ADMIN = Split-Path $SqlPlus -Parent
|
||||
$ConnStr = $User + '/' + $Password + '@' + $Alias
|
||||
|
||||
if ($DoarImport -and $DoarArhiva) { Opreste '-DoarImport si -DoarArhiva se exclud reciproc.' }
|
||||
|
||||
# ---------- 1. ce se publica ----------
|
||||
Scrie-Titlu '1. SCRIPTURI DE PUBLICAT'
|
||||
$candidati = New-Object System.Collections.ArrayList
|
||||
if ($Fisier) {
|
||||
foreach ($f in $Fisier) {
|
||||
$cale = $f
|
||||
if (-not [System.IO.Path]::IsPathRooted($cale)) {
|
||||
$cale = (Resolve-Path -LiteralPath $f -ErrorAction SilentlyContinue)
|
||||
if (-not $cale) { Opreste ('nu gasesc fisierul ' + $f) }
|
||||
$cale = $cale.Path
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $cale)) { Opreste ('nu gasesc fisierul ' + $cale) }
|
||||
$info = Parseaza-NumeScript $cale
|
||||
if (-not $info) { Opreste ('nume de script neconform (<prefix>_YYYY_MM_DD_NN_<tip>.sql): ' + $cale) }
|
||||
[void]$candidati.Add($info)
|
||||
}
|
||||
$luni = @($candidati | ForEach-Object { $_.Data.ToString('yyyy-MM') } | Sort-Object -Unique)
|
||||
if ($luni.Count -gt 1) { Opreste ('scripturile date sunt din luni diferite (' + ($luni -join ', ') + ') - ruleaza cate o luna.') }
|
||||
if (-not $Luna) { $Luna = $luni[0] }
|
||||
} else {
|
||||
if (-not $Luna) { $Luna = (Get-Date).ToString('yyyy-MM') }
|
||||
}
|
||||
|
||||
if ($Luna -notmatch '^(\d{4})-(\d{2})$') { Opreste ('-Luna trebuie in formatul YYYY-MM (primit: ' + $Luna + ')') }
|
||||
$anLuna = [int]$Matches[1]
|
||||
$lunaLuna = [int]$Matches[2]
|
||||
$dataInceput = Get-Date -Year $anLuna -Month $lunaLuna -Day 1 -Hour 0 -Minute 0 -Second 0
|
||||
$dataSfarsit = $dataInceput.AddMonths(1).AddDays(-1)
|
||||
$etichetaLuna = $dataInceput.ToString('yyyyMMdd') + '_' + $dataSfarsit.ToString('yyyyMMdd')
|
||||
|
||||
$dirLuna = Join-Path (Join-Path $DirScripturi $dataInceput.ToString('yyyy')) $dataInceput.ToString('MM')
|
||||
if (-not $Fisier -and -not $DoarArhiva) {
|
||||
if (-not (Test-Path -LiteralPath $dirLuna)) { Opreste ('nu gasesc directorul lunii: ' + $dirLuna) }
|
||||
foreach ($f in (Get-ChildItem -LiteralPath $dirLuna -Filter '*.sql' -File | Sort-Object Name)) {
|
||||
$info = Parseaza-NumeScript $f.FullName
|
||||
if (-not $info) { Write-Output (' [sarit] nume neconform: ' + $f.Name); continue }
|
||||
[void]$candidati.Add($info)
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output ('Luna: ' + $Luna + ' arhiva: ' + $etichetaLuna)
|
||||
Write-Output ('Configurare: ' + $Settings)
|
||||
Write-Output ('Baza: ' + $User + '@' + $Alias + ' (' + $SqlPlus + ')')
|
||||
Write-Output ('Scripturi: ' + $dirLuna)
|
||||
Write-Output ('Arhive: ' + $ZipPath)
|
||||
|
||||
foreach ($c in $candidati) {
|
||||
if ($prefixe.Count -gt 0 -and $prefixe -notcontains $c.Prefix) {
|
||||
Write-Output (' [atentie] prefix necunoscut "' + $c.Prefix + '" in ' + [System.IO.Path]::GetFileName($c.Cale) + ' (in ini: ' + ($prefixe -join ', ') + ')')
|
||||
}
|
||||
$octeti = [System.IO.File]::ReadAllBytes($c.Cale)
|
||||
if ($octeti.Length -eq 0) { Opreste ('fisier gol: ' + $c.Cale) }
|
||||
$text = [System.Text.Encoding]::GetEncoding(1252).GetString($octeti)
|
||||
if ($text -match "(?<!`r)`n") { Opreste ('sfarsituri de linie LF in ' + $c.Cale + ' - scripturile trebuie salvate cu CRLF (parsarea pe client se face pe CHR(13)+CHR(10)).') }
|
||||
Add-Member -InputObject $c -NotePropertyName Octeti -NotePropertyValue $octeti
|
||||
}
|
||||
|
||||
# ---------- 2. starea din baza ----------
|
||||
Scrie-Titlu '2. STAREA DIN UPD_DATABASE'
|
||||
$metadate = Citeste-MetadateLuna -Inceput $dataInceput -Sfarsit $dataSfarsit
|
||||
Write-Output ('In baza, pentru luna ' + $Luna + ': ' + $metadate.Count + ' scripturi.')
|
||||
$dupaNume = @{}
|
||||
foreach ($m in $metadate) { $dupaNume[$m.NumeScript] = $m }
|
||||
|
||||
$deImportat = New-Object System.Collections.ArrayList
|
||||
if (-not $DoarArhiva) {
|
||||
$existente = @($candidati | Where-Object { $dupaNume.ContainsKey($_.NumeScript) })
|
||||
$continuturi = @{}
|
||||
if ($existente.Count -gt 0) {
|
||||
$continuturi = Citeste-Continut -Metadate @($existente | ForEach-Object { $dupaNume[$_.NumeScript] })
|
||||
}
|
||||
foreach ($c in $candidati) {
|
||||
if (-not $dupaNume.ContainsKey($c.NumeScript)) {
|
||||
Write-Output (' NOU ' + $c.NumeScript + ' (' + $c.Octeti.Length + ' octeti)')
|
||||
[void]$deImportat.Add($c)
|
||||
continue
|
||||
}
|
||||
$m = $dupaNume[$c.NumeScript]
|
||||
$inBaza = $continuturi[$m.Id]
|
||||
$identic = Compara-Octeti -A $inBaza -B $c.Octeti
|
||||
if ($identic -and -not $Toate) {
|
||||
Write-Output (' publicat ' + $c.NumeScript + ' (id ' + $m.Id + ', identic)')
|
||||
} elseif ($identic) {
|
||||
Write-Output (' REPUBLIC ' + $c.NumeScript + ' (id ' + $m.Id + ', identic, fortat cu -Toate)')
|
||||
[void]$deImportat.Add($c)
|
||||
} else {
|
||||
Write-Output (' MODIFICAT ' + $c.NumeScript + ' (id ' + $m.Id + ', in baza ' + $(if ($inBaza) { $inBaza.Length } else { 0 }) + ' octeti, pe disc ' + $c.Octeti.Length + ')')
|
||||
[void]$deImportat.Add($c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ---------- 3. import ----------
|
||||
if (-not $DoarArhiva) {
|
||||
Scrie-Titlu '3. IMPORT IN UPD_DATABASE'
|
||||
if ($deImportat.Count -eq 0) {
|
||||
Write-Output 'Nimic de importat - toate scripturile din luna sunt deja publicate cu acelasi continut.'
|
||||
} elseif ($DryRun) {
|
||||
Write-Output ('DryRun - as importa ' + $deImportat.Count + ' scripturi (vezi lista de mai sus).')
|
||||
} else {
|
||||
foreach ($c in $deImportat) {
|
||||
$id = Importa-Script -Info $c -Octeti $c.Octeti
|
||||
Write-Output (' importat ' + $c.NumeScript + ' -> id ' + $id)
|
||||
}
|
||||
$metadate = Citeste-MetadateLuna -Inceput $dataInceput -Sfarsit $dataSfarsit
|
||||
$dupaNume = @{}
|
||||
foreach ($m in $metadate) { $dupaNume[$m.NumeScript] = $m }
|
||||
$verif = Citeste-Continut -Metadate @($deImportat | ForEach-Object { $dupaNume[$_.NumeScript] })
|
||||
$erori = 0
|
||||
foreach ($c in $deImportat) {
|
||||
$m = $dupaNume[$c.NumeScript]
|
||||
$inBaza = $verif[$m.Id]
|
||||
if (Compara-Octeti -A $inBaza -B $c.Octeti) {
|
||||
Write-Output (' verificat ' + $c.NumeScript + ' (' + $c.Octeti.Length + ' octeti, identic cu fisierul)')
|
||||
} else {
|
||||
Write-Output (' DIFERIT ' + $c.NumeScript + ' - continutul din baza nu coincide cu fisierul!')
|
||||
$erori++
|
||||
}
|
||||
}
|
||||
if ($erori -gt 0) { Opreste ($erori + ' scripturi nu s-au scris corect in baza - nu generez arhiva.') }
|
||||
}
|
||||
}
|
||||
|
||||
if ($DoarImport) {
|
||||
Scrie-Titlu 'GATA (doar import)'
|
||||
Write-Output 'Arhiva NU a fost regenerata - clientii primesc scripturile abia dupa pasul de arhiva.'
|
||||
Curata-Temp
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ---------- 4. arhiva lunara ----------
|
||||
Scrie-Titlu '4. ARHIVA LUNARA'
|
||||
if (-not (Test-Path -LiteralPath $ZipPath)) { Opreste ('nu gasesc directorul arhivelor: ' + $ZipPath) }
|
||||
if ($DryRun) {
|
||||
Write-Output ('DryRun - as regenera database_' + $etichetaLuna + '.zip si databasen_' + $etichetaLuna + '.zip din ' + $metadate.Count + ' scripturi.')
|
||||
Curata-Temp
|
||||
exit 0
|
||||
}
|
||||
|
||||
$metadate = Citeste-MetadateLuna -Inceput $dataInceput -Sfarsit $dataSfarsit
|
||||
if ($metadate.Count -eq 0) { Opreste ('nu exista scripturi in UPD_DATABASE pentru luna ' + $Luna + ' - nu am ce arhiva.') }
|
||||
|
||||
$continuturi = Citeste-Continut -Metadate $metadate
|
||||
$fisiereSql = New-Object System.Collections.ArrayList
|
||||
foreach ($m in $metadate) {
|
||||
$b = $continuturi[$m.Id]
|
||||
if (-not $b -or $b.Length -ne $m.Lungime) {
|
||||
Opreste ('citire incompleta pentru ' + $m.NumeScript + ' (asteptat ' + $m.Lungime + ' octeti, citit ' + $(if ($b) { $b.Length } else { 0 }) + ').')
|
||||
}
|
||||
$numeFis = $m.Stem + '.sql'
|
||||
[System.IO.File]::WriteAllBytes((Join-Path $TempDir $numeFis), $b)
|
||||
[void]$fisiereSql.Add($numeFis)
|
||||
}
|
||||
Write-Output ('Extrase din baza: ' + $fisiereSql.Count + ' scripturi.')
|
||||
|
||||
$numeFisiere = @($fisiereSql)
|
||||
$rezultat = @()
|
||||
foreach ($prefix in @('database', 'databasen')) {
|
||||
$numeXml = $prefix + '_' + $etichetaLuna + '.xml'
|
||||
$caleXml = Join-Path $TempDir $numeXml
|
||||
Scrie-XmlArhiva -Metadate $metadate -Cale $caleXml
|
||||
$caleZip = Join-Path $TempDir ($prefix + '_' + $etichetaLuna + '.zip')
|
||||
Scrie-Arhiva -CaleZip $caleZip -CaleXml $caleXml -Fisiere @($numeFisiere | ForEach-Object { Join-Path $TempDir $_ })
|
||||
Write-Output ('Generat ' + [System.IO.Path]::GetFileName($caleZip) + ' (' + (Get-Item -LiteralPath $caleZip).Length + ' octeti)')
|
||||
$rezultat += [PSCustomObject]@{ Zip = $caleZip; Xml = $numeXml }
|
||||
}
|
||||
|
||||
# ---------- 5. verificare cu cititorul clientului ----------
|
||||
if (-not $FaraVerificareZip) {
|
||||
Scrie-Titlu '5. VERIFICARE ARHIVA PRIN ZIP_UTIL_PKG'
|
||||
Verifica-ArhivaPrinOracle -CaleZip $rezultat[0].Zip -FisiereAsteptate (@($rezultat[0].Xml) + $numeFisiere)
|
||||
} else {
|
||||
Scrie-Titlu '5. VERIFICARE ARHIVA PRIN ZIP_UTIL_PKG'
|
||||
Write-Output 'Sarit (-FaraVerificareZip).'
|
||||
}
|
||||
|
||||
# ---------- 6. publicare in _UPDATE ----------
|
||||
Scrie-Titlu '6. PUBLICARE IN _UPDATE'
|
||||
if (-not $BackupPath) { $BackupPath = Join-Path $ZipPath ('_backup\' + (Get-Date).ToString('yyyyMMdd_HHmmss')) }
|
||||
New-Item -ItemType Directory -Force -Path $BackupPath | Out-Null
|
||||
foreach ($n in @(($rezultat | ForEach-Object { [System.IO.Path]::GetFileName($_.Zip) }) + 'roa_database.xml' + 'roa_databasen.xml')) {
|
||||
$tinta = Join-Path $ZipPath $n
|
||||
if (Test-Path -LiteralPath $tinta) {
|
||||
Copy-Item -LiteralPath $tinta -Destination (Join-Path $BackupPath $n) -Force
|
||||
Write-Output (' salvat ' + $n + ' -> ' + $BackupPath)
|
||||
}
|
||||
}
|
||||
foreach ($r in $rezultat) {
|
||||
Copy-Item -LiteralPath $r.Zip -Destination (Join-Path $ZipPath ([System.IO.Path]::GetFileName($r.Zip))) -Force
|
||||
Write-Output (' publicat ' + [System.IO.Path]::GetFileName($r.Zip))
|
||||
}
|
||||
Scrie-IndexArhive -Prefix 'database' -Cale (Join-Path $ZipPath 'roa_database.xml')
|
||||
Scrie-IndexArhive -Prefix 'databasen' -Cale (Join-Path $ZipPath 'roa_databasen.xml')
|
||||
Write-Output ' publicat roa_database.xml, roa_databasen.xml'
|
||||
|
||||
Scrie-Titlu 'GATA'
|
||||
Write-Output ('Luna ' + $Luna + ': ' + $metadate.Count + ' scripturi in arhiva, ' + $deImportat.Count + ' importate acum.')
|
||||
Write-Output ('Backup-ul fisierelor inlocuite: ' + $BackupPath)
|
||||
Curata-Temp
|
||||
exit 0
|
||||
Reference in New Issue
Block a user