#6 editare factura emisa: S5 - scrierea sumelor editate in Oracle
La salvarea unei facturi deja emise, modificarile facute liniilor de articole se scriu acum real in VANZARI_DETALII, in aceeasi tranzactie cu restul salvarii, si totalurile documentului se recalculeaza din liniile efectiv salvate. - ofacturare_editare.prg: helper nou ScrieArticoleFacturaEditate. Idiomul e "marcheaza tot sters, invie ce ramane", nu delta, pentru ca actualizeaza_vanzari face UPDATE ... SET STERS = 0 pe tot documentul, fara garda; o scriere delta ar lasa liniile sterse sa reinvie la fiecare salvare. Cursor gol = no-op, ca o eroare la incarcare sa nu goleasca factura. - comun.vc2, ofacturare_comun.vc2: agatarea apelului dupa finalizeaza_modificare_nota si inainte de inchiderea tranzactiei, in ambele puncte de intrare. - omodificari.vc2: coloana Pret achizitie in grid, editabila doar pe liniile noi; liniile de set devin needitabile, cu marcaj; cinci validari la salvare. - teste: cinci suite noi (validari, grid UI, scriere reala, discount/valuta, rollback, al doilea punct de intrare) si asteptari actualizate in test_page3_articole. - docs: oracle_export.md - exportul all_source cere linesize 32767, altfel rupe liniile lungi prin mijlocul identificatorilor; scripturi-migrare-db.md - UpdateVersiune adauga singur extensia .sql. Cere scripturile ff_2026_08_09_01 (PACK_FACTURARE) si ff_2026_08_09_02 (VVANZARI_ARTICOLE). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
This commit is contained in:
@@ -2488,6 +2488,9 @@ DEFINE CLASS afisjurcom AS _frmbase OF "_frm_base.vcx"
|
|||||||
ALLTRIM(Str(lnCod)) + [,] + Alltrim(Str(lnIdFact)) + [,] + Alltrim(Str(lnIdfactd)) + [,?gnIdUtil); end;]
|
ALLTRIM(Str(lnCod)) + [,] + Alltrim(Str(lnIdFact)) + [,] + Alltrim(Str(lnIdfactd)) + [,?gnIdUtil); end;]
|
||||||
lnSucces = Iif(goExecutor.oExecuta(lcSql),1,-1)
|
lnSucces = Iif(goExecutor.oExecuta(lcSql),1,-1)
|
||||||
Endif
|
Endif
|
||||||
|
If lnSucces > 0 And "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) And Used('tvanz') And Reccount('tvanz') = 1
|
||||||
|
lnSucces = Iif(ScrieArticoleFacturaEditate(tvanz.id_vanzare), 1, -1)
|
||||||
|
Endif
|
||||||
*!* IF lnSucces > 0 AND llGestInvantar && nota de inventariere : update dataOra_validat cu dataora modificarii notei contabile
|
*!* IF lnSucces > 0 AND llGestInvantar && nota de inventariere : update dataOra_validat cu dataora modificarii notei contabile
|
||||||
*!* lcSql = [update ] + gcs + [.gest_inventar set dataora_validat = pack_contafin.GET_DATAORA() where dataora_validat = ?pdDataOra and an = ?pnAn and luna = ?pnLuna]
|
*!* lcSql = [update ] + gcs + [.gest_inventar set dataora_validat = pack_contafin.GET_DATAORA() where dataora_validat = ?pdDataOra and an = ?pnAn and luna = ?pnLuna]
|
||||||
*!* lnSucces = goExecutor.oExecute(lcSql)
|
*!* lnSucces = goExecutor.oExecute(lcSql)
|
||||||
|
|||||||
@@ -3825,6 +3825,9 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
|
|||||||
Alltrim(Str(lnCod)) + [,] + Alltrim(Str(lnIdFact)) + [,] + Alltrim(Str(lnIdFactD)) + [,?gnIdUtil); end;]
|
Alltrim(Str(lnCod)) + [,] + Alltrim(Str(lnIdFact)) + [,] + Alltrim(Str(lnIdFactD)) + [,?gnIdUtil); end;]
|
||||||
lnSucces = Iif(goExecutor.oExecuta(lcSql),1,-1)
|
lnSucces = Iif(goExecutor.oExecuta(lcSql),1,-1)
|
||||||
Endif
|
Endif
|
||||||
|
If lnSucces > 0 And "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) And Used('tvanz') And Reccount('tvanz') = 1
|
||||||
|
lnSucces = Iif(ScrieArticoleFacturaEditate(tvanz.id_vanzare), 1, -1)
|
||||||
|
Endif
|
||||||
If Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1))
|
If Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1))
|
||||||
If lnSucces > 0
|
If lnSucces > 0
|
||||||
Thisform.do_cauta()
|
Thisform.do_cauta()
|
||||||
|
|||||||
@@ -6641,6 +6641,8 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Text1" 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.Header1" UniqueID="" Timestamp="" />
|
||||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Text1" UniqueID="" Timestamp="" />
|
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Text1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretAchizitieArt.Header1" UniqueID="" Timestamp="" />
|
||||||
|
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretAchizitieArt.Text1" UniqueID="" Timestamp="" />
|
||||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt.Header1" UniqueID="" Timestamp="" />
|
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt.Header1" UniqueID="" Timestamp="" />
|
||||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt._checkbox1" UniqueID="" Timestamp="" />
|
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt._checkbox1" UniqueID="" Timestamp="" />
|
||||||
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cProcTvavArt.Header1" UniqueID="" Timestamp="" />
|
*< OBJECTDATA: ObjPath="pgfArticole.PAGE3.grdArticoleFactura.cProcTvavArt.Header1" UniqueID="" Timestamp="" />
|
||||||
@@ -12317,7 +12319,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
|
|
||||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura' AS _grdrow WITH ;
|
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura' AS _grdrow WITH ;
|
||||||
Anchor = 15, ;
|
Anchor = 15, ;
|
||||||
ColumnCount = 14, ;
|
ColumnCount = 15, ;
|
||||||
DeleteMark = .F., ;
|
DeleteMark = .F., ;
|
||||||
FontSize = 10, ;
|
FontSize = 10, ;
|
||||||
GridLineColor = 128,128,128, ;
|
GridLineColor = 128,128,128, ;
|
||||||
@@ -12336,35 +12338,35 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
Width = 759, ;
|
Width = 759, ;
|
||||||
ZOrderSet = 1, ;
|
ZOrderSet = 1, ;
|
||||||
Column1.ControlSource = "tvd.denumire", ;
|
Column1.ControlSource = "tvd.denumire", ;
|
||||||
Column1.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column1.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column1.FontName = "Arial", ;
|
Column1.FontName = "Arial", ;
|
||||||
Column1.FontSize = 10, ;
|
Column1.FontSize = 10, ;
|
||||||
Column1.Name = "cDenumireArt", ;
|
Column1.Name = "cDenumireArt", ;
|
||||||
Column1.ReadOnly = .T., ;
|
Column1.ReadOnly = .T., ;
|
||||||
Column1.Width = 170, ;
|
Column1.Width = 170, ;
|
||||||
Column2.ControlSource = "tvd.codmat", ;
|
Column2.ControlSource = "tvd.codmat", ;
|
||||||
Column2.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column2.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column2.FontName = "Arial", ;
|
Column2.FontName = "Arial", ;
|
||||||
Column2.FontSize = 10, ;
|
Column2.FontSize = 10, ;
|
||||||
Column2.Name = "cCodmatArt", ;
|
Column2.Name = "cCodmatArt", ;
|
||||||
Column2.ReadOnly = .T., ;
|
Column2.ReadOnly = .T., ;
|
||||||
Column2.Width = 90, ;
|
Column2.Width = 90, ;
|
||||||
Column3.ControlSource = "tvd.serie", ;
|
Column3.ControlSource = "tvd.serie", ;
|
||||||
Column3.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column3.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column3.FontName = "Arial", ;
|
Column3.FontName = "Arial", ;
|
||||||
Column3.FontSize = 10, ;
|
Column3.FontSize = 10, ;
|
||||||
Column3.Name = "cSerieArt", ;
|
Column3.Name = "cSerieArt", ;
|
||||||
Column3.ReadOnly = .T., ;
|
Column3.ReadOnly = .T., ;
|
||||||
Column3.Width = 70, ;
|
Column3.Width = 70, ;
|
||||||
Column4.ControlSource = "tvd.lot", ;
|
Column4.ControlSource = "tvd.lot", ;
|
||||||
Column4.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column4.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column4.FontName = "Arial", ;
|
Column4.FontName = "Arial", ;
|
||||||
Column4.FontSize = 10, ;
|
Column4.FontSize = 10, ;
|
||||||
Column4.Name = "cLotArt", ;
|
Column4.Name = "cLotArt", ;
|
||||||
Column4.ReadOnly = .T., ;
|
Column4.ReadOnly = .T., ;
|
||||||
Column4.Width = 60, ;
|
Column4.Width = 60, ;
|
||||||
Column5.ControlSource = "tvd.cantitate", ;
|
Column5.ControlSource = "tvd.cantitate", ;
|
||||||
Column5.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column5.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column5.FontName = "Arial", ;
|
Column5.FontName = "Arial", ;
|
||||||
Column5.FontSize = 10, ;
|
Column5.FontSize = 10, ;
|
||||||
Column5.Format = "R", ;
|
Column5.Format = "R", ;
|
||||||
@@ -12373,7 +12375,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
Column5.ReadOnly = .F., ;
|
Column5.ReadOnly = .F., ;
|
||||||
Column5.Width = 70, ;
|
Column5.Width = 70, ;
|
||||||
Column6.ControlSource = "tvd.pret", ;
|
Column6.ControlSource = "tvd.pret", ;
|
||||||
Column6.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column6.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column6.FontName = "Arial", ;
|
Column6.FontName = "Arial", ;
|
||||||
Column6.FontSize = 10, ;
|
Column6.FontSize = 10, ;
|
||||||
Column6.Format = "R", ;
|
Column6.Format = "R", ;
|
||||||
@@ -12381,69 +12383,78 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
Column6.Name = "cPretArt", ;
|
Column6.Name = "cPretArt", ;
|
||||||
Column6.ReadOnly = .F., ;
|
Column6.ReadOnly = .F., ;
|
||||||
Column6.Width = 70, ;
|
Column6.Width = 70, ;
|
||||||
Column7.ControlSource = "tvd.pret_cu_tva", ;
|
Column7.ControlSource = "tvd.pret_achizitie", ;
|
||||||
Column7.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column7.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column7.FontName = "Arial", ;
|
Column7.FontName = "Arial", ;
|
||||||
Column7.FontSize = 10, ;
|
Column7.FontSize = 10, ;
|
||||||
Column7.Name = "cPretCuTvaArt", ;
|
Column7.Format = "R", ;
|
||||||
|
Column7.InputMask = (get_mask(12,gnPPRET)), ;
|
||||||
|
Column7.Name = "cPretAchizitieArt", ;
|
||||||
Column7.ReadOnly = .F., ;
|
Column7.ReadOnly = .F., ;
|
||||||
Column7.Sparse = .F., ;
|
Column7.Width = 90, ;
|
||||||
Column7.Width = 80, ;
|
Column8.ControlSource = "tvd.pret_cu_tva", ;
|
||||||
Column8.ControlSource = "tvd.proc_tvav", ;
|
Column8.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column8.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
|
||||||
Column8.FontName = "Arial", ;
|
Column8.FontName = "Arial", ;
|
||||||
Column8.FontSize = 10, ;
|
Column8.FontSize = 10, ;
|
||||||
Column8.Format = "R", ;
|
Column8.Name = "cPretCuTvaArt", ;
|
||||||
Column8.InputMask = "9.99", ;
|
Column8.ReadOnly = .F., ;
|
||||||
Column8.Name = "cProcTvavArt", ;
|
Column8.Sparse = .F., ;
|
||||||
Column8.ReadOnly = .T., ;
|
Column8.Width = 80, ;
|
||||||
Column8.Width = 55, ;
|
Column9.ControlSource = "tvd.proc_tvav", ;
|
||||||
Column9.ControlSource = "tvd.discount_unitar", ;
|
Column9.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column9.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
|
||||||
Column9.FontName = "Arial", ;
|
Column9.FontName = "Arial", ;
|
||||||
Column9.FontSize = 10, ;
|
Column9.FontSize = 10, ;
|
||||||
Column9.Format = "R", ;
|
Column9.Format = "R", ;
|
||||||
Column9.InputMask = (get_mask(12,gnPPRET)), ;
|
Column9.InputMask = "9.99", ;
|
||||||
Column9.Name = "cDiscountUnitarArt", ;
|
Column9.Name = "cProcTvavArt", ;
|
||||||
Column9.ReadOnly = .T., ;
|
Column9.ReadOnly = .T., ;
|
||||||
Column9.Width = 90, ;
|
Column9.Width = 55, ;
|
||||||
Column10.ControlSource = "tvd.nume_gestiune", ;
|
Column10.ControlSource = "tvd.discount_unitar", ;
|
||||||
Column10.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column10.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column10.FontName = "Arial", ;
|
Column10.FontName = "Arial", ;
|
||||||
Column10.FontSize = 10, ;
|
Column10.FontSize = 10, ;
|
||||||
Column10.Name = "cGestiuneArt", ;
|
Column10.Format = "R", ;
|
||||||
|
Column10.InputMask = (get_mask(12,gnPPRET)), ;
|
||||||
|
Column10.Name = "cDiscountUnitarArt", ;
|
||||||
Column10.ReadOnly = .T., ;
|
Column10.ReadOnly = .T., ;
|
||||||
Column10.Width = 90, ;
|
Column10.Width = 90, ;
|
||||||
Column11.ControlSource = "tvd.nume_val", ;
|
Column11.ControlSource = "tvd.nume_gestiune", ;
|
||||||
Column11.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column11.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column11.FontName = "Arial", ;
|
Column11.FontName = "Arial", ;
|
||||||
Column11.FontSize = 10, ;
|
Column11.FontSize = 10, ;
|
||||||
Column11.Name = "cValutaArt", ;
|
Column11.Name = "cGestiuneArt", ;
|
||||||
Column11.ReadOnly = .T., ;
|
Column11.ReadOnly = .T., ;
|
||||||
Column11.Width = 60, ;
|
Column11.Width = 90, ;
|
||||||
Column12.ControlSource = "tvd.explicatie", ;
|
Column12.ControlSource = "tvd.nume_val", ;
|
||||||
Column12.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column12.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column12.FontName = "Arial", ;
|
Column12.FontName = "Arial", ;
|
||||||
Column12.FontSize = 10, ;
|
Column12.FontSize = 10, ;
|
||||||
Column12.Name = "cExplicatieArt", ;
|
Column12.Name = "cValutaArt", ;
|
||||||
Column12.ReadOnly = .T., ;
|
Column12.ReadOnly = .T., ;
|
||||||
Column12.Width = 150, ;
|
Column12.Width = 60, ;
|
||||||
Column13.ControlSource = "tvd.taxcode", ;
|
Column13.ControlSource = "tvd.explicatie", ;
|
||||||
Column13.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column13.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column13.FontName = "Arial", ;
|
Column13.FontName = "Arial", ;
|
||||||
Column13.FontSize = 10, ;
|
Column13.FontSize = 10, ;
|
||||||
Column13.Name = "cTaxcodeArt", ;
|
Column13.Name = "cExplicatieArt", ;
|
||||||
Column13.ReadOnly = .T., ;
|
Column13.ReadOnly = .T., ;
|
||||||
Column13.Width = 60, ;
|
Column13.Width = 150, ;
|
||||||
Column14.ControlSource = "tvd.valoare", ;
|
Column14.ControlSource = "tvd.taxcode", ;
|
||||||
Column14.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))", ;
|
Column14.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
Column14.FontName = "Arial", ;
|
Column14.FontName = "Arial", ;
|
||||||
Column14.FontSize = 10, ;
|
Column14.FontSize = 10, ;
|
||||||
Column14.Format = "R", ;
|
Column14.Name = "cTaxcodeArt", ;
|
||||||
Column14.InputMask = (get_mask(14,gnPa)), ;
|
|
||||||
Column14.Name = "cValoareArt", ;
|
|
||||||
Column14.ReadOnly = .T., ;
|
Column14.ReadOnly = .T., ;
|
||||||
Column14.Width = 90
|
Column14.Width = 60, ;
|
||||||
|
Column15.ControlSource = "tvd.valoare", ;
|
||||||
|
Column15.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))", ;
|
||||||
|
Column15.FontName = "Arial", ;
|
||||||
|
Column15.FontSize = 10, ;
|
||||||
|
Column15.Format = "R", ;
|
||||||
|
Column15.InputMask = (get_mask(14,gnPa)), ;
|
||||||
|
Column15.Name = "cValoareArt", ;
|
||||||
|
Column15.ReadOnly = .T., ;
|
||||||
|
Column15.Width = 90
|
||||||
*< END OBJECT: ClassLib="_grd_base.vcx" BaseClass="grid" />
|
*< END OBJECT: ClassLib="_grd_base.vcx" BaseClass="grid" />
|
||||||
|
|
||||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Header1' AS header WITH ;
|
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Header1' AS header WITH ;
|
||||||
@@ -12593,6 +12604,27 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
SelectedBackColor = 100,185,255
|
SelectedBackColor = 100,185,255
|
||||||
*< END OBJECT: BaseClass="textbox" />
|
*< END OBJECT: BaseClass="textbox" />
|
||||||
|
|
||||||
|
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretAchizitieArt.Header1' AS header WITH ;
|
||||||
|
Alignment = 2, ;
|
||||||
|
Caption = "Pret achizitie", ;
|
||||||
|
FontName = "Arial", ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
Name = "Header1", ;
|
||||||
|
WordWrap = .T.
|
||||||
|
*< END OBJECT: BaseClass="header" />
|
||||||
|
|
||||||
|
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretAchizitieArt.Text1' AS textbox WITH ;
|
||||||
|
BackColor = 255,255,255, ;
|
||||||
|
BorderStyle = 0, ;
|
||||||
|
FontName = "Arial", ;
|
||||||
|
FontSize = 10, ;
|
||||||
|
ForeColor = 0,0,0, ;
|
||||||
|
Margin = 0, ;
|
||||||
|
Name = "Text1", ;
|
||||||
|
ReadOnly = .F., ;
|
||||||
|
SelectedBackColor = 100,185,255
|
||||||
|
*< END OBJECT: BaseClass="textbox" />
|
||||||
|
|
||||||
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Header1' AS header WITH ;
|
ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Header1' AS header WITH ;
|
||||||
Alignment = 2, ;
|
Alignment = 2, ;
|
||||||
Caption = "Pret", ;
|
Caption = "Pret", ;
|
||||||
@@ -13116,7 +13148,8 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
id_jtva_coloana WITH toArticol.id_jtva_coloana, serie WITH toArticol.serie, ;
|
id_jtva_coloana WITH toArticol.id_jtva_coloana, serie WITH toArticol.serie, ;
|
||||||
explicatie WITH toArticol.explicatie, taxcode WITH toArticol.taxcode, lot WITH toArticol.lot, ;
|
explicatie WITH toArticol.explicatie, taxcode WITH toArticol.taxcode, lot WITH toArticol.lot, ;
|
||||||
sters WITH 0, denumire WITH toArticol.denumire, codmat WITH toArticol.codmat, ;
|
sters WITH 0, denumire WITH toArticol.denumire, codmat WITH toArticol.codmat, ;
|
||||||
nume_gestiune WITH '', nume_val WITH Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.nume_val,''), toArticol.nume_val), lmodificat WITH .T.
|
nume_gestiune WITH '', nume_val WITH Iif(Used('tvanz') And Reccount('tvanz') > 0, Nvl(tvanz.nume_val,''), toArticol.nume_val), ;
|
||||||
|
pret_achizitie WITH Nvl(toArticol.pret_achizitie,0), lmodificat WITH .T.
|
||||||
Thisform.calculeaza_valori_articol()
|
Thisform.calculeaza_valori_articol()
|
||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
@@ -14293,6 +14326,64 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
Endif
|
Endif
|
||||||
ENDIF
|
ENDIF
|
||||||
*!* modificare v 2.4.4 ^
|
*!* modificare v 2.4.4 ^
|
||||||
|
IF "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) AND Used('tvd')
|
||||||
|
LOCAL lnAreaTvd, lnRecnoTvd, lnLiniiActive
|
||||||
|
lnAreaTvd = Select()
|
||||||
|
lnRecnoTvd = Recno('tvd')
|
||||||
|
lnLiniiActive = 0
|
||||||
|
SELECT tvd
|
||||||
|
SCAN FOR Nvl(sters,0) <> 1
|
||||||
|
lnLiniiActive = m.lnLiniiActive + 1
|
||||||
|
IF Nvl(cantitate,0) <= 0
|
||||||
|
AMESSAGEBOX("Linia '" + Alltrim(Nvl(denumire,'')) + "' are cantitatea 0 sau negativa.",0+16,"Eroare")
|
||||||
|
IF Between(m.lnRecnoTvd,1,Reccount('tvd'))
|
||||||
|
GO (m.lnRecnoTvd) IN tvd
|
||||||
|
ENDIF
|
||||||
|
SELECT (m.lnAreaTvd)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
IF Isnull(pret)
|
||||||
|
AMESSAGEBOX("Linia '" + Alltrim(Nvl(denumire,'')) + "' nu are pret completat.",0+16,"Eroare")
|
||||||
|
IF Between(m.lnRecnoTvd,1,Reccount('tvd'))
|
||||||
|
GO (m.lnRecnoTvd) IN tvd
|
||||||
|
ENDIF
|
||||||
|
SELECT (m.lnAreaTvd)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
IF Nvl(id_articol,0) = 0
|
||||||
|
AMESSAGEBOX("Linia '" + Alltrim(Nvl(denumire,'')) + "' nu are articol asociat.",0+16,"Eroare")
|
||||||
|
IF Between(m.lnRecnoTvd,1,Reccount('tvd'))
|
||||||
|
GO (m.lnRecnoTvd) IN tvd
|
||||||
|
ENDIF
|
||||||
|
SELECT (m.lnAreaTvd)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
IF Nvl(id_vanzare_det,0) = 0 AND Nvl(pret_achizitie,0) = 0
|
||||||
|
IF amessagebox("Linia '" + Alltrim(Nvl(denumire,'')) + "' are pretul de achizitie 0." + CRLF + ;
|
||||||
|
"Doriti sa continuati?",4+32,"Pret de achizitie") <> 6
|
||||||
|
IF Between(m.lnRecnoTvd,1,Reccount('tvd'))
|
||||||
|
GO (m.lnRecnoTvd) IN tvd
|
||||||
|
ENDIF
|
||||||
|
SELECT (m.lnAreaTvd)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
ENDSCAN
|
||||||
|
IF m.lnLiniiActive = 0 AND Used('tvanz') AND Reccount('tvanz') = 1
|
||||||
|
IF amessagebox("Toate liniile facturii au fost sterse." + CRLF + ;
|
||||||
|
"Doriti sa continuati?",4+32,"Factura fara linii") <> 6
|
||||||
|
IF Between(m.lnRecnoTvd,1,Reccount('tvd'))
|
||||||
|
GO (m.lnRecnoTvd) IN tvd
|
||||||
|
ENDIF
|
||||||
|
SELECT (m.lnAreaTvd)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
IF Between(m.lnRecnoTvd,1,Reccount('tvd'))
|
||||||
|
GO (m.lnRecnoTvd) IN tvd
|
||||||
|
ENDIF
|
||||||
|
SELECT (m.lnAreaTvd)
|
||||||
|
ENDIF
|
||||||
RETURN m.llRet
|
RETURN m.llRet
|
||||||
|
|
||||||
|
|
||||||
@@ -14568,7 +14659,7 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
IF Used('tvd')
|
IF Used('tvd')
|
||||||
Use In tvd
|
Use In tvd
|
||||||
ENDIF
|
ENDIF
|
||||||
CREATE CURSOR tvd (id_vanzare I NULL, id_vanzare_det I NULL, id_articol I NULL, cantitate N(12,3) NULL, pret N(14,4) NULL, pret_cu_tva N(14,4) NULL, proc_tvav N(6,4) NULL, discount_unitar N(14,4) NULL, id_gestiune I NULL, cont C(20) NULL, id_valuta I NULL, id_jtva_coloana I NULL, serie C(20) NULL, explicatie C(60) NULL, taxcode I NULL, lot C(20) NULL, sters I NULL, denumire C(100) NULL, codmat C(30) NULL, nume_gestiune C(60) NULL, nume_val C(20) NULL, lmodificat L, valoare N(14,2), in_stoc I NULL)
|
CREATE CURSOR tvd (id_vanzare I NULL, id_vanzare_det I NULL, id_articol I NULL, cantitate N(12,3) NULL, pret N(14,4) NULL, pret_cu_tva N(14,4) NULL, proc_tvav N(6,4) NULL, discount_unitar N(14,4) NULL, id_gestiune I NULL, cont C(20) NULL, id_valuta I NULL, id_jtva_coloana I NULL, serie C(20) NULL, explicatie C(60) NULL, taxcode I NULL, lot C(20) NULL, sters I NULL, id_vanzare_set I NULL, pret_achizitie N(14,4) NULL, denumire C(100) NULL, codmat C(30) NULL, nume_gestiune C(60) NULL, nume_val C(20) NULL, lmodificat L, valoare N(14,2), in_stoc I NULL)
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
*!* cursorul tvanz - placeholder gol, ca bara de totaluri (ControlSource pe tvanz.discount) sa se lege la construire
|
*!* cursorul tvanz - placeholder gol, ca bara de totaluri (ControlSource pe tvanz.discount) sa se lege la construire
|
||||||
@@ -16433,6 +16524,16 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
PROCEDURE pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Text1.When
|
PROCEDURE pgfArticole.PAGE3.grdArticoleFactura.cCantitateArt.Text1.When
|
||||||
|
IF Nvl(tvd.id_vanzare_set,0) <> 0
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
Thisform.oldvalue = This.Value
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE pgfArticole.PAGE3.grdArticoleFactura.cPretAchizitieArt.Text1.When
|
||||||
|
IF Nvl(tvd.id_vanzare_set,0) <> 0 OR Nvl(tvd.id_vanzare_det,0) <> 0
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
Thisform.oldvalue = This.Value
|
Thisform.oldvalue = This.Value
|
||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
@@ -16444,6 +16545,9 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
PROCEDURE pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Text1.When
|
PROCEDURE pgfArticole.PAGE3.grdArticoleFactura.cPretArt.Text1.When
|
||||||
|
IF Nvl(tvd.id_vanzare_set,0) <> 0
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
Thisform.oldvalue = This.Value
|
Thisform.oldvalue = This.Value
|
||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
@@ -16457,6 +16561,10 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
|
|||||||
This.Parent.Parent.Refresh()
|
This.Parent.Parent.Refresh()
|
||||||
ENDPROC
|
ENDPROC
|
||||||
|
|
||||||
|
PROCEDURE pgfArticole.PAGE3.grdArticoleFactura.cPretCuTvaArt._checkbox1.When
|
||||||
|
RETURN Nvl(tvd.id_vanzare_set,0) = 0
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
PROCEDURE pgfArticole.PAGE3.txtDiscountArt.Valid
|
PROCEDURE pgfArticole.PAGE3.txtDiscountArt.Valid
|
||||||
Thisform.ActualizeazaBaraTotaluri()
|
Thisform.ActualizeazaBaraTotaluri()
|
||||||
ENDPROC
|
ENDPROC
|
||||||
|
|||||||
@@ -27,9 +27,22 @@ Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF
|
|||||||
|
|
||||||
## Comanda de export (re-generare .pck)
|
## Comanda de export (re-generare .pck)
|
||||||
|
|
||||||
|
> **`linesize` prea mic corupe tăcut sursa.** SQL\*Plus face **wrap** la coloana `linesize`, deci o
|
||||||
|
> linie de cod mai lungă e ruptă în două — inclusiv **prin mijlocul unui identificator**. Fișierul
|
||||||
|
> pare întreg, `diff` față de el nu arată nimic, dar recompilarea lui dă erori la linii care n-au
|
||||||
|
> nicio legătură cu ce ai modificat (`ORA-00920`, `PLS-*`). `PACK_FACTURARE` are linii de peste
|
||||||
|
> **1000** de caractere, iar un export la `linesize 400` i-a rupt 8. Folosește `linesize 32767` și
|
||||||
|
> verifică după export că nicio linie nu atinge exact valoarea `linesize`.
|
||||||
|
>
|
||||||
|
> **Exportul e bun pentru CITIT, nu ca bază pentru un script de migrare.** Pentru un script de
|
||||||
|
> pachet, pleacă de la ultimul script aplicat din `SCRIPTURI_CLAR` (fișier real, care n-a trecut
|
||||||
|
> niciodată printr-un spool) și confirmă că e la zi comparându-l cu exportul **ignorând spațiul
|
||||||
|
> alb** — așa wrap-ul nu mai contează:
|
||||||
|
> `tr -d ' \t\r\n' < fisier | md5sum` pe ambele.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- export_pack.sql
|
-- export_pack.sql
|
||||||
set pagesize 0 linesize 400 trimspool on feedback off heading off termout off
|
set pagesize 0 linesize 32767 long 2000000 longchunksize 32767 trimspool on feedback off heading off termout off
|
||||||
spool D:\ROA\ROAGEST\COMUN\docs\PACK_CONTAFIN.pck
|
spool D:\ROA\ROAGEST\COMUN\docs\PACK_CONTAFIN.pck
|
||||||
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE' order by line;
|
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE' order by line;
|
||||||
select '/' from dual;
|
select '/' from dual;
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ Reguli confirmate de Marius (24.07.2026):
|
|||||||
arata spre comentariu. Pus la sfarsit de fraza, `.` in loc de `;`. Comentariile de **dinaintea**
|
arata spre comentariu. Pus la sfarsit de fraza, `.` in loc de `;`. Comentariile de **dinaintea**
|
||||||
instructiunii nu sunt afectate.
|
instructiunii nu sunt afectate.
|
||||||
- **Fiecare script se incheie cu `exec pack_migrare.UpdateVersiune('<nume_script>');` urmat de
|
- **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
|
`commit;`.** Numele se da **fara extensia `.sql`** — o adauga `UpdateVersiune`; trecuta si in
|
||||||
|
argument, ajunge in `VERSIUNE` ca `..._.sql.sql` si scriptul apare ca neaplicat la comparatia de
|
||||||
|
mai jos. Toate scriptele din `SCRIPTURI_CLAR` o omit, iar in `VERSIUNE` nu exista niciun rand cu
|
||||||
|
dubla extensie.
|
||||||
|
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
|
se poate aplica fara ca versiunea sa se inregistreze, iar `VERSIUNE` ajunge sa minta despre ce s-a
|
||||||
aplicat.
|
aplicat.
|
||||||
- **Rularea manuala se face conectat pe schema tinta** (`CONTAFIN_ORACLE` pentru `co_`, schema firmei
|
- **Rularea manuala se face conectat pe schema tinta** (`CONTAFIN_ORACLE` pentru `co_`, schema firmei
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
*!* marius.mutu
|
*!* marius.mutu
|
||||||
*!* helpere comune pentru editarea unei facturi emise: garda eFactura, cursoarele notei si ale rulajelor,
|
*!* helpere comune pentru editarea unei facturi emise: garda eFactura, cursoarele notei si ale rulajelor,
|
||||||
*!* randul de vanzare corespunzator notei (inclusiv valuta documentului: in_valuta/id_valuta/nume_val),
|
*!* randul de vanzare corespunzator notei (inclusiv valuta documentului: in_valuta/id_valuta/nume_val),
|
||||||
*!* liniile de articole pentru pagina de articole factura (inclusiv in_stoc, pentru corectia verdictului
|
*!* liniile de articole pentru pagina de articole factura (inclusiv in_stoc si id_vanzare_set/pret_achizitie,
|
||||||
*!* RUL pe liniile nestocate), pregatirea cursorului de articole inainte de Createobject(frm_modific2024)
|
*!* pentru corectia verdictului RUL pe liniile nestocate si pentru liniile din seturi), pregatirea
|
||||||
*!* si construirea obiectului poArticol pentru adaugarea unei linii noi prin dialogul frm_articol_factura,
|
*!* cursorului de articole inainte de Createobject(frm_modific2024), construirea obiectului poArticol
|
||||||
*!* populat cu valuta documentului cand acesta e in valuta
|
*!* pentru adaugarea unei linii noi prin dialogul frm_articol_factura (populat cu valuta documentului
|
||||||
|
*!* cand acesta e in valuta) si scrierea in VANZARI_DETALII a liniilor editate/adaugate/sterse
|
||||||
|
|
||||||
|
|
||||||
*!* parametru: id_fact
|
*!* parametru: id_fact
|
||||||
@@ -271,7 +272,7 @@ FUNCTION CreeazaCursorArticoleGol
|
|||||||
ENDIF
|
ENDIF
|
||||||
CREATE CURSOR (m.lcAlias) (id_vanzare I NULL, id_vanzare_det I NULL, id_articol I NULL, cantitate N(12,3) NULL, pret N(14,4) NULL, pret_cu_tva N(14,4) NULL, proc_tvav N(6,4) NULL, ;
|
CREATE CURSOR (m.lcAlias) (id_vanzare I NULL, id_vanzare_det I NULL, id_articol I NULL, cantitate N(12,3) NULL, pret N(14,4) NULL, pret_cu_tva N(14,4) NULL, proc_tvav N(6,4) NULL, ;
|
||||||
discount_unitar N(14,4) NULL, id_gestiune I NULL, cont C(20) NULL, id_valuta I NULL, id_jtva_coloana I NULL, serie C(20) NULL, explicatie C(60) NULL, ;
|
discount_unitar N(14,4) NULL, id_gestiune I NULL, cont C(20) NULL, id_valuta I NULL, id_jtva_coloana I NULL, serie C(20) NULL, explicatie C(60) NULL, ;
|
||||||
taxcode I NULL, lot C(20) NULL, sters I NULL, denumire C(100) NULL, codmat C(30) NULL, nume_gestiune C(60) NULL, nume_val C(20) NULL, ;
|
taxcode I NULL, lot C(20) NULL, sters I NULL, id_vanzare_set I NULL, pret_achizitie N(14,4) NULL, denumire C(100) NULL, codmat C(30) NULL, nume_gestiune C(60) NULL, nume_val C(20) NULL, ;
|
||||||
lmodificat L, valoare N(14,2), in_stoc I NULL)
|
lmodificat L, valoare N(14,2), in_stoc I NULL)
|
||||||
ENDFUNC && CreeazaCursorArticoleGol
|
ENDFUNC && CreeazaCursorArticoleGol
|
||||||
|
|
||||||
@@ -455,3 +456,100 @@ FUNCTION CreeazaPoArticolNouTvd
|
|||||||
|
|
||||||
RETURN loArticol
|
RETURN loArticol
|
||||||
ENDFUNC && CreeazaPoArticolNouTvd
|
ENDFUNC && CreeazaPoArticolNouTvd
|
||||||
|
|
||||||
|
|
||||||
|
*!* parametri: id_vanzare (din tvanz.id_vanzare), alias articole (implicit tvd), alias vanzare (implicit tvanz)
|
||||||
|
*!* scrie in VANZARI_DETALII liniile editate ale notei, ca diferenta fata de starea persistata: marcheaza
|
||||||
|
*!* sters tot documentul, invie/actualizeaza liniile pastrate din alias, insereaza liniile noi, apoi
|
||||||
|
*!* recalculeaza totalurile documentului (cu discountul din alias vanzare, ca sa nu poata diverge de
|
||||||
|
*!* liniile scrise); ruleaza in tranzactia manuala deja deschisa de apelant, dupa finalizeaza_modificare_nota
|
||||||
|
*!* - nu da COMMIT/ROLLBACK, nu inchide cursoare, salveaza si restaureaza workarea/pozitia curenta
|
||||||
|
*!* retur logic: .T. daca a mers tot sau nu era nimic de facut, .F. la primul esec Oracle (se opreste acolo)
|
||||||
|
FUNCTION ScrieArticoleFacturaEditate
|
||||||
|
LPARAMETERS tnIdVanzare, tcAliasArticole, tcAliasVanzare
|
||||||
|
|
||||||
|
LOCAL lcAliasArt, lcAliasVanz, lnAreaOrigine, lnRecnoArt, llSucces, lcSql, lnDiscount, llDiscountNul
|
||||||
|
lcAliasArt = IIF(Type('tcAliasArticole') = 'C' AND !Empty(m.tcAliasArticole), m.tcAliasArticole, 'tvd')
|
||||||
|
lcAliasVanz = IIF(Type('tcAliasVanzare') = 'C' AND !Empty(m.tcAliasVanzare), m.tcAliasVanzare, 'tvanz')
|
||||||
|
|
||||||
|
*!* cursor gol de articole nu inseamna "document fara linii" - poate fi si un esec de incarcare (IncarcaArticoleFactura intoarce .T. cu cursor gol la eroare Oracle); fara ancora, ar goli tacut factura
|
||||||
|
IF Nvl(m.tnIdVanzare,0) <= 0 OR !Used(m.lcAliasArt) OR !Used(m.lcAliasVanz) OR Reccount(m.lcAliasVanz) <> 1 OR Reccount(m.lcAliasArt) = 0
|
||||||
|
RETURN .T.
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
lnAreaOrigine = Select()
|
||||||
|
llSucces = .T.
|
||||||
|
|
||||||
|
SELECT (m.lcAliasVanz)
|
||||||
|
GO TOP
|
||||||
|
llDiscountNul = Isnull(discount)
|
||||||
|
lnDiscount = Nvl(discount,0)
|
||||||
|
|
||||||
|
*!* marcheaza sters tot documentul - perechea reset-ului STERS=0 din actualizeaza_vanzari
|
||||||
|
lcSql = [update vanzari_detalii set sters = 1, id_utils = ] + Alltrim(Str(gnIdUtil)) + [, dataoras = sysdate ] + ;
|
||||||
|
[where id_vanzare = ] + Alltrim(Str(m.tnIdVanzare)) + [ and sters = 0]
|
||||||
|
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||||
|
|
||||||
|
*!* invie si actualizeaza liniile pastrate - toate cele active din alias, nu doar lmodificat, pasul de mai sus le-a marcat pe toate
|
||||||
|
IF m.llSucces
|
||||||
|
SELECT (m.lcAliasArt)
|
||||||
|
lnRecnoArt = Recno()
|
||||||
|
SCAN FOR id_vanzare_det > 0 AND Nvl(sters,0) <> 1
|
||||||
|
lcSql = [update vanzari_detalii set sters = 0, cantitate = ] + Alltrim(Str(Nvl(cantitate,0),18,3)) + ;
|
||||||
|
[, pret = ] + Alltrim(Str(Nvl(pret,0),18,4)) + [, pret_cu_tva = ] + Alltrim(Str(Nvl(pret_cu_tva,0))) + ;
|
||||||
|
[, id_utils = ] + Alltrim(Str(gnIdUtil)) + [, dataoras = sysdate ] + ;
|
||||||
|
[where id_vanzare_det = ] + Alltrim(Str(id_vanzare_det)) + [ and id_vanzare = ] + Alltrim(Str(m.tnIdVanzare))
|
||||||
|
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||||
|
IF !m.llSucces
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
ENDSCAN
|
||||||
|
TRY
|
||||||
|
GO m.lnRecnoArt IN (m.lcAliasArt)
|
||||||
|
CATCH
|
||||||
|
GO TOP IN (m.lcAliasArt)
|
||||||
|
ENDTRY
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*!* insereaza liniile noi - fara id_vanzare_det, il genereaza trigger-ul TRG_VANZARI_DET_BEFOINS
|
||||||
|
IF m.llSucces
|
||||||
|
SELECT (m.lcAliasArt)
|
||||||
|
lnRecnoArt = Recno()
|
||||||
|
SCAN FOR id_vanzare_det = 0 AND Nvl(sters,0) <> 1
|
||||||
|
lcSql = [insert into vanzari_detalii (id_vanzare, id_articol, cantitate, pret, pret_cu_tva, proc_tvav, discount_unitar, ] + ;
|
||||||
|
[id_gestiune, cont, id_valuta, id_jtva_coloana, serie, explicatie, taxcode, lot, pret_achizitie, id_utils, dataoras) values (] + ;
|
||||||
|
Alltrim(Str(m.tnIdVanzare)) + [,] + Alltrim(Str(Nvl(id_articol,0))) + [,] + Alltrim(Str(Nvl(cantitate,0),18,3)) + [,] + ;
|
||||||
|
Alltrim(Str(Nvl(pret,0),18,4)) + [,] + Alltrim(Str(Nvl(pret_cu_tva,0))) + [,] + Alltrim(Str(Nvl(proc_tvav,0),18,4)) + [,] + ;
|
||||||
|
Alltrim(Str(Nvl(discount_unitar,0),18,4)) + [,] + Iif(Isnull(id_gestiune),[NULL],Alltrim(Str(id_gestiune))) + [,] + ;
|
||||||
|
Iif(Empty(Nvl(cont,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(cont,''))) + [']) + [,] + ;
|
||||||
|
Iif(Isnull(id_valuta),[NULL],Alltrim(Str(id_valuta))) + [,] + Iif(Isnull(id_jtva_coloana),[NULL],Alltrim(Str(id_jtva_coloana))) + [,] + ;
|
||||||
|
Iif(Empty(Nvl(serie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(serie,''))) + [']) + [,] + ;
|
||||||
|
Iif(Empty(Nvl(explicatie,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(explicatie,''))) + [']) + [,] + ;
|
||||||
|
Iif(Isnull(taxcode),[NULL],Alltrim(Str(taxcode))) + [,] + ;
|
||||||
|
Iif(Empty(Nvl(lot,'')),[NULL],['] + OracleSpecialCharacters(Alltrim(Nvl(lot,''))) + [']) + [,] + ;
|
||||||
|
Alltrim(Str(Nvl(pret_achizitie,0),18,4)) + [,] + Alltrim(Str(gnIdUtil)) + [, sysdate)]
|
||||||
|
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||||
|
IF !m.llSucces
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
ENDSCAN
|
||||||
|
TRY
|
||||||
|
GO m.lnRecnoArt IN (m.lcAliasArt)
|
||||||
|
CATCH
|
||||||
|
GO TOP IN (m.lcAliasArt)
|
||||||
|
ENDTRY
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*!* recalculul totalurilor, cu discountul documentului dat ca parametru - .NULL. pastreaza discountul curent
|
||||||
|
IF m.llSucces
|
||||||
|
lcSql = [begin pack_facturare.recalculeaza_totaluri_vanzari(] + Alltrim(Str(m.tnIdVanzare)) + [,] + ;
|
||||||
|
Iif(m.llDiscountNul,[NULL],Alltrim(Str(m.lnDiscount,18,4))) + [); end;]
|
||||||
|
llSucces = goExecutor.oExecuta(m.lcSql)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF m.lnAreaOrigine > 0
|
||||||
|
SELECT (m.lnAreaOrigine)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
RETURN m.llSucces
|
||||||
|
ENDFUNC && ScrieArticoleFacturaEditate
|
||||||
|
|||||||
@@ -355,11 +355,15 @@ PROCEDURE verifica_editare_grid
|
|||||||
loForm.Show()
|
loForm.Show()
|
||||||
|
|
||||||
loGrid = loForm.pgfArticole.Page3.grdArticoleFactura
|
loGrid = loForm.pgfArticole.Page3.grdArticoleFactura
|
||||||
llStructuraOk = (loGrid.ColumnCount == 14) AND ;
|
*!* S5: coloana noua Column7=pret_achizitie (dupa Column6=pret), Column8..15 = restul, deplasate cu 1;
|
||||||
(Type('tvd.lmodificat') == 'L') AND (Type('tvd.valoare') == 'N')
|
*!* pret_achizitie e editabila la nivel de coloana (gating-ul e mutat in When, per rand - decizia S5.C)
|
||||||
|
llStructuraOk = (loGrid.ColumnCount == 15) AND ;
|
||||||
|
(Type('tvd.lmodificat') == 'L') AND (Type('tvd.valoare') == 'N') AND ;
|
||||||
|
(Type('tvd.pret_achizitie') == 'N') AND (Type('tvd.id_vanzare_set') == 'N')
|
||||||
llReadOnlyOk = (loGrid.Column5.ReadOnly == .F.) AND (loGrid.Column6.ReadOnly == .F.) AND ;
|
llReadOnlyOk = (loGrid.Column5.ReadOnly == .F.) AND (loGrid.Column6.ReadOnly == .F.) AND ;
|
||||||
(loGrid.Column7.ReadOnly == .F.) AND (Pemstatus(loGrid.Column7, '_checkbox1', 5)) AND ;
|
(loGrid.Column7.ReadOnly == .F.) AND (loGrid.Column8.ReadOnly == .F.) AND ;
|
||||||
(loGrid.Column1.ReadOnly == .T.) AND (loGrid.Column14.ReadOnly == .T.)
|
(Pemstatus(loGrid.Column8, '_checkbox1', 5)) AND ;
|
||||||
|
(loGrid.Column1.ReadOnly == .T.) AND (loGrid.Column15.ReadOnly == .T.)
|
||||||
|
|
||||||
IF Reccount('tvd') > 0
|
IF Reccount('tvd') > 0
|
||||||
Go Top In tvd
|
Go Top In tvd
|
||||||
@@ -379,8 +383,8 @@ PROCEDURE verifica_editare_grid
|
|||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
STRTOFILE('--- S4 runda 3A, editare grid, cod=' + TRANSFORM(tnCod) + ' ---' + CHR(13) + CHR(10) + ;
|
STRTOFILE('--- S4 runda 3A, editare grid, cod=' + TRANSFORM(tnCod) + ' ---' + CHR(13) + CHR(10) + ;
|
||||||
' structura grid/cursor (ColumnCount=14, lmodificat L, valoare N) = ' + IIF(llStructuraOk, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
' structura grid/cursor (ColumnCount=15, lmodificat L, valoare N, pret_achizitie N, id_vanzare_set N) = ' + IIF(llStructuraOk, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
||||||
' ReadOnly (cantitate/pret/pret_cu_tva editabile, checkbox pe pret_cu_tva, restul readonly) = ' + IIF(llReadOnlyOk, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
' ReadOnly (cantitate/pret/pret_achizitie editabile, checkbox pe pret_cu_tva, restul readonly) = ' + IIF(llReadOnlyOk, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
||||||
' stare initiala (lmodificat=.F., valoare calculata corect) = ' + IIF(llInitOk, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
' stare initiala (lmodificat=.F., valoare calculata corect) = ' + IIF(llInitOk, 'PASS', 'FAIL') + CHR(13) + CHR(10) + ;
|
||||||
' dupa editare cantitate (lmodificat=.T., valoare recalculata) = ' + IIF(llDupaEditareOk, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
' dupa editare cantitate (lmodificat=.T., valoare recalculata) = ' + IIF(llDupaEditareOk, 'PASS', 'FAIL') + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
|||||||
415
utile/Teste/editare_factura/test_s5_al_doilea_intrare.prg
Normal file
415
utile/Teste/editare_factura/test_s5_al_doilea_intrare.prg
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
* test_s5_al_doilea_intrare.prg
|
||||||
|
* Inchide golul "al doilea punct de intrare" din docs\livrare_s5.md, sectiunea 5: agatarea din
|
||||||
|
* comun.vc2:2491-2493 (afisjurcom.do_modifica, "Registrul jurnal" ROACONT/ROAGEST, textual identica
|
||||||
|
* cu cea din ofacturare_comun.vc2:3828-3830, deja testata cu scriere reala in test_s5_scriere_reala.prg)
|
||||||
|
* nu trecuse inca prin nicio scriere reala.
|
||||||
|
*
|
||||||
|
* Diferenta functionala fata de do_editare_factura (frm_facturi), singura care conteaza pentru acest
|
||||||
|
* test: afisjurcom.do_modifica NU apeleaza IncarcaVanzareDinNota direct - apeleaza
|
||||||
|
* PregatesteArticoleFacturaEditare('tact') (comun.vc2:2436) INAINTE de Createobject(frm_modific2024),
|
||||||
|
* care populeaza tvanz (si crsArticoleFactura) pe alta cale de cod. Testul reproduce EXACT secventa
|
||||||
|
* comun.vc2:2222-2569 (do_modifica), mai putin partea de UI (grid-ul actjur, frm_modific2024 - nu
|
||||||
|
* garda "Used('tvanz') And Reccount('tvanz')=1" testata prin PregatesteArticoleFacturaEditare reala,
|
||||||
|
* nici SCAN pe articole, care ramane la verificarea vizuala a lui Marius, per briefing), pe aceeasi
|
||||||
|
* nota folosita deja de test_s5_scriere_reala.prg/test_s5_discount_valuta.prg (id_vanzare=1049) -
|
||||||
|
* SINGURA din documentele de test cunoscute care are simultan rand real in VANZARI si nota in luna
|
||||||
|
* curenta (cerinta lui afisjurcom.do_modifica, linia 2265-2268).
|
||||||
|
*
|
||||||
|
* Fara nicio modificare de articole (ca in blocul C din test_s5_discount_valuta.prg): dovedeste ca
|
||||||
|
* PE ACEASTA CALE lnSucces ajunge > 0 dupa finalizeaza_modificare_nota, garda noua se satisface real
|
||||||
|
* (nu doar static) si ScrieArticoleFacturaEditate se executa cu tvanz.id_vanzare corect. Tranzactia
|
||||||
|
* se inchide cu COMMIT (Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1)), comun.vc2:2541) - lantul
|
||||||
|
* reuseste, deci NU ROLLBACK (spre deosebire de celelalte suite S5 cu esec provocat deliberat).
|
||||||
|
*
|
||||||
|
* ATENTIE - GASIT SI REPARAT IN TIMPUL SCRIERII ACESTUI TEST (nu ramane in fisierul final): o prima
|
||||||
|
* varianta apela ScrieArticoleFacturaEditate FARA sa incarce intai 'tvd' (frm_modific2024, sarit aici
|
||||||
|
* deliberat, e cel care il populeaza in fluxul real, din crsArticoleFactura). Garda externa
|
||||||
|
* (Used('tvanz') And Reccount('tvanz')=1) s-a satisfacut, dar garda INTERNA de no-op a helperului
|
||||||
|
* (!Used('tvd')) a facut din apel un no-op TACUT (intoarce tot .T.) - fara sa corecteze reset-ul
|
||||||
|
* STERS=0 pe care actualizeaza_vanzari il face pe TOT documentul (acelasi mecanism documentat in
|
||||||
|
* rec_s5_scriere_reala.md), iar tranzactia a COMMIS reset-ul necorectat: o linie definitiv stearsa
|
||||||
|
* in testele anterioare (det=1582, id_vanzare=1049) a fost reinviata real in Oracle. Reparat imediat
|
||||||
|
* (UPDATE vanzari_detalii SET STERS=1 WHERE id_vanzare_det=1582, COMMIT, verificat prin sqlplus) -
|
||||||
|
* varianta finala incarca 'tvd' cu IncarcaArticoleFactura chiar dupa PregatesteArticoleFacturaEditare
|
||||||
|
* (ca sa reproduca ce ar face Load()-ul lui frm_modific2024), deci helperul chiar corecteaza reset-ul,
|
||||||
|
* la fel ca in fluxul real. CONSUMA UN COD (finalizeaza_modificare_nota il realoca la orice salvare,
|
||||||
|
* chiar fara modificari de articole - acelasi efect ca blocul C din test_s5_discount_valuta.prg).
|
||||||
|
*
|
||||||
|
* Harness: do_deschide/inchide_tranzactie reproduse inline dupa _frm_base.vc2:252-302 (identic cu
|
||||||
|
* celelalte suite S5 cu scriere reala). Nu atinge cod de aplicatie, nu instantiaza afisjurcom sau
|
||||||
|
* frm_modific2024 (evita riscul de UI blocanta headless). QUIT la final.
|
||||||
|
|
||||||
|
SET SAFETY OFF
|
||||||
|
SET TALK OFF
|
||||||
|
|
||||||
|
LOCAL lcLog
|
||||||
|
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s5_al_doilea_intrare_log.txt'
|
||||||
|
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
|
||||||
|
|
||||||
|
PUBLIC gcErrLog, gcTestLog, gnPass, gnFail
|
||||||
|
gcErrLog = lcLog
|
||||||
|
gcTestLog = lcLog
|
||||||
|
gnPass = 0
|
||||||
|
gnFail = 0
|
||||||
|
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
PUBLIC gnIdVanzareTest
|
||||||
|
gnIdVanzareTest = 1049
|
||||||
|
|
||||||
|
DO test_al_doilea_intrare WITH gnIdVanzareTest, lcLog
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + 'REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
QUIT
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE asserteaza
|
||||||
|
LPARAMETERS tcNume, tlConditie, tcValoare
|
||||||
|
|
||||||
|
IF m.tlConditie
|
||||||
|
gnPass = gnPass + 1
|
||||||
|
STRTOFILE('PASS ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ELSE
|
||||||
|
gnFail = gnFail + 1
|
||||||
|
STRTOFILE('FAIL ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- executa SELECT-ul prin goExecutor (cai care CITESC - fara risc) si intoarce codul de succes
|
||||||
|
PROCEDURE ExecSel
|
||||||
|
LPARAMETERS tcSql, tcCursor
|
||||||
|
LOCAL lnQ
|
||||||
|
IF USED(tcCursor)
|
||||||
|
USE IN (tcCursor)
|
||||||
|
ENDIF
|
||||||
|
lnQ = goExecutor.oExecute(tcSql, tcCursor)
|
||||||
|
RETURN lnQ
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- reproduce _frm_base.vc2:252-265 (do_deschide_tranzactie / Thisform.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 / Thisform.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_al_doilea_intrare
|
||||||
|
LPARAMETERS tnIdVanzare, tcLog
|
||||||
|
|
||||||
|
*-- pnAn/pnLuna/lnCod/lnIdFact/lnIdfactd/lnIdSet/pdDataOra PRIVATE - finalizeaza_modificare_nota
|
||||||
|
*-- foloseste ?pnLuna/?pnAn/?pdDataOra ca bind-variabile in josul stivei (comun.vc2:2487-2488)
|
||||||
|
PRIVATE pnAn, pnLuna, lnCod, lnIdFact, lnIdfactd, lnIdSet, pdDataOra
|
||||||
|
LOCAL lcSql, lnQ, lnSters, llEProforma, llSters, llGestInvantar, llRul, lnSucces
|
||||||
|
LOCAL lnCodInainte, lnCodDupa, lnDiscInainte, lnFtvaInainte, lnTvaInainte, lnCtvaInainte
|
||||||
|
LOCAL lnDiscDupa, lnFtvaDupa, lnTvaDupa, lnCtvaDupa, lnNrLiniiInainte, lnNrLiniiDupa
|
||||||
|
LOCAL llBlocExecutat
|
||||||
|
llBlocExecutat = .F.
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + '========== al doilea punct de intrare (afisjurcom.do_modifica, comun.vc2:2222-2569), ' + ;
|
||||||
|
'id_vanzare=' + TRANSFORM(tnIdVanzare) + ' ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
*-- starea documentului INAINTE, citita direct din VANZARI (echivalentul "cod-ul se realoca la fiecare salvare")
|
||||||
|
lcSql = [select cod, nvl(sters,0) as sters, discount, total_fara_tva, total_tva, total_cu_tva, ] + ;
|
||||||
|
[extract(year from data_act) as anact, extract(month from data_act) as lunaact ] + ;
|
||||||
|
[from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_vz0')
|
||||||
|
IF lnQ <= 0 OR RECCOUNT('v_vz0') <> 1
|
||||||
|
DO asserteaza WITH '0: VANZARI citit', .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
SELECT v_vz0
|
||||||
|
lnCod = cod
|
||||||
|
lnCodInainte = cod
|
||||||
|
lnDiscInainte = NVL(discount, 0)
|
||||||
|
lnFtvaInainte = total_fara_tva
|
||||||
|
lnTvaInainte = total_tva
|
||||||
|
lnCtvaInainte = total_cu_tva
|
||||||
|
USE IN v_vz0
|
||||||
|
|
||||||
|
lcSql = [select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ and sters = 0]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_cnt0')
|
||||||
|
lnNrLiniiInainte = IIF(lnQ > 0, v_cnt0.nr, -1)
|
||||||
|
USE IN v_cnt0
|
||||||
|
|
||||||
|
STRTOFILE(' VANZARI inainte: cod=' + TRANSFORM(lnCodInainte) + ' discount=' + TRANSFORM(lnDiscInainte) + ;
|
||||||
|
' ftva=' + TRANSFORM(lnFtvaInainte) + ' tva=' + TRANSFORM(lnTvaInainte) + ' ctva=' + TRANSFORM(lnCtvaInainte) + ;
|
||||||
|
' linii active=' + TRANSFORM(lnNrLiniiInainte) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
*-- 1) "Select actjur" (comun.vc2:2253-2263) - un rand din vact_tot, exact ca gridul registrului jurnal
|
||||||
|
lcSql = [select cod, an, luna, id_set, sters, id_fact, id_factd, dataora from vact_tot ] + ;
|
||||||
|
[where cod = ] + TRANSFORM(lnCod) + [ and rownum = 1]
|
||||||
|
lnQ = ExecSel(lcSql, 'actjur')
|
||||||
|
IF lnQ <= 0 OR RECCOUNT('actjur') <> 1
|
||||||
|
DO asserteaza WITH '1: actjur (randul din registrul jurnal) gasit pentru cod=' + TRANSFORM(lnCod), .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
SELECT actjur
|
||||||
|
pnAn = an
|
||||||
|
pnLuna = luna
|
||||||
|
lnIdSet = id_set
|
||||||
|
lnSters = sters
|
||||||
|
lnIdFact = id_fact
|
||||||
|
lnIdfactd = id_factd
|
||||||
|
pdDataOra = NULL
|
||||||
|
STRTOFILE(' actjur: cod=' + TRANSFORM(lnCod) + ' an/luna=' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ;
|
||||||
|
' id_set=' + TRANSFORM(lnIdSet) + ' sters=' + TRANSFORM(lnSters) + ' id_fact=' + TRANSFORM(lnIdFact) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
*-- 2) garzile din do_modifica (comun.vc2:2265-2290), fara UI
|
||||||
|
DO asserteaza WITH '2: nota din luna curenta (garda comun.vc2:2265)', (pnAn * 12) + pnLuna = (gnAn * 12) + gnLuna, ;
|
||||||
|
TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ' vs curent ' + TRANSFORM(gnAn) + '/' + TRANSFORM(gnLuna)
|
||||||
|
IF (pnAn * 12) + pnLuna <> (gnAn * 12) + gnLuna
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO asserteaza WITH '3: id_set NU e in intervalul ROAPRODUCTIE (30000-30009, comun.vc2:2278)', !BETWEEN(lnIdSet, 30000, 30009), TRANSFORM(lnIdSet)
|
||||||
|
IF BETWEEN(lnIdSet, 30000, 30009)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
llSters = (lnSters = 1)
|
||||||
|
DO asserteaza WITH '4: nota nu e deja stearsa (llSters=.F.)', !llSters, TRANSFORM(lnSters)
|
||||||
|
llGestInvantar = (lnIdSet = 90101)
|
||||||
|
DO asserteaza WITH '5: nu e nota de inventariere (id_set<>90101, ramura pdDataOra=actjur.dataora nu se activeaza)', !llGestInvantar, TRANSFORM(lnIdSet)
|
||||||
|
IF llGestInvantar
|
||||||
|
pdDataOra = actjur.dataora
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 3) cursoarele notei (actactan/tact/trul/trul_obinv) - identic cu comun.vc2:2313-2427,
|
||||||
|
*-- deja extras ca helper si folosit de test_s5_scriere_reala.prg pe aceeasi nota
|
||||||
|
IF !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.)
|
||||||
|
DO asserteaza WITH '6: IncarcaCursoareModificareNota', .F., 'a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO asserteaza WITH '6: nota are randuri in actactan/tact', RECCOUNT('actactan') > 0, TRANSFORM(RECCOUNT('actactan'))
|
||||||
|
IF RECCOUNT('actactan') = 0
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 4) cu_Tva pe tact - a doua reasignare, comun.vc2:2433 (identica cu ofacturare_comun.vc2/test_s5_scriere_reala.prg)
|
||||||
|
SELECT a.*, IIF(NVL(id_jtva_coloana, 0) = 0, 0, 1) AS cu_Tva FROM tact a INTO CURSOR tact READWRITE
|
||||||
|
|
||||||
|
*-- 5) PregatesteArticoleFacturaEditare('tact') - comun.vc2:2436, DIFERENTA functionala fata de
|
||||||
|
*-- ofacturare_comun.vc2/do_editare_factura (care apeleaza IncarcaVanzareDinNota direct); aici
|
||||||
|
*-- populeaza tvanz SI crsArticoleFactura, calea specifica acestui punct de intrare
|
||||||
|
IF USED('tvanz')
|
||||||
|
USE IN tvanz
|
||||||
|
ENDIF
|
||||||
|
IF USED('crsArticoleFactura')
|
||||||
|
USE IN crsArticoleFactura
|
||||||
|
ENDIF
|
||||||
|
LOCAL llGasitTvanz
|
||||||
|
llGasitTvanz = PregatesteArticoleFacturaEditare('tact')
|
||||||
|
DO asserteaza WITH '7: PregatesteArticoleFacturaEditare gaseste documentul in VANZARI (calea specifica acestui punct de intrare)', ;
|
||||||
|
llGasitTvanz, TRANSFORM(llGasitTvanz)
|
||||||
|
DO asserteaza WITH '8: garda noua satisfacuta REAL (nu static): Used(tvanz) And Reccount(tvanz)=1', ;
|
||||||
|
USED('tvanz') AND RECCOUNT('tvanz') = 1, 'Used=' + TRANSFORM(USED('tvanz')) + ' Reccount=' + IIF(USED('tvanz'), TRANSFORM(RECCOUNT('tvanz')), '-')
|
||||||
|
DO asserteaza WITH '9: tvanz.id_vanzare corect (populat de PregatesteArticoleFacturaEditare, nu presupus)', ;
|
||||||
|
USED('tvanz') AND RECCOUNT('tvanz') = 1 AND tvanz.id_vanzare = tnIdVanzare, ;
|
||||||
|
IIF(USED('tvanz') AND RECCOUNT('tvanz') = 1, TRANSFORM(tvanz.id_vanzare), 'tvanz gol')
|
||||||
|
DO asserteaza WITH '10: crsArticoleFactura precarcat (acelasi apel)', USED('crsArticoleFactura'), TRANSFORM(USED('crsArticoleFactura'))
|
||||||
|
|
||||||
|
*-- frm_modific2024 SARIT (nu se instantiaza - risc de UI blocanta headless, verificare vizuala
|
||||||
|
*-- ramane la Marius, per briefing); buton=1 fortat direct, ca in celelalte suite S5. In fluxul
|
||||||
|
*-- real, Load()-ul formularului populeaza 'tvd' din crsArticoleFactura - reprodus aici explicit,
|
||||||
|
*-- FARA nicio modificare, ca ScrieArticoleFacturaEditate sa nu fie no-op (vezi ATENTIE din antet)
|
||||||
|
IF USED('tvd')
|
||||||
|
USE IN tvd
|
||||||
|
ENDIF
|
||||||
|
IncarcaArticoleFactura(tnIdVanzare, 'tvd')
|
||||||
|
DO asserteaza WITH '10b: tvd incarcat cu liniile active reale (ca Load()-ul lui frm_modific2024)', ;
|
||||||
|
USED('tvd') AND RECCOUNT('tvd') = lnNrLiniiInainte, 'Reccount=' + IIF(USED('tvd'), TRANSFORM(RECCOUNT('tvd')), '-') + ' asteptat=' + TRANSFORM(lnNrLiniiInainte)
|
||||||
|
|
||||||
|
*-- 6) ramura buton=1 (comun.vc2:2447-2493), copiata identic; llRul=.T. neconditionat (:2449,
|
||||||
|
*-- "este posibil sa modific si rul, rul_obinv" - asa cum scrie codul, nu dupa Reccount(trul))
|
||||||
|
llRul = .T.
|
||||||
|
lnSucces = 0
|
||||||
|
TRY
|
||||||
|
IF MyDeschideTranzactie()
|
||||||
|
SELECT actactan
|
||||||
|
IF !llSters
|
||||||
|
lnSucces = OSCRIE_IN_FISIERE(2, .T., llRul)
|
||||||
|
ELSE
|
||||||
|
lnSucces = 1
|
||||||
|
ENDIF
|
||||||
|
STRTOFILE(' OSCRIE_IN_FISIERE(2,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
IF lnSucces > 0
|
||||||
|
IF USED('actactan')
|
||||||
|
USE IN actactan
|
||||||
|
ENDIF
|
||||||
|
SELECT tact
|
||||||
|
IF gnAn >= IIF(TYPE('gnAnFormNou') = 'U', 2007, gnAnFormNou)
|
||||||
|
REPLACE id_jtva_coloana WITH NULL, proc_tva WITH 0 FOR cu_Tva = 0
|
||||||
|
ENDIF
|
||||||
|
SELECT * FROM tact INTO CURSOR actactan READWRITE
|
||||||
|
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
|
||||||
|
IF llRul
|
||||||
|
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
|
||||||
|
ENDIF
|
||||||
|
lnSucces = OSCRIE_IN_FISIERE(0, .T., llRul)
|
||||||
|
STRTOFILE(' OSCRIE_IN_FISIERE(0,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF lnSucces > 0
|
||||||
|
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,?pdDataOra,] + ALLTRIM(STR(lnIdSet)) + [,] + ;
|
||||||
|
ALLTRIM(STR(lnCod)) + [,] + ALLTRIM(STR(lnIdFact)) + [,] + ALLTRIM(STR(lnIdfactd)) + [,?gnIdUtil); end;]
|
||||||
|
lnSucces = IIF(goExecutor.oExecuta(lcSql), 1, -1)
|
||||||
|
STRTOFILE(' finalizeaza_modificare_nota => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
DO asserteaza WITH '11: lantul pana la finalizeaza_modificare_nota a reusit (lnSucces>0)', lnSucces > 0, 'lnSucces=' + TRANSFORM(lnSucces)
|
||||||
|
|
||||||
|
*-- blocul nou, comun.vc2:2491-2493, identic textual cu ofacturare_comun.vc2:3828-3830
|
||||||
|
IF lnSucces > 0 AND "OFACTURARE_EDITARE" $ UPPER(SET("Procedure")) AND USED('tvanz') AND RECCOUNT('tvanz') = 1
|
||||||
|
llBlocExecutat = .T.
|
||||||
|
lnSucces = IIF(ScrieArticoleFacturaEditate(tvanz.id_vanzare, 'tvd', 'tvanz'), 1, -1)
|
||||||
|
STRTOFILE(' ScrieArticoleFacturaEditate => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' ATENTIE: blocul ScrieArticoleFacturaEditate NU s-a executat' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- comun.vc2:2541 - Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,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 inchiderea tranzactiei' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' FAIL: deschiderea tranzactiei 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
|
||||||
|
|
||||||
|
DO asserteaza WITH '12: blocul ScrieArticoleFacturaEditate S-A EXECUTAT pe aceasta cale (garda satisfacuta)', ;
|
||||||
|
llBlocExecutat, TRANSFORM(llBlocExecutat)
|
||||||
|
DO asserteaza WITH '13: lantul complet (inclusiv ScrieArticoleFacturaEditate prin acest punct de intrare) a reusit', ;
|
||||||
|
lnSucces > 0, 'lnSucces=' + TRANSFORM(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
|
||||||
|
IF USED('crsArticoleFactura')
|
||||||
|
USE IN crsArticoleFactura
|
||||||
|
ENDIF
|
||||||
|
IF USED('tvd')
|
||||||
|
USE IN tvd
|
||||||
|
ENDIF
|
||||||
|
IF USED('tvanz')
|
||||||
|
USE IN tvanz
|
||||||
|
ENDIF
|
||||||
|
IF USED('actjur')
|
||||||
|
USE IN actjur
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- verificare de fond: lantul a COMIS (lnSucces>0) - COD-ul se realoca (ca in blocul C din
|
||||||
|
*-- test_s5_discount_valuta.prg), dar continutul liniilor si totalurile raman identice, pentru ca
|
||||||
|
*-- 'tvd' a fost incarcat fara nicio modificare (vezi ATENTIE din antet)
|
||||||
|
lcSql = [select cod, nvl(discount,0) as discount, total_fara_tva, total_tva, total_cu_tva from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_vz1')
|
||||||
|
IF lnQ > 0 AND RECCOUNT('v_vz1') = 1
|
||||||
|
lnCodDupa = v_vz1.cod
|
||||||
|
lnDiscDupa = v_vz1.discount
|
||||||
|
lnFtvaDupa = v_vz1.total_fara_tva
|
||||||
|
lnTvaDupa = v_vz1.total_tva
|
||||||
|
lnCtvaDupa = v_vz1.total_cu_tva
|
||||||
|
ENDIF
|
||||||
|
USE IN v_vz1
|
||||||
|
lcSql = [select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ and sters = 0]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_cnt1')
|
||||||
|
lnNrLiniiDupa = IIF(lnQ > 0, v_cnt1.nr, -1)
|
||||||
|
USE IN v_cnt1
|
||||||
|
|
||||||
|
STRTOFILE(' DUPA COMMIT: cod=' + TRANSFORM(lnCodDupa) + ' (era ' + TRANSFORM(lnCodInainte) + ') discount=' + TRANSFORM(lnDiscDupa) + ;
|
||||||
|
' ftva=' + TRANSFORM(lnFtvaDupa) + ' tva=' + TRANSFORM(lnTvaDupa) + ' ctva=' + TRANSFORM(lnCtvaDupa) + ;
|
||||||
|
' linii active=' + TRANSFORM(lnNrLiniiDupa) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
DO asserteaza WITH '14: COD s-a realocat la salvare (ca la orice trecere prin finalizeaza_modificare_nota, chiar fara modificari)', ;
|
||||||
|
lnCodDupa <> lnCodInainte, TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(lnCodDupa)
|
||||||
|
DO asserteaza WITH '15: discount/totalurile raman neschimbate (nicio modificare in tvd)', ;
|
||||||
|
ABS(lnDiscDupa - lnDiscInainte) < 0.0001 AND ABS(lnFtvaDupa - lnFtvaInainte) < 0.0001 ;
|
||||||
|
AND ABS(lnTvaDupa - lnTvaInainte) < 0.0001 AND ABS(lnCtvaDupa - lnCtvaInainte) < 0.0001, ;
|
||||||
|
'disc=' + TRANSFORM(lnDiscDupa) + ' ftva=' + TRANSFORM(lnFtvaDupa) + ' tva=' + TRANSFORM(lnTvaDupa) + ' ctva=' + TRANSFORM(lnCtvaDupa)
|
||||||
|
DO asserteaza WITH '16: numarul de linii active ramane neschimbat (idempotent, ca la reeditare fara modificari)', ;
|
||||||
|
lnNrLiniiDupa = lnNrLiniiInainte, 'dupa=' + TRANSFORM(lnNrLiniiDupa) + ' inainte=' + TRANSFORM(lnNrLiniiInainte)
|
||||||
|
|
||||||
|
*-- verificarea CRITICA: linia definitiv stearsa in testele anterioare (det=1582) trebuie sa
|
||||||
|
*-- RAMANA stearsa - exact reset-ul pe care ScrieArticoleFacturaEditate trebuie sa-l corecteze
|
||||||
|
LOCAL lnStersLiniaVecheStearsa
|
||||||
|
lcSql = [select nvl(sters,0) as sters from vanzari_detalii where id_vanzare_det = 1582]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_1582')
|
||||||
|
lnStersLiniaVecheStearsa = IIF(lnQ > 0 AND RECCOUNT('v_1582') = 1, v_1582.sters, -1)
|
||||||
|
USE IN v_1582
|
||||||
|
DO asserteaza WITH '17: linia definitiv stearsa in testele anterioare (det=1582) a ramas stearsa dupa aceasta salvare', ;
|
||||||
|
lnStersLiniaVecheStearsa = 1, 'sters=' + TRANSFORM(lnStersLiniaVecheStearsa)
|
||||||
|
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
|
||||||
816
utile/Teste/editare_factura/test_s5_discount_valuta.prg
Normal file
816
utile/Teste/editare_factura/test_s5_discount_valuta.prg
Normal file
@@ -0,0 +1,816 @@
|
|||||||
|
* test_s5_discount_valuta.prg
|
||||||
|
* Inchide cele doua goluri declarate de test_s5_scriere_reala: parametrul de discount al procedurii
|
||||||
|
* pack_facturare.recalculeaza_totaluri_vanzari (decizia 41) si documentele in valuta.
|
||||||
|
*
|
||||||
|
* Contractul verificat: recalculeaza_totaluri_vanzari(V_ID_VANZARE, V_DISCOUNT DEFAULT NULL), cu
|
||||||
|
* NULL = "pastreaza valoarea curenta". Cazul periculos e al doilea: daca NULL ar zeroa tacit
|
||||||
|
* discountul, orice salvare ulterioara a documentului l-ar sterge.
|
||||||
|
*
|
||||||
|
* BLOCUL A - contractul pe un document in RON (id_vanzare = 1049, in_valuta = 0). Patru apeluri
|
||||||
|
* succesive in aceeasi tranzactie, cu citirea starii necomise intre ele:
|
||||||
|
* NULL pe discount 0 -> recalculul reproduce exact starea persistata (idempotent)
|
||||||
|
* valoare nenula -> ajunge in VANZARI.DISCOUNT si scade totalurile
|
||||||
|
* NULL peste ea -> VERDICTUL: pastreaza sau zeroeaza
|
||||||
|
* 0 -> readuce documentul la starea de plecare
|
||||||
|
* Tranzactia se inchide cu ROLLBACK, deci blocul NU consuma date.
|
||||||
|
*
|
||||||
|
* BLOCUL B - acelasi contract pe un document REAL in valuta (id_vanzare = 1037, in_valuta = 1,
|
||||||
|
* id_valuta = 2, curs = 5.2688, cu rand in VANZARI_CURSURI). Aici se exercita ramura
|
||||||
|
* decode(in_valuta, 1, ROUND(curs * discount / multiplicator, PPRETV), discount) din procedura -
|
||||||
|
* discountul e exprimat in valuta si se converteste la RON prin cursul documentului. Se verifica
|
||||||
|
* si perechea valval/tvaval/totval. Documentul e din 05.2026 (arhiva), deci tranzactia se inchide
|
||||||
|
* obligatoriu cu ROLLBACK: nimic nu se modifica in el.
|
||||||
|
*
|
||||||
|
* BLOCUL C - lantul real de salvare pe un document cu discount NENUL (id_vanzare = 1049). Singurul
|
||||||
|
* bloc care scrie: pune discountul prin procedura (COMMIT), ruleaza lantul complet de editare fara
|
||||||
|
* nicio modificare de linii (COMMIT) si verifica ca discountul supravietuieste salvarii - adica
|
||||||
|
* tvanz.discount (citit din VANZARI de IncarcaVanzareNota) ajunge inapoi in procedura prin
|
||||||
|
* ScrieArticoleFacturaEditate. La final restaureaza discount = 0 si totalurile initiale (COMMIT).
|
||||||
|
* CONSUMA UN COD: VANZARI.COD se realoca la salvare.
|
||||||
|
*
|
||||||
|
* Harness identic cu test_s5_scriere_reala.prg: frm_modific2024 ocolit, buton = 1 fortat,
|
||||||
|
* do_deschide/inchide_tranzactie reproduse inline dupa _frm_base.vc2:252-302. Nu atinge cod de
|
||||||
|
* aplicatie, nu modifica PACK_FACTURARE. QUIT la final.
|
||||||
|
|
||||||
|
SET SAFETY OFF
|
||||||
|
SET TALK OFF
|
||||||
|
|
||||||
|
LOCAL lcLog
|
||||||
|
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s5_discount_valuta_log.txt'
|
||||||
|
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
|
||||||
|
|
||||||
|
PUBLIC gcErrLog, gcTestLog, gnPass, gnFail
|
||||||
|
gcErrLog = lcLog
|
||||||
|
gcTestLog = lcLog
|
||||||
|
gnPass = 0
|
||||||
|
gnFail = 0
|
||||||
|
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||||
|
|
||||||
|
*-- mock amessagebox incarcat PRIMUL, inaintea lantului real (la nume duplicat castiga primul gasit)
|
||||||
|
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
|
||||||
|
|
||||||
|
LOCAL lnVerifMock
|
||||||
|
lnVerifMock = amessagebox('verificare mock', 4+32, 'test')
|
||||||
|
STRTOFILE('verificare mock amessagebox = ' + TRANSFORM(lnVerifMock) + ;
|
||||||
|
IIF(lnVerifMock = 6, ' (OK, mock activ)', ' (ATENTIE: amessagebox real, 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
|
||||||
|
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\odocumente.prg ADDITIVE
|
||||||
|
|
||||||
|
IF TYPE('gnPC') <> 'N'
|
||||||
|
PUBLIC gnPC
|
||||||
|
gnPC = 2
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
PUBLIC gcMockUltimMesaj, gnMockUltimTip
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
gnMockUltimTip = 0
|
||||||
|
|
||||||
|
*-- documentele de test si valorile de discount folosite
|
||||||
|
PUBLIC gnIdRon, gnIdValuta, gnDiscRon, gnDiscValuta, gnPPretV
|
||||||
|
gnIdRon = 1049
|
||||||
|
gnIdValuta = 1037
|
||||||
|
gnDiscRon = 12.5
|
||||||
|
gnDiscValuta = 10
|
||||||
|
gnPPretV = 2
|
||||||
|
|
||||||
|
*-- capul documentului citit de CitesteCap
|
||||||
|
PUBLIC gnCapCod, gnCapSters, gnCapInValuta, gnCapDisc, gnCapDiscNul, gnCapDiscTva
|
||||||
|
PUBLIC gnCapVA, gnCapFtva, gnCapTva, gnCapCtva, gnCapValval, gnCapTvaval, gnCapTotval
|
||||||
|
PUBLIC gnCapIdValuta, gnCapCurs, gnCapMult
|
||||||
|
|
||||||
|
STRTOFILE('gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + ' gnIdUtil=' + TRANSFORM(gnIdUtil) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
|
||||||
|
*-- precizia de pret in valuta, din optiunile firmei - intra in formula de conversie a discountului
|
||||||
|
IF ExecSel([select to_number(pack_sesiune.getOptiuneFirma('PPRETV')) as ppretv from dual], 'v_opt') > 0
|
||||||
|
gnPPretV = NVL(v_opt.ppretv, 2)
|
||||||
|
USE IN v_opt
|
||||||
|
ENDIF
|
||||||
|
STRTOFILE('PPRETV = ' + TRANSFORM(gnPPretV) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
|
||||||
|
DO bloc_a_discount_ron WITH lcLog
|
||||||
|
DO bloc_b_valuta WITH lcLog
|
||||||
|
DO bloc_c_lant_real WITH lcLog
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + 'REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
QUIT
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE asserteaza
|
||||||
|
LPARAMETERS tcNume, tlConditie, tcValoare
|
||||||
|
|
||||||
|
IF m.tlConditie
|
||||||
|
gnPass = gnPass + 1
|
||||||
|
STRTOFILE('PASS ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ELSE
|
||||||
|
gnFail = gnFail + 1
|
||||||
|
STRTOFILE('FAIL ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- executa SELECT-ul prin goExecutor si intoarce codul de succes; cursorul vechi se inchide intai
|
||||||
|
PROCEDURE ExecSel
|
||||||
|
LPARAMETERS tcSql, tcCursor
|
||||||
|
LOCAL lnQ
|
||||||
|
IF USED(tcCursor)
|
||||||
|
USE IN (tcCursor)
|
||||||
|
ENDIF
|
||||||
|
lnQ = goExecutor.oExecute(tcSql, tcCursor)
|
||||||
|
RETURN lnQ
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- citeste capul documentului in variabilele gnCap*; citirea merge pe aceeasi conexiune, deci vede
|
||||||
|
*-- si starea necomisa din interiorul tranzactiei. Intoarce .F. daca randul nu exista.
|
||||||
|
PROCEDURE CitesteCap
|
||||||
|
LPARAMETERS tnId
|
||||||
|
LOCAL lcSql, lnQ
|
||||||
|
lcSql = [select cod, nvl(sters,0) as sters, nvl(in_valuta,0) as in_valuta, ] + ;
|
||||||
|
[nvl(discount,0) as discount, nvl2(discount,0,1) as disc_nul, nvl(discount_tva,0) as discount_tva, ] + ;
|
||||||
|
[nvl(valoare_achizitie,0) as valoare_achizitie, nvl(total_fara_tva,0) as total_fara_tva, ] + ;
|
||||||
|
[nvl(total_tva,0) as total_tva, nvl(total_cu_tva,0) as total_cu_tva, ] + ;
|
||||||
|
[nvl(valval,0) as valval, nvl(tvaval,0) as tvaval, nvl(totval,0) as totval, ] + ;
|
||||||
|
[nvl(id_valuta,0) as id_valuta, nvl(curs,0) as curs, nvl(multiplicator,0) as multiplicator ] + ;
|
||||||
|
[from vanzari where id_vanzare = ] + TRANSFORM(tnId)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_cap')
|
||||||
|
IF lnQ <= 0 OR RECCOUNT('v_cap') <> 1
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
SELECT v_cap
|
||||||
|
gnCapCod = cod
|
||||||
|
gnCapSters = sters
|
||||||
|
gnCapInValuta = in_valuta
|
||||||
|
gnCapDisc = discount
|
||||||
|
gnCapDiscNul = disc_nul
|
||||||
|
gnCapDiscTva = discount_tva
|
||||||
|
gnCapVA = valoare_achizitie
|
||||||
|
gnCapFtva = total_fara_tva
|
||||||
|
gnCapTva = total_tva
|
||||||
|
gnCapCtva = total_cu_tva
|
||||||
|
gnCapValval = valval
|
||||||
|
gnCapTvaval = tvaval
|
||||||
|
gnCapTotval = totval
|
||||||
|
gnCapIdValuta = id_valuta
|
||||||
|
gnCapCurs = curs
|
||||||
|
gnCapMult = multiplicator
|
||||||
|
USE IN v_cap
|
||||||
|
RETURN .T.
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE LogCap
|
||||||
|
LPARAMETERS tcEticheta, tcLog
|
||||||
|
STRTOFILE(' [' + tcEticheta + '] cod=' + TRANSFORM(gnCapCod) + ' in_valuta=' + TRANSFORM(gnCapInValuta) + ;
|
||||||
|
' discount=' + TRANSFORM(gnCapDisc) + IIF(gnCapDiscNul = 1, ' (NULL in baza)', '') + ;
|
||||||
|
' discount_tva=' + TRANSFORM(gnCapDiscTva) + ' val_ach=' + TRANSFORM(gnCapVA) + CHR(13) + CHR(10) + ;
|
||||||
|
' ftva=' + TRANSFORM(gnCapFtva) + ' tva=' + TRANSFORM(gnCapTva) + ' ctva=' + TRANSFORM(gnCapCtva) + ;
|
||||||
|
' | valval=' + TRANSFORM(gnCapValval) + ' tvaval=' + TRANSFORM(gnCapTvaval) + ' totval=' + TRANSFORM(gnCapTotval) + ;
|
||||||
|
' | id_valuta=' + TRANSFORM(gnCapIdValuta) + ' curs=' + TRANSFORM(gnCapCurs) + ' mult=' + TRANSFORM(gnCapMult) + ;
|
||||||
|
CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- apeleaza procedura de recalcul; tcDiscount e literalul SQL ('NULL' sau o valoare)
|
||||||
|
PROCEDURE ApelRecalc
|
||||||
|
LPARAMETERS tnId, tcDiscount, tcLog
|
||||||
|
LOCAL lcSql, llOk
|
||||||
|
lcSql = [begin pack_facturare.recalculeaza_totaluri_vanzari(] + ALLTRIM(STR(tnId)) + [,] + tcDiscount + [); end;]
|
||||||
|
llOk = goExecutor.oExecuta(lcSql)
|
||||||
|
STRTOFILE(' APEL ' + lcSql + ' => ' + IIF(llOk, 'OK', 'ESEC [' + ALLTRIM(TRANSFORM(NVL(goExecutor.cEroare, ''))) + ']') + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
RETURN llOk
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- cota de TVA maxima de pe liniile active - intra in formula discountului de TVA din procedura
|
||||||
|
PROCEDURE CotaMaxima
|
||||||
|
LPARAMETERS tnId
|
||||||
|
LOCAL lcSql, lnQ, lnRez
|
||||||
|
lnRez = 0
|
||||||
|
lcSql = [select nvl(max(proc_tvav),0) as tvavmax from vanzari_detalii where id_vanzare = ] + ;
|
||||||
|
TRANSFORM(tnId) + [ and sters = 0]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_tvav')
|
||||||
|
IF lnQ > 0 AND RECCOUNT('v_tvav') = 1
|
||||||
|
lnRez = v_tvav.tvavmax
|
||||||
|
ENDIF
|
||||||
|
IF USED('v_tvav')
|
||||||
|
USE IN v_tvav
|
||||||
|
ENDIF
|
||||||
|
RETURN lnRez
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
*=====================================================================================
|
||||||
|
*-- BLOCUL A: contractul parametrului de discount, pe document in RON, cu ROLLBACK la final
|
||||||
|
*=====================================================================================
|
||||||
|
PROCEDURE bloc_a_discount_ron
|
||||||
|
LPARAMETERS tcLog
|
||||||
|
|
||||||
|
LOCAL lnBaseDisc, lnBaseDiscTva, lnBaseVA, lnBaseFtva, lnBaseTva, lnBaseCtva
|
||||||
|
LOCAL lnP1Disc, lnP1Ftva, lnP1Tva, lnP1Ctva, lnP1DiscTva, lnP1VA
|
||||||
|
LOCAL lnTvavMax, lnAstFtva, lnAstDiscTva, llOk, lcEt
|
||||||
|
|
||||||
|
lcEt = 'A'
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + '========== BLOCUL A - contractul de discount pe document in RON (id_vanzare=' + ;
|
||||||
|
TRANSFORM(gnIdRon) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
IF !CitesteCap(gnIdRon)
|
||||||
|
DO asserteaza WITH lcEt + ': documentul in RON exista', .F., 'id_vanzare=' + TRANSFORM(gnIdRon)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'STARE INITIALA', tcLog
|
||||||
|
|
||||||
|
IF gnCapInValuta <> 0
|
||||||
|
DO asserteaza WITH lcEt + ': documentul ales e in RON (in_valuta=0)', .F., TRANSFORM(gnCapInValuta)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
lnBaseDisc = gnCapDisc
|
||||||
|
lnBaseDiscTva = gnCapDiscTva
|
||||||
|
lnBaseVA = gnCapVA
|
||||||
|
lnBaseFtva = gnCapFtva
|
||||||
|
lnBaseTva = gnCapTva
|
||||||
|
lnBaseCtva = gnCapCtva
|
||||||
|
|
||||||
|
lnTvavMax = CotaMaxima(gnIdRon)
|
||||||
|
STRTOFILE(' cota TVA maxima pe liniile active = ' + TRANSFORM(lnTvavMax) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
IF !MyDeschideTranzactie()
|
||||||
|
DO asserteaza WITH lcEt + ': tranzactia s-a deschis', .F., 'SQLSetprop a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
TRY
|
||||||
|
*-- PASUL 1: NULL peste discountul curent (0) - recalculul trebuie sa reproduca exact starea
|
||||||
|
llOk = ApelRecalc(gnIdRon, 'NULL', tcLog)
|
||||||
|
DO asserteaza WITH lcEt + '1: apelul cu NULL a mers', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
IF llOk AND CitesteCap(gnIdRon)
|
||||||
|
DO LogCap WITH 'dupa recalc(NULL) pe discount 0', tcLog
|
||||||
|
DO asserteaza WITH lcEt + '1: recalculul reproduce exact totalurile persistate (idempotent)', ;
|
||||||
|
ABS(gnCapFtva - lnBaseFtva) < 0.005 AND ABS(gnCapTva - lnBaseTva) < 0.005 ;
|
||||||
|
AND ABS(gnCapCtva - lnBaseCtva) < 0.005 AND ABS(gnCapVA - lnBaseVA) < 0.005, ;
|
||||||
|
'ftva ' + TRANSFORM(lnBaseFtva) + '->' + TRANSFORM(gnCapFtva) + ' tva ' + TRANSFORM(lnBaseTva) + ;
|
||||||
|
'->' + TRANSFORM(gnCapTva) + ' ctva ' + TRANSFORM(lnBaseCtva) + '->' + TRANSFORM(gnCapCtva)
|
||||||
|
DO asserteaza WITH lcEt + '1: NULL nu schimba discountul (0 ramane 0)', ;
|
||||||
|
ABS(gnCapDisc - lnBaseDisc) < 0.0001, TRANSFORM(lnBaseDisc) + ' -> ' + TRANSFORM(gnCapDisc)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- PASUL 2: valoare nenula - trebuie sa ajunga in VANZARI.DISCOUNT si sa scada totalurile.
|
||||||
|
*-- pe document in RON procedura ia discountul ca atare (decode(in_valuta,1,...,discount))
|
||||||
|
lnAstFtva = lnBaseFtva - gnDiscRon
|
||||||
|
lnAstDiscTva = ROUND(gnDiscRon * (lnTvavMax - 1), gnPPretV)
|
||||||
|
llOk = ApelRecalc(gnIdRon, ALLTRIM(STR(gnDiscRon, 18, 4)), tcLog)
|
||||||
|
DO asserteaza WITH lcEt + '2: apelul cu valoare nenula a mers', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
IF !llOk OR !CitesteCap(gnIdRon)
|
||||||
|
MyInchideTranzactie(2)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'dupa recalc(' + TRANSFORM(gnDiscRon) + ')', tcLog
|
||||||
|
|
||||||
|
DO asserteaza WITH lcEt + '2: valoarea nenula ajunge in VANZARI.DISCOUNT', ;
|
||||||
|
ABS(gnCapDisc - gnDiscRon) < 0.0001, 'discount=' + TRANSFORM(gnCapDisc) + ' (cerut ' + TRANSFORM(gnDiscRon) + ')'
|
||||||
|
DO asserteaza WITH lcEt + '2: total_fara_tva scade exact cu discountul', ;
|
||||||
|
ABS(gnCapFtva - lnAstFtva) < 0.005, 'ftva=' + TRANSFORM(gnCapFtva) + ' asteptat ' + TRANSFORM(lnAstFtva)
|
||||||
|
DO asserteaza WITH lcEt + '2: DISCOUNT_TVA = discount * (cota - 1), rotunjit', ;
|
||||||
|
ABS(gnCapDiscTva - lnAstDiscTva) < 0.011, 'discount_tva=' + TRANSFORM(gnCapDiscTva) + ' asteptat ' + TRANSFORM(lnAstDiscTva)
|
||||||
|
DO asserteaza WITH lcEt + '2: total_tva scade cu TVA-ul discountului', ;
|
||||||
|
ABS(gnCapTva - (lnBaseTva - lnAstDiscTva)) < 0.011, ;
|
||||||
|
'tva=' + TRANSFORM(gnCapTva) + ' asteptat ' + TRANSFORM(lnBaseTva - lnAstDiscTva)
|
||||||
|
DO asserteaza WITH lcEt + '2: totalurile raman coerente (fara_tva + tva = cu_tva)', ;
|
||||||
|
ABS((gnCapFtva + gnCapTva) - gnCapCtva) < 0.01, ;
|
||||||
|
TRANSFORM(gnCapFtva) + ' + ' + TRANSFORM(gnCapTva) + ' = ' + TRANSFORM(gnCapCtva)
|
||||||
|
DO asserteaza WITH lcEt + '2: VALOARE_ACHIZITIE nu depinde de discount', ;
|
||||||
|
ABS(gnCapVA - lnBaseVA) < 0.005, TRANSFORM(lnBaseVA) + ' -> ' + TRANSFORM(gnCapVA)
|
||||||
|
|
||||||
|
lnP1Disc = gnCapDisc
|
||||||
|
lnP1Ftva = gnCapFtva
|
||||||
|
lnP1Tva = gnCapTva
|
||||||
|
lnP1Ctva = gnCapCtva
|
||||||
|
lnP1DiscTva = gnCapDiscTva
|
||||||
|
lnP1VA = gnCapVA
|
||||||
|
|
||||||
|
*-- PASUL 3: VERDICTUL. NULL peste un discount nenul - pastreaza sau zeroeaza?
|
||||||
|
llOk = ApelRecalc(gnIdRon, 'NULL', tcLog)
|
||||||
|
DO asserteaza WITH lcEt + '3: apelul cu NULL peste discount nenul a mers', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
IF !llOk OR !CitesteCap(gnIdRon)
|
||||||
|
MyInchideTranzactie(2)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'VERDICT - dupa recalc(NULL) peste discount ' + TRANSFORM(lnP1Disc), tcLog
|
||||||
|
|
||||||
|
DO asserteaza WITH lcEt + '3: VERDICT - NULL PASTREAZA discountul curent, nu-l zeroeaza', ;
|
||||||
|
ABS(gnCapDisc - lnP1Disc) < 0.0001, ;
|
||||||
|
'discount inainte=' + TRANSFORM(lnP1Disc) + ' dupa NULL=' + TRANSFORM(gnCapDisc)
|
||||||
|
DO asserteaza WITH lcEt + '3: NULL lasa toate totalurile neschimbate', ;
|
||||||
|
ABS(gnCapFtva - lnP1Ftva) < 0.0001 AND ABS(gnCapTva - lnP1Tva) < 0.0001 ;
|
||||||
|
AND ABS(gnCapCtva - lnP1Ctva) < 0.0001 AND ABS(gnCapDiscTva - lnP1DiscTva) < 0.0001 ;
|
||||||
|
AND ABS(gnCapVA - lnP1VA) < 0.0001, ;
|
||||||
|
'ftva=' + TRANSFORM(gnCapFtva) + ' tva=' + TRANSFORM(gnCapTva) + ' ctva=' + TRANSFORM(gnCapCtva)
|
||||||
|
|
||||||
|
*-- PASUL 4: 0 explicit - readuce documentul la starea de plecare
|
||||||
|
llOk = ApelRecalc(gnIdRon, '0', tcLog)
|
||||||
|
DO asserteaza WITH lcEt + '4: apelul cu 0 a mers', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
IF llOk AND CitesteCap(gnIdRon)
|
||||||
|
DO LogCap WITH 'dupa recalc(0)', tcLog
|
||||||
|
DO asserteaza WITH lcEt + '4: 0 explicit zeroeaza discountul (spre deosebire de NULL)', ;
|
||||||
|
ABS(gnCapDisc - 0) < 0.0001, 'discount=' + TRANSFORM(gnCapDisc)
|
||||||
|
DO asserteaza WITH lcEt + '4: totalurile revin exact la starea de plecare', ;
|
||||||
|
ABS(gnCapFtva - lnBaseFtva) < 0.005 AND ABS(gnCapTva - lnBaseTva) < 0.005 ;
|
||||||
|
AND ABS(gnCapCtva - lnBaseCtva) < 0.005, ;
|
||||||
|
'ftva=' + TRANSFORM(gnCapFtva) + ' tva=' + TRANSFORM(gnCapTva) + ' ctva=' + TRANSFORM(gnCapCtva)
|
||||||
|
ENDIF
|
||||||
|
CATCH TO loExc
|
||||||
|
STRTOFILE(' EXCEPTIE in blocul A: ' + TRANSFORM(loExc.ErrorNo) + ' [' + loExc.Message + '] ' + ;
|
||||||
|
loExc.Procedure + ':' + TRANSFORM(loExc.LineNo) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDTRY
|
||||||
|
|
||||||
|
*-- blocul A nu consuma date: tot ce s-a scris mai sus se anuleaza
|
||||||
|
IF MyInchideTranzactie(2)
|
||||||
|
STRTOFILE(' tranzactie inchisa cu ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' FAIL la ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF CitesteCap(gnIdRon)
|
||||||
|
DO LogCap WITH 'DUPA ROLLBACK', tcLog
|
||||||
|
DO asserteaza WITH lcEt + '5: ROLLBACK-ul a lasat documentul exact cum era (blocul nu consuma date)', ;
|
||||||
|
ABS(gnCapDisc - lnBaseDisc) < 0.0001 AND ABS(gnCapFtva - lnBaseFtva) < 0.0001 ;
|
||||||
|
AND ABS(gnCapTva - lnBaseTva) < 0.0001 AND ABS(gnCapCtva - lnBaseCtva) < 0.0001 ;
|
||||||
|
AND ABS(gnCapDiscTva - lnBaseDiscTva) < 0.0001 AND ABS(gnCapVA - lnBaseVA) < 0.0001, ;
|
||||||
|
'discount=' + TRANSFORM(gnCapDisc) + ' ftva=' + TRANSFORM(gnCapFtva) + ' tva=' + TRANSFORM(gnCapTva)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*=====================================================================================
|
||||||
|
*-- BLOCUL B: acelasi contract pe un document REAL in valuta, cu ROLLBACK la final
|
||||||
|
*=====================================================================================
|
||||||
|
PROCEDURE bloc_b_valuta
|
||||||
|
LPARAMETERS tcLog
|
||||||
|
|
||||||
|
LOCAL lnBaseDisc, lnBaseDiscTva, lnBaseVA, lnBaseFtva, lnBaseTva, lnBaseCtva
|
||||||
|
LOCAL lnBaseValval, lnBaseTvaval, lnBaseTotval, lnBaseIdVal, lnBaseCurs, lnBaseMult
|
||||||
|
LOCAL lnP1Disc, lnP1Ftva, lnP1Tva, lnP1Valval, lnP1Tvaval
|
||||||
|
LOCAL lnTvavMax, lnDiscRon, lnAstDiscTvaVal, llOk, lcEt, lnNrCursuri
|
||||||
|
|
||||||
|
lcEt = 'B'
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + '========== BLOCUL B - document REAL in valuta (id_vanzare=' + ;
|
||||||
|
TRANSFORM(gnIdValuta) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
IF !CitesteCap(gnIdValuta)
|
||||||
|
DO asserteaza WITH lcEt + ': documentul in valuta exista', .F., 'id_vanzare=' + TRANSFORM(gnIdValuta)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'STARE INITIALA', tcLog
|
||||||
|
|
||||||
|
DO asserteaza WITH lcEt + '0: documentul ales e chiar in valuta (in_valuta=1, cu id_valuta si curs)', ;
|
||||||
|
gnCapInValuta = 1 AND gnCapIdValuta > 0 AND gnCapCurs > 0 AND gnCapMult > 0, ;
|
||||||
|
'in_valuta=' + TRANSFORM(gnCapInValuta) + ' id_valuta=' + TRANSFORM(gnCapIdValuta) + ;
|
||||||
|
' curs=' + TRANSFORM(gnCapCurs) + ' mult=' + TRANSFORM(gnCapMult)
|
||||||
|
IF gnCapInValuta <> 1 OR gnCapCurs <= 0
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- fara rand in VANZARI_CURSURI, join-ul din procedura da NULL si agregatele se golesc (riscul R5)
|
||||||
|
lnNrCursuri = 0
|
||||||
|
IF ExecSel([select count(*) as nr from vanzari_cursuri where id_vanzare = ] + TRANSFORM(gnIdValuta), 'v_crs') > 0
|
||||||
|
lnNrCursuri = v_crs.nr
|
||||||
|
USE IN v_crs
|
||||||
|
ENDIF
|
||||||
|
DO asserteaza WITH lcEt + '0: documentul are rand in VANZARI_CURSURI (altfel recalculul da NULL)', ;
|
||||||
|
lnNrCursuri > 0, 'randuri=' + TRANSFORM(lnNrCursuri)
|
||||||
|
|
||||||
|
lnBaseDisc = gnCapDisc
|
||||||
|
lnBaseDiscTva = gnCapDiscTva
|
||||||
|
lnBaseVA = gnCapVA
|
||||||
|
lnBaseFtva = gnCapFtva
|
||||||
|
lnBaseTva = gnCapTva
|
||||||
|
lnBaseCtva = gnCapCtva
|
||||||
|
lnBaseValval = gnCapValval
|
||||||
|
lnBaseTvaval = gnCapTvaval
|
||||||
|
lnBaseTotval = gnCapTotval
|
||||||
|
lnBaseIdVal = gnCapIdValuta
|
||||||
|
lnBaseCurs = gnCapCurs
|
||||||
|
lnBaseMult = gnCapMult
|
||||||
|
|
||||||
|
lnTvavMax = CotaMaxima(gnIdValuta)
|
||||||
|
STRTOFILE(' cota TVA maxima pe liniile active = ' + TRANSFORM(lnTvavMax) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
IF !MyDeschideTranzactie()
|
||||||
|
DO asserteaza WITH lcEt + ': tranzactia s-a deschis', .F., 'SQLSetprop a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
TRY
|
||||||
|
*-- PASUL 1: recalcul cu NULL pe un document in valuta emis normal - trebuie sa reproduca
|
||||||
|
*-- exact totalurile persistate, si in RON si in valuta (proba ca agregarea si conversia
|
||||||
|
*-- prin curs sunt corecte pe un document real, nu doar pe unul simulat in VFP)
|
||||||
|
llOk = ApelRecalc(gnIdValuta, 'NULL', tcLog)
|
||||||
|
DO asserteaza WITH lcEt + '1: apelul cu NULL a mers pe documentul in valuta', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
IF !llOk OR !CitesteCap(gnIdValuta)
|
||||||
|
MyInchideTranzactie(2)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'dupa recalc(NULL)', tcLog
|
||||||
|
|
||||||
|
DO asserteaza WITH lcEt + '1: totalurile in RON sunt reproduse exact pe documentul in valuta', ;
|
||||||
|
ABS(gnCapFtva - lnBaseFtva) < 0.005 AND ABS(gnCapTva - lnBaseTva) < 0.005 ;
|
||||||
|
AND ABS(gnCapCtva - lnBaseCtva) < 0.005, ;
|
||||||
|
'ftva ' + TRANSFORM(lnBaseFtva) + '->' + TRANSFORM(gnCapFtva) + ' tva ' + TRANSFORM(lnBaseTva) + ;
|
||||||
|
'->' + TRANSFORM(gnCapTva) + ' ctva ' + TRANSFORM(lnBaseCtva) + '->' + TRANSFORM(gnCapCtva)
|
||||||
|
DO asserteaza WITH lcEt + '1: totalurile in valuta (valval/tvaval/totval) sunt reproduse exact', ;
|
||||||
|
ABS(gnCapValval - lnBaseValval) < 0.005 AND ABS(gnCapTvaval - lnBaseTvaval) < 0.005 ;
|
||||||
|
AND ABS(gnCapTotval - lnBaseTotval) < 0.005, ;
|
||||||
|
'valval ' + TRANSFORM(lnBaseValval) + '->' + TRANSFORM(gnCapValval) + ' tvaval ' + ;
|
||||||
|
TRANSFORM(lnBaseTvaval) + '->' + TRANSFORM(gnCapTvaval) + ' totval ' + TRANSFORM(lnBaseTotval) + ;
|
||||||
|
'->' + TRANSFORM(gnCapTotval)
|
||||||
|
DO asserteaza WITH lcEt + '1: valuta documentului (id_valuta/curs/multiplicator) e pastrata', ;
|
||||||
|
gnCapIdValuta = lnBaseIdVal AND ABS(gnCapCurs - lnBaseCurs) < 0.00001 AND ABS(gnCapMult - lnBaseMult) < 0.00001, ;
|
||||||
|
'id_valuta=' + TRANSFORM(gnCapIdValuta) + ' curs=' + TRANSFORM(gnCapCurs) + ' mult=' + TRANSFORM(gnCapMult)
|
||||||
|
DO asserteaza WITH lcEt + '1: NULL nu schimba discountul documentului in valuta', ;
|
||||||
|
ABS(gnCapDisc - lnBaseDisc) < 0.0001, TRANSFORM(lnBaseDisc) + ' -> ' + TRANSFORM(gnCapDisc)
|
||||||
|
|
||||||
|
*-- PASUL 2: discount nenul pe document in valuta. Discountul e exprimat in valuta:
|
||||||
|
*-- in RON se scade ROUND(curs * discount / multiplicator, PPRETV), in valuta se scade brut.
|
||||||
|
lnDiscRon = ROUND(lnBaseCurs * gnDiscValuta / lnBaseMult, gnPPretV)
|
||||||
|
lnAstDiscTvaVal = ROUND(gnDiscValuta * (lnTvavMax - 1), gnPPretV)
|
||||||
|
STRTOFILE(' discount ' + TRANSFORM(gnDiscValuta) + ' in valuta => ' + TRANSFORM(lnDiscRon) + ' RON (curs ' + ;
|
||||||
|
TRANSFORM(lnBaseCurs) + ' / mult ' + TRANSFORM(lnBaseMult) + ')' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
llOk = ApelRecalc(gnIdValuta, ALLTRIM(STR(gnDiscValuta, 18, 4)), tcLog)
|
||||||
|
DO asserteaza WITH lcEt + '2: apelul cu valoare nenula a mers pe documentul in valuta', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
IF !llOk OR !CitesteCap(gnIdValuta)
|
||||||
|
MyInchideTranzactie(2)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'dupa recalc(' + TRANSFORM(gnDiscValuta) + ')', tcLog
|
||||||
|
|
||||||
|
DO asserteaza WITH lcEt + '2: valoarea nenula ajunge in VANZARI.DISCOUNT (document in valuta)', ;
|
||||||
|
ABS(gnCapDisc - gnDiscValuta) < 0.0001, 'discount=' + TRANSFORM(gnCapDisc) + ' (cerut ' + TRANSFORM(gnDiscValuta) + ')'
|
||||||
|
DO asserteaza WITH lcEt + '2: total_fara_tva scade cu discountul CONVERTIT prin cursul documentului', ;
|
||||||
|
ABS(gnCapFtva - (lnBaseFtva - lnDiscRon)) < 0.011, ;
|
||||||
|
'ftva=' + TRANSFORM(gnCapFtva) + ' asteptat ' + TRANSFORM(lnBaseFtva - lnDiscRon)
|
||||||
|
DO asserteaza WITH lcEt + '2: valval scade cu discountul BRUT, in valuta', ;
|
||||||
|
ABS(gnCapValval - (lnBaseValval - gnDiscValuta)) < 0.011, ;
|
||||||
|
'valval=' + TRANSFORM(gnCapValval) + ' asteptat ' + TRANSFORM(lnBaseValval - gnDiscValuta)
|
||||||
|
DO asserteaza WITH lcEt + '2: DISCOUNT_TVA pastreaza TVA-ul discountului in valuta', ;
|
||||||
|
ABS(gnCapDiscTva - lnAstDiscTvaVal) < 0.011, ;
|
||||||
|
'discount_tva=' + TRANSFORM(gnCapDiscTva) + ' asteptat ' + TRANSFORM(lnAstDiscTvaVal)
|
||||||
|
DO asserteaza WITH lcEt + '2: tvaval scade cu TVA-ul discountului in valuta', ;
|
||||||
|
ABS(gnCapTvaval - (lnBaseTvaval - lnAstDiscTvaVal)) < 0.011, ;
|
||||||
|
'tvaval=' + TRANSFORM(gnCapTvaval) + ' asteptat ' + TRANSFORM(lnBaseTvaval - lnAstDiscTvaVal)
|
||||||
|
DO asserteaza WITH lcEt + '2: totalurile in RON raman coerente (fara_tva + tva = cu_tva)', ;
|
||||||
|
ABS((gnCapFtva + gnCapTva) - gnCapCtva) < 0.01, ;
|
||||||
|
TRANSFORM(gnCapFtva) + ' + ' + TRANSFORM(gnCapTva) + ' = ' + TRANSFORM(gnCapCtva)
|
||||||
|
DO asserteaza WITH lcEt + '2: totalurile in valuta raman coerente (valval + tvaval = totval)', ;
|
||||||
|
ABS((gnCapValval + gnCapTvaval) - gnCapTotval) < 0.01, ;
|
||||||
|
TRANSFORM(gnCapValval) + ' + ' + TRANSFORM(gnCapTvaval) + ' = ' + TRANSFORM(gnCapTotval)
|
||||||
|
|
||||||
|
lnP1Disc = gnCapDisc
|
||||||
|
lnP1Ftva = gnCapFtva
|
||||||
|
lnP1Tva = gnCapTva
|
||||||
|
lnP1Valval = gnCapValval
|
||||||
|
lnP1Tvaval = gnCapTvaval
|
||||||
|
|
||||||
|
*-- PASUL 3: verdictul pe NULL, repetat pe calea de valuta
|
||||||
|
llOk = ApelRecalc(gnIdValuta, 'NULL', tcLog)
|
||||||
|
DO asserteaza WITH lcEt + '3: apelul cu NULL peste discount nenul a mers', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
IF llOk AND CitesteCap(gnIdValuta)
|
||||||
|
DO LogCap WITH 'VERDICT valuta - dupa recalc(NULL) peste discount ' + TRANSFORM(lnP1Disc), tcLog
|
||||||
|
DO asserteaza WITH lcEt + '3: VERDICT - NULL pastreaza discountul si pe documentul in valuta', ;
|
||||||
|
ABS(gnCapDisc - lnP1Disc) < 0.0001, ;
|
||||||
|
'discount inainte=' + TRANSFORM(lnP1Disc) + ' dupa NULL=' + TRANSFORM(gnCapDisc)
|
||||||
|
DO asserteaza WITH lcEt + '3: NULL lasa neschimbate si totalurile in RON, si cele in valuta', ;
|
||||||
|
ABS(gnCapFtva - lnP1Ftva) < 0.0001 AND ABS(gnCapTva - lnP1Tva) < 0.0001 ;
|
||||||
|
AND ABS(gnCapValval - lnP1Valval) < 0.0001 AND ABS(gnCapTvaval - lnP1Tvaval) < 0.0001, ;
|
||||||
|
'ftva=' + TRANSFORM(gnCapFtva) + ' valval=' + TRANSFORM(gnCapValval)
|
||||||
|
ENDIF
|
||||||
|
CATCH TO loExc
|
||||||
|
STRTOFILE(' EXCEPTIE in blocul B: ' + TRANSFORM(loExc.ErrorNo) + ' [' + loExc.Message + '] ' + ;
|
||||||
|
loExc.Procedure + ':' + TRANSFORM(loExc.LineNo) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDTRY
|
||||||
|
|
||||||
|
*-- documentul e din arhiva (2026-05): ROLLBACK obligatoriu, nu se modifica nimic in el
|
||||||
|
IF MyInchideTranzactie(2)
|
||||||
|
STRTOFILE(' tranzactie inchisa cu ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' FAIL la ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF CitesteCap(gnIdValuta)
|
||||||
|
DO LogCap WITH 'DUPA ROLLBACK', tcLog
|
||||||
|
DO asserteaza WITH lcEt + '4: ROLLBACK-ul a lasat documentul din arhiva exact cum era', ;
|
||||||
|
ABS(gnCapDisc - lnBaseDisc) < 0.0001 AND ABS(gnCapFtva - lnBaseFtva) < 0.0001 ;
|
||||||
|
AND ABS(gnCapTva - lnBaseTva) < 0.0001 AND ABS(gnCapCtva - lnBaseCtva) < 0.0001 ;
|
||||||
|
AND ABS(gnCapValval - lnBaseValval) < 0.0001 AND ABS(gnCapTvaval - lnBaseTvaval) < 0.0001 ;
|
||||||
|
AND ABS(gnCapTotval - lnBaseTotval) < 0.0001 AND ABS(gnCapVA - lnBaseVA) < 0.0001, ;
|
||||||
|
'discount=' + TRANSFORM(gnCapDisc) + ' ftva=' + TRANSFORM(gnCapFtva) + ' valval=' + TRANSFORM(gnCapValval)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*=====================================================================================
|
||||||
|
*-- BLOCUL C: lantul real de salvare pe un document cu discount NENUL. Singurul care comite.
|
||||||
|
*=====================================================================================
|
||||||
|
PROCEDURE bloc_c_lant_real
|
||||||
|
LPARAMETERS tcLog
|
||||||
|
|
||||||
|
*-- pnAn/pnLuna/lnCod/lnIdFact PRIVATE (nu LOCAL), ca in ofacturare_comun.vc2:3730 -
|
||||||
|
*-- finalizeaza_modificare_nota le foloseste ca bind-variabile ?pnLuna/?pnAn in josul stivei
|
||||||
|
PRIVATE pnAn, pnLuna, lnCod, lnIdFact
|
||||||
|
LOCAL lnBaseDisc, lnBaseFtva, lnBaseTva, lnBaseCtva, lnBaseVA, lnBaseDiscTva
|
||||||
|
LOCAL lnCodInainte, lnSters, llEProforma, lnIdSet, lnIdFactD, lnSucces, llGasitRand
|
||||||
|
LOCAL lcSql, lnQ, lcEt, llOk, lnDiscTvaAst, lnTvavMax, lnNrLinii
|
||||||
|
|
||||||
|
lcEt = 'C'
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + '========== BLOCUL C - lantul real de salvare pe document cu discount nenul (id_vanzare=' + ;
|
||||||
|
TRANSFORM(gnIdRon) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
IF !CitesteCap(gnIdRon)
|
||||||
|
DO asserteaza WITH lcEt + ': documentul exista', .F., 'id_vanzare=' + TRANSFORM(gnIdRon)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'STARE INITIALA', tcLog
|
||||||
|
|
||||||
|
lnBaseDisc = gnCapDisc
|
||||||
|
lnBaseDiscTva = gnCapDiscTva
|
||||||
|
lnBaseVA = gnCapVA
|
||||||
|
lnBaseFtva = gnCapFtva
|
||||||
|
lnBaseTva = gnCapTva
|
||||||
|
lnBaseCtva = gnCapCtva
|
||||||
|
lnTvavMax = CotaMaxima(gnIdRon)
|
||||||
|
lnDiscTvaAst = ROUND(gnDiscRon * (lnTvavMax - 1), gnPPretV)
|
||||||
|
|
||||||
|
*-- 1) pregatirea: documentul primeste un discount nenul, comis, prin chiar procedura testata
|
||||||
|
IF !MyDeschideTranzactie()
|
||||||
|
DO asserteaza WITH lcEt + '0: tranzactia de pregatire s-a deschis', .F., 'SQLSetprop a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
llOk = ApelRecalc(gnIdRon, ALLTRIM(STR(gnDiscRon, 18, 4)), tcLog)
|
||||||
|
IF !llOk
|
||||||
|
MyInchideTranzactie(2)
|
||||||
|
DO asserteaza WITH lcEt + '0: pregatirea documentului cu discount nenul', .F., 'apelul a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
MyInchideTranzactie(1)
|
||||||
|
IF !CitesteCap(gnIdRon)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
DO LogCap WITH 'PREGATIT, comis - discount nenul pe document', tcLog
|
||||||
|
DO asserteaza WITH lcEt + '0: documentul are acum discount nenul, comis', ;
|
||||||
|
ABS(gnCapDisc - gnDiscRon) < 0.0001, 'discount=' + TRANSFORM(gnCapDisc)
|
||||||
|
|
||||||
|
*-- 2) lantul real de editare, fara nicio modificare de linii
|
||||||
|
lcSql = [select cod, sters, id_fact, eproforma, ] + ;
|
||||||
|
[extract(year from data_act) as anact, extract(month from data_act) as lunaact ] + ;
|
||||||
|
[from vanzari where id_vanzare = ] + TRANSFORM(gnIdRon)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_vz')
|
||||||
|
IF lnQ <= 0 OR RECCOUNT('v_vz') <> 1
|
||||||
|
DO asserteaza WITH lcEt + '1: VANZARI citit', .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
SELECT v_vz
|
||||||
|
lnCod = cod
|
||||||
|
lnCodInainte = cod
|
||||||
|
lnSters = sters
|
||||||
|
lnIdFact = id_fact
|
||||||
|
llEProforma = (NVL(eproforma, 0) = 1)
|
||||||
|
pnAn = anact
|
||||||
|
pnLuna = lunaact
|
||||||
|
USE IN v_vz
|
||||||
|
|
||||||
|
IF lnSters = 1 OR llEProforma OR (pnAn * 12) + pnLuna <> (gnAn * 12) + gnLuna
|
||||||
|
DO asserteaza WITH lcEt + '1: document editabil, din luna curenta', .F., ;
|
||||||
|
'sters=' + TRANSFORM(lnSters) + ' an/luna=' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna)
|
||||||
|
DO restaureaza_discount WITH tcLog, lnBaseDisc, lnBaseFtva, lnBaseTva, lnBaseCtva
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
IF ReferinteDocumenteNota(pnAn, pnLuna, lnCod) OR EsteInEFactura(lnIdFact)
|
||||||
|
DO asserteaza WITH lcEt + '1: document fara referinte / netrimis in eFactura', .F., 'blocat de garda'
|
||||||
|
DO restaureaza_discount WITH tcLog, lnBaseDisc, lnBaseFtva, lnBaseTva, lnBaseCtva
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.) OR RECCOUNT('actactan') = 0
|
||||||
|
DO asserteaza WITH lcEt + '1: IncarcaCursoareModificareNota', .F., 'a esuat sau nota e goala'
|
||||||
|
DO restaureaza_discount WITH tcLog, lnBaseDisc, lnBaseFtva, lnBaseTva, lnBaseCtva
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
SELECT a.*, IIF(NVL(id_jtva_coloana, 0) = 0, 0, 1) AS cu_Tva FROM tact a INTO CURSOR tact READWRITE
|
||||||
|
|
||||||
|
IF !IncarcaVanzareDinNota('tact')
|
||||||
|
DO asserteaza WITH lcEt + '1: IncarcaVanzareDinNota', .F., 'nu a gasit randul din VANZARI'
|
||||||
|
DO restaureaza_discount WITH tcLog, lnBaseDisc, lnBaseFtva, lnBaseTva, lnBaseCtva
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
IncarcaArticoleFactura(gnIdRon, 'tvd')
|
||||||
|
lnNrLinii = RECCOUNT('tvd')
|
||||||
|
|
||||||
|
*-- proba cheie a caii VFP: discountul documentului ajunge in cursorul pe care se sprijina helperul
|
||||||
|
DO asserteaza WITH lcEt + '2: tvanz.discount aduce discountul nenul din VANZARI in cursorul de lucru', ;
|
||||||
|
!ISNULL(tvanz.discount) AND ABS(NVL(tvanz.discount, 0) - gnDiscRon) < 0.0001, ;
|
||||||
|
'tvanz.discount=' + TRANSFORM(NVL(tvanz.discount, 0)) + ' (in VANZARI ' + TRANSFORM(gnDiscRon) + ')'
|
||||||
|
STRTOFILE(' tvd incarcat cu ' + TRANSFORM(lnNrLinii) + ' linii active; tvanz.discount=' + ;
|
||||||
|
TRANSFORM(NVL(tvanz.discount, 0)) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
*-- frm_modific2024 ocolit, buton=1 fortat (inainte_de_do_termin NU se executa)
|
||||||
|
buton = 1
|
||||||
|
lnSucces = 0
|
||||||
|
TRY
|
||||||
|
IF MyDeschideTranzactie()
|
||||||
|
SELECT actactan
|
||||||
|
lnSucces = OSCRIE_IN_FISIERE(2, .T., .T.)
|
||||||
|
STRTOFILE(' OSCRIE_IN_FISIERE(2,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
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.)
|
||||||
|
STRTOFILE(' OSCRIE_IN_FISIERE(0,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
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)
|
||||||
|
STRTOFILE(' finalizeaza_modificare_nota => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- starea necomisa a discountului dupa realinierea COD-ului: actualizeaza_vanzari nu-l atinge
|
||||||
|
IF lnSucces > 0 AND CitesteCap(gnIdRon)
|
||||||
|
DO LogCap WITH 'IN TRANZACTIE, dupa finalizeaza_modificare_nota', tcLog
|
||||||
|
DO asserteaza WITH lcEt + '3: finalizeaza_modificare_nota nu atinge DISCOUNT', ;
|
||||||
|
ABS(gnCapDisc - gnDiscRon) < 0.0001, 'discount=' + TRANSFORM(gnCapDisc)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF lnSucces > 0 AND "OFACTURARE_EDITARE" $ UPPER(SET("Procedure")) AND USED('tvanz') AND RECCOUNT('tvanz') = 1
|
||||||
|
lnSucces = IIF(ScrieArticoleFacturaEditate(tvanz.id_vanzare), 1, -1)
|
||||||
|
STRTOFILE(' ScrieArticoleFacturaEditate => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' ATENTIE: blocul ScrieArticoleFacturaEditate NU s-a executat' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
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 inchiderea tranzactiei' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' FAIL: deschiderea tranzactiei 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
|
||||||
|
|
||||||
|
DO asserteaza WITH lcEt + '4: lantul de salvare a mers pana la capat (lnSucces>0, COMMIT)', ;
|
||||||
|
lnSucces > 0, 'lnSucces=' + TRANSFORM(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
|
||||||
|
IF USED('tvd')
|
||||||
|
USE IN tvd
|
||||||
|
ENDIF
|
||||||
|
IF USED('tvanz')
|
||||||
|
USE IN tvanz
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 3) verificarile de dupa commit: discountul a supravietuit salvarii complete
|
||||||
|
IF CitesteCap(gnIdRon)
|
||||||
|
DO LogCap WITH 'DUPA COMMIT', tcLog
|
||||||
|
DO asserteaza WITH lcEt + '5: discountul nenul supravietuieste salvarii complete a documentului', ;
|
||||||
|
ABS(gnCapDisc - gnDiscRon) < 0.0001, ;
|
||||||
|
'discount=' + TRANSFORM(gnCapDisc) + ' (era ' + TRANSFORM(gnDiscRon) + ')'
|
||||||
|
DO asserteaza WITH lcEt + '5: VANZARI.COD realocat, documentul ramane activ', ;
|
||||||
|
gnCapCod <> lnCodInainte AND gnCapSters = 0, TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(gnCapCod)
|
||||||
|
DO asserteaza WITH lcEt + '5: totalurile de dupa salvare tin cont de discount', ;
|
||||||
|
ABS(gnCapFtva - (lnBaseFtva - gnDiscRon)) < 0.011 AND ABS(gnCapDiscTva - lnDiscTvaAst) < 0.011, ;
|
||||||
|
'ftva=' + TRANSFORM(gnCapFtva) + ' asteptat ' + TRANSFORM(lnBaseFtva - gnDiscRon) + ;
|
||||||
|
' discount_tva=' + TRANSFORM(gnCapDiscTva)
|
||||||
|
DO asserteaza WITH lcEt + '5: totalurile raman coerente dupa salvare', ;
|
||||||
|
ABS((gnCapFtva + gnCapTva) - gnCapCtva) < 0.01, ;
|
||||||
|
TRANSFORM(gnCapFtva) + ' + ' + TRANSFORM(gnCapTva) + ' = ' + TRANSFORM(gnCapCtva)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 4) restaurarea: documentul se intoarce la discount 0 si la totalurile de plecare
|
||||||
|
DO restaureaza_discount WITH tcLog, lnBaseDisc, lnBaseFtva, lnBaseTva, lnBaseCtva
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- readuce documentul de lucru la discountul si totalurile de plecare, comis
|
||||||
|
PROCEDURE restaureaza_discount
|
||||||
|
LPARAMETERS tcLog, tnBaseDisc, tnBaseFtva, tnBaseTva, tnBaseCtva
|
||||||
|
LOCAL llOk
|
||||||
|
|
||||||
|
IF !MyDeschideTranzactie()
|
||||||
|
DO asserteaza WITH 'C6: tranzactia de restaurare s-a deschis', .F., 'SQLSetprop a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
llOk = ApelRecalc(gnIdRon, ALLTRIM(STR(tnBaseDisc, 18, 4)), tcLog)
|
||||||
|
IF llOk
|
||||||
|
MyInchideTranzactie(1)
|
||||||
|
ELSE
|
||||||
|
MyInchideTranzactie(2)
|
||||||
|
ENDIF
|
||||||
|
DO asserteaza WITH 'C6: restaurarea discountului initial a mers', llOk, 'llOk=' + TRANSFORM(llOk)
|
||||||
|
|
||||||
|
IF CitesteCap(gnIdRon)
|
||||||
|
DO LogCap WITH 'DUPA RESTAURARE', tcLog
|
||||||
|
DO asserteaza WITH 'C6: documentul e readus la discountul si totalurile de plecare', ;
|
||||||
|
ABS(gnCapDisc - tnBaseDisc) < 0.0001 AND ABS(gnCapFtva - tnBaseFtva) < 0.005 ;
|
||||||
|
AND ABS(gnCapTva - tnBaseTva) < 0.005 AND ABS(gnCapCtva - tnBaseCtva) < 0.005, ;
|
||||||
|
'discount=' + TRANSFORM(gnCapDisc) + ' ftva=' + TRANSFORM(gnCapFtva) + ;
|
||||||
|
' tva=' + TRANSFORM(gnCapTva) + ' ctva=' + TRANSFORM(gnCapCtva)
|
||||||
|
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
|
||||||
470
utile/Teste/editare_factura/test_s5_rollback_real.prg
Normal file
470
utile/Teste/editare_factura/test_s5_rollback_real.prg
Normal file
@@ -0,0 +1,470 @@
|
|||||||
|
* test_s5_rollback_real.prg
|
||||||
|
* Inchide golul "calea de ROLLBACK la esec partial" din docs\livrare_s5.md, sectiunea 5: pana acum
|
||||||
|
* niciun test nu provocase deliberat un esec in mijlocul ScrieArticoleFacturaEditate (ofacturare_editare.prg)
|
||||||
|
* pe date reale - comportamentul de rollback era verificat doar static, prin simetria codului.
|
||||||
|
*
|
||||||
|
* PARTEA M (mock, fara Oracle) - completeaza test_s5_validari_articole.prg/B3 (care opreste esecul
|
||||||
|
* la a DOUA comanda, adica in mijlocul buclei UPDATE a liniilor pastrate): aici esecul e la PRIMA
|
||||||
|
* comanda (chiar update-ul "marcheaza tot sters", primul pas al helperului) - dovedeste ca daca
|
||||||
|
* pasul 1 esueaza, functia se opreste imediat, FARA nicio comanda de UPDATE/INSERT/recalcul.
|
||||||
|
*
|
||||||
|
* PARTEA R (real, Oracle) - NU apeleaza ScrieArticoleFacturaEditate direct (vezi ATENTIE mai jos),
|
||||||
|
* ci reproduce EXACT aceeasi secventa SQL pe care helperul ar genera-o pentru un caz cu esec la
|
||||||
|
* INSERT (id_articol inexistent, FK_VANZARE_DET002), prin SQLEXEC brut, in tranzactia manuala
|
||||||
|
* deja folosita de test_s5_scriere_reala.prg. Dovedeste, pe id_vanzare = 1049:
|
||||||
|
* 1) pasii 1-2 ai helperului (marcheaza tot sters, invie+actualizeaza liniile pastrate) chiar
|
||||||
|
* produc starea asteptata NECOMISA, verificata pe aceeasi conexiune;
|
||||||
|
* 2) o linie noua VALIDA se INSEREaza cu succes, tot necomis - proba de executie PARTIALA reala;
|
||||||
|
* 3) o linie noua cu id_articol inexistent arunca eroarea Oracle reala (ORA-02291) - exact
|
||||||
|
* punctul unde helperul s-ar opri (EXIT din SCAN al pasului 3, recalculeaza_totaluri_vanzari
|
||||||
|
* NU s-ar mai apela);
|
||||||
|
* 4) tranzactia se inchide cu ROLLBACK (tiparul apelantilor: lnSucces=Iif(...,1,-1), apoi
|
||||||
|
* MyInchideTranzactie(Iif(lnSucces<0,2,1)));
|
||||||
|
* 5) verificat INDEPENDENT prin sqlplus, dupa terminarea procesului VFP: VANZARI_DETALII pentru
|
||||||
|
* 1049 are EXACT acelasi continut (id_vanzare_det/sters/cantitate/pret/pret_achizitie) ca
|
||||||
|
* inainte de test - nimic din pasii 1-3 nu a supravietuit.
|
||||||
|
*
|
||||||
|
* ATENTIE - GASIT IN TIMPUL ACESTUI TEST, NU REPARAT (cod de productie interzis pentru acest agent):
|
||||||
|
* apelul goExecutor.oExecuta(<sql invalid>) - EXACT calea Oracle folosita de ScrieArticoleFacturaEditate
|
||||||
|
* pentru toate comenzile ei - AGATA procesul VFP headless la o eroare Oracle REALA (nu simulata),
|
||||||
|
* sub tranzactie manuala (SQLSetprop Transactions=2), chiar daca Oracle a raspuns deja cu eroarea
|
||||||
|
* (sesiunea Oracle arata INACTIVE/"SQL*Net message from client", 0 sesiuni blocante, nicio fereastra
|
||||||
|
* de dialog Windows - EnumWindows arata doar fereastra principala). Reprodus de doua ori izolat, cu
|
||||||
|
* un script minimal (~15 linii, test_repro_hang_fk.prg, sters dupa investigatie), inclusiv fara nicio
|
||||||
|
* legatura cu ScrieArticoleFacturaEditate - deci NU e un bug al helperului, ci al executorului comun
|
||||||
|
* (COMUN\programe\oproceduri_comune.prg, clasa oexecutor, PROCEDURE oExecute). SQLEXEC brut (fara
|
||||||
|
* goExecutor) pe ACEEASI comanda intoarce eroarea instant (lnRes=-1, AERROR populat) - vezi
|
||||||
|
* test_repro_hang_fk_raw.prg (sters dupa investigatie). Suspiciune, neconfirmata: ramurile de eroare
|
||||||
|
* din oExecute apeleaza necondiotionat goLog.Log() cand Type('goLog')='O' - posibil sa incerce o
|
||||||
|
* comanda Oracle proprie pe aceeasi conexiune, aflata deja sub tranzactie manuala. Consecinta pentru
|
||||||
|
* livrare: comportamentul REAL al aplicatiei (nu doar al helperului izolat) la un esec Oracle propriu-zis
|
||||||
|
* in acest lant de scriere NU a putut fi verificat capat-la-capat prin apelul functiei de productie -
|
||||||
|
* doar prin reproducerea manuala a secventei ei SQL. De raportat separat echipei, nu de reparat aici.
|
||||||
|
*
|
||||||
|
* Harness identic cu test_s5_scriere_reala.prg: do_deschide/inchide_tranzactie reproduse inline dupa
|
||||||
|
* _frm_base.vc2:252-302. Nu atinge cod de aplicatie. QUIT la final.
|
||||||
|
|
||||||
|
SET SAFETY OFF
|
||||||
|
SET TALK OFF
|
||||||
|
|
||||||
|
LOCAL lcLog
|
||||||
|
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s5_rollback_real_log.txt'
|
||||||
|
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
|
||||||
|
|
||||||
|
PUBLIC gcErrLog, gcTestLog, gnPass, gnFail
|
||||||
|
gcErrLog = lcLog
|
||||||
|
gcTestLog = lcLog
|
||||||
|
gnPass = 0
|
||||||
|
gnFail = 0
|
||||||
|
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||||
|
|
||||||
|
PUBLIC gnIdVanzareTest
|
||||||
|
gnIdVanzareTest = 1049
|
||||||
|
|
||||||
|
DO parte_m_mock WITH lcLog
|
||||||
|
DO parte_r_real WITH lcLog, gnIdVanzareTest
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + 'REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
QUIT
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE asserteaza
|
||||||
|
LPARAMETERS tcNume, tlConditie, tcValoare
|
||||||
|
|
||||||
|
IF m.tlConditie
|
||||||
|
gnPass = gnPass + 1
|
||||||
|
STRTOFILE('PASS ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ELSE
|
||||||
|
gnFail = gnFail + 1
|
||||||
|
STRTOFILE('FAIL ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- executa SELECT-ul prin goExecutor (cai care CITESC - fara risc, vezi ATENTIE din antet) si
|
||||||
|
*-- intoarce codul de succes; cursorul vechi se inchide intai
|
||||||
|
PROCEDURE ExecSel
|
||||||
|
LPARAMETERS tcSql, tcCursor
|
||||||
|
LOCAL lnQ
|
||||||
|
IF USED(tcCursor)
|
||||||
|
USE IN (tcCursor)
|
||||||
|
ENDIF
|
||||||
|
lnQ = goExecutor.oExecute(tcSql, tcCursor)
|
||||||
|
RETURN lnQ
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
*=====================================================================================
|
||||||
|
*-- PARTEA M: mock pe goExecutor - esec chiar la PRIMA comanda (pasul 1, "marcheaza tot sters")
|
||||||
|
*=====================================================================================
|
||||||
|
PROCEDURE parte_m_mock
|
||||||
|
LPARAMETERS tcLog
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + '========== PARTEA M - esec mock la prima comanda (pasul 1) ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
LOCAL loExecutorReal
|
||||||
|
loExecutorReal = goExecutor
|
||||||
|
|
||||||
|
*-- obiectul mock se construieste O SINGURA DATA, inline in program - vezi capcana l, testare-ui-vfp.md
|
||||||
|
goExecutor = CREATEOBJECT('dummyexecutorrollback')
|
||||||
|
goExecutor.nFailAtCall = 1
|
||||||
|
|
||||||
|
IF USED('crstvdrb')
|
||||||
|
USE IN crstvdrb
|
||||||
|
ENDIF
|
||||||
|
CreeazaCursorArticoleGol('crstvdrb')
|
||||||
|
SELECT crstvdrb
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 701, id_articol WITH 1, cantitate WITH 1, pret WITH 1, sters WITH 0 IN crstvdrb
|
||||||
|
|
||||||
|
IF USED('crstvanzrb')
|
||||||
|
USE IN crstvanzrb
|
||||||
|
ENDIF
|
||||||
|
CREATE CURSOR crstvanzrb (id_vanzare I, discount N(18,4) NULL)
|
||||||
|
INSERT INTO crstvanzrb (id_vanzare, discount) VALUES (99999, NULL)
|
||||||
|
|
||||||
|
LOCAL llRet
|
||||||
|
llRet = ScrieArticoleFacturaEditate(99999, 'crstvdrb', 'crstvanzrb')
|
||||||
|
DO asserteaza WITH 'M1: esec la prima comanda (pasul 1) -> functia intoarce .F. imediat', llRet == .F., TRANSFORM(llRet)
|
||||||
|
DO asserteaza WITH 'M2: esec la prima comanda -> NICIO alta comanda incercata (1 comanda total, nu update/insert/recalcul)', ;
|
||||||
|
goExecutor.nApeluri == 1, 'nApeluri=' + TRANSFORM(goExecutor.nApeluri)
|
||||||
|
|
||||||
|
goExecutor = loExecutorReal
|
||||||
|
|
||||||
|
IF USED('crstvdrb')
|
||||||
|
USE IN crstvdrb
|
||||||
|
ENDIF
|
||||||
|
IF USED('crstvanzrb')
|
||||||
|
USE IN crstvanzrb
|
||||||
|
ENDIF
|
||||||
|
IF USED('crsMockSqlRb')
|
||||||
|
USE IN crsMockSqlRb
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*=====================================================================================
|
||||||
|
*-- PARTEA R: aceeasi secventa SQL pe care ScrieArticoleFacturaEditate ar genera-o pentru un caz cu
|
||||||
|
*-- esec la INSERT, prin SQLEXEC brut (vezi ATENTIE din antetul fisierului - goExecutor.oExecuta pe
|
||||||
|
*-- o comanda care esueaza real agata procesul, deci NU e folosit aici pentru comenzile de scriere)
|
||||||
|
*=====================================================================================
|
||||||
|
PROCEDURE parte_r_real
|
||||||
|
LPARAMETERS tcLog, tnIdVanzare
|
||||||
|
|
||||||
|
LOCAL lcSql, lnQ, lnRes, lnArtLipsa, lnArtValid
|
||||||
|
LOCAL lnDet1, lnDet2, lnDet3, lnCant1Inainte, lnPret1
|
||||||
|
LOCAL lnNrLiniiInainte, lcSnapshotInainte, lcSnapshotDupa
|
||||||
|
LOCAL lnCodInainte, lnCodDupa, lnNrLiniiInTranz, lnStersDet1InTranz
|
||||||
|
LOCAL lnSuccesFinal, lnNrLiniiDupa
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + '========== PARTEA R - esec Oracle real (FK id_articol), rollback (id_vanzare=' + ;
|
||||||
|
TRANSFORM(tnIdVanzare) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
*-- id_articol garantat inexistent - verificat inainte de scriere, nu presupus
|
||||||
|
lnArtLipsa = 999999999
|
||||||
|
lnQ = ExecSel([select count(*) as nr from nom_articole where id_articol = ] + TRANSFORM(lnArtLipsa), 'v_chk')
|
||||||
|
DO asserteaza WITH 'R0: id_articol folosit pentru esec chiar NU exista in NOM_ARTICOLE', ;
|
||||||
|
lnQ > 0 AND v_chk.nr = 0, 'nr=' + IIF(lnQ > 0, TRANSFORM(v_chk.nr), 'eroare citire')
|
||||||
|
IF USED('v_chk')
|
||||||
|
USE IN v_chk
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- starea INAINTE, citita direct din Oracle
|
||||||
|
lcSql = [select cod from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_vz0')
|
||||||
|
IF lnQ <= 0 OR RECCOUNT('v_vz0') <> 1
|
||||||
|
DO asserteaza WITH 'R0: VANZARI citit', .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
lnCodInainte = v_vz0.cod
|
||||||
|
USE IN v_vz0
|
||||||
|
|
||||||
|
lcSql = [select id_vanzare_det, id_articol, nvl(sters,0) as sters, nvl(cantitate,0) as cantitate, ] + ;
|
||||||
|
[nvl(pret,0) as pret, nvl(pret_achizitie,0) as pret_achizitie ] + ;
|
||||||
|
[from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ order by id_vanzare_det]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_lin0')
|
||||||
|
IF lnQ <= 0
|
||||||
|
DO asserteaza WITH 'R0: VANZARI_DETALII citit', .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
lnNrLiniiInainte = RECCOUNT('v_lin0')
|
||||||
|
lcSnapshotInainte = ''
|
||||||
|
lnDet1 = 0
|
||||||
|
lnDet2 = 0
|
||||||
|
lnDet3 = 0
|
||||||
|
SELECT v_lin0
|
||||||
|
SCAN
|
||||||
|
IF sters = 0
|
||||||
|
DO CASE
|
||||||
|
CASE lnDet1 = 0
|
||||||
|
lnDet1 = id_vanzare_det
|
||||||
|
lnCant1Inainte = cantitate
|
||||||
|
lnPret1 = pret
|
||||||
|
CASE lnDet2 = 0
|
||||||
|
lnDet2 = id_vanzare_det
|
||||||
|
CASE lnDet3 = 0
|
||||||
|
lnDet3 = id_vanzare_det
|
||||||
|
ENDCASE
|
||||||
|
ENDIF
|
||||||
|
lcSnapshotInainte = lcSnapshotInainte + TRANSFORM(id_vanzare_det) + ':' + TRANSFORM(sters) + ':' + ;
|
||||||
|
TRANSFORM(cantitate) + ':' + TRANSFORM(pret) + ':' + TRANSFORM(pret_achizitie) + '|'
|
||||||
|
ENDSCAN
|
||||||
|
GO TOP IN v_lin0
|
||||||
|
lnArtValid = v_lin0.id_articol
|
||||||
|
USE IN v_lin0
|
||||||
|
|
||||||
|
STRTOFILE(' INAINTE: cod=' + TRANSFORM(lnCodInainte) + ' linii=' + TRANSFORM(lnNrLiniiInainte) + ;
|
||||||
|
' pastrate=' + TRANSFORM(lnDet1) + '/' + TRANSFORM(lnDet2) + '/' + TRANSFORM(lnDet3) + ;
|
||||||
|
' snapshot=[' + lcSnapshotInainte + ']' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
DO asserteaza WITH 'R0: documentul are cel putin 3 linii active (pastrate)', lnDet1 > 0 AND lnDet2 > 0 AND lnDet3 > 0, ;
|
||||||
|
TRANSFORM(lnDet1) + '/' + TRANSFORM(lnDet2) + '/' + TRANSFORM(lnDet3)
|
||||||
|
IF lnDet1 = 0 OR lnDet2 = 0 OR lnDet3 = 0
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- lantul de scriere, tiparul exact al apelantilor: pornire tranzactie -> comenzi -> esec -> ROLLBACK
|
||||||
|
lnSuccesFinal = 1
|
||||||
|
TRY
|
||||||
|
IF !MyDeschideTranzactie()
|
||||||
|
DO asserteaza WITH 'R1: tranzactia s-a deschis', .F., 'SQLSetprop a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- PASUL 1 al helperului: marcheaza tot sters (ofacturare_editare.prg:489-490)
|
||||||
|
lcSql = [update vanzari_detalii set sters = 1, id_utils = ] + TRANSFORM(gnIdUtil) + [, dataoras = sysdate ] + ;
|
||||||
|
[where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ and sters = 0]
|
||||||
|
lnRes = SQLEXEC(gnHandle, lcSql)
|
||||||
|
STRTOFILE(' PAS1 marcheaza tot sters => ' + TRANSFORM(lnRes) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
IF lnRes < 0
|
||||||
|
lnSuccesFinal = -1
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- PASUL 2 al helperului: invie+actualizeaza liniile pastrate (:498-501) - cele 3 identificate mai sus,
|
||||||
|
*-- prima cu cantitatea dublata (ca sa se poata verifica direct efectul UPDATE-ului)
|
||||||
|
IF lnSuccesFinal > 0
|
||||||
|
lcSql = [update vanzari_detalii set sters = 0, cantitate = ] + TRANSFORM(lnCant1Inainte * 2) + ;
|
||||||
|
[, pret = ] + TRANSFORM(lnPret1) + [, pret_cu_tva = 0, id_utils = ] + TRANSFORM(gnIdUtil) + ;
|
||||||
|
[, dataoras = sysdate where id_vanzare_det = ] + TRANSFORM(lnDet1) + [ and id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnRes = SQLEXEC(gnHandle, lcSql)
|
||||||
|
STRTOFILE(' PAS2 update linie pastrata det=' + TRANSFORM(lnDet1) + ' => ' + TRANSFORM(lnRes) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
IF lnRes < 0
|
||||||
|
lnSuccesFinal = -1
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
IF lnSuccesFinal > 0
|
||||||
|
lcSql = [update vanzari_detalii set sters = 0, id_utils = ] + TRANSFORM(gnIdUtil) + [, dataoras = sysdate ] + ;
|
||||||
|
[where id_vanzare_det = ] + TRANSFORM(lnDet2) + [ and id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnRes = SQLEXEC(gnHandle, lcSql)
|
||||||
|
STRTOFILE(' PAS2 update linie pastrata det=' + TRANSFORM(lnDet2) + ' => ' + TRANSFORM(lnRes) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
IF lnRes < 0
|
||||||
|
lnSuccesFinal = -1
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
IF lnSuccesFinal > 0
|
||||||
|
lcSql = [update vanzari_detalii set sters = 0, id_utils = ] + TRANSFORM(gnIdUtil) + [, dataoras = sysdate ] + ;
|
||||||
|
[where id_vanzare_det = ] + TRANSFORM(lnDet3) + [ and id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnRes = SQLEXEC(gnHandle, lcSql)
|
||||||
|
STRTOFILE(' PAS2 update linie pastrata det=' + TRANSFORM(lnDet3) + ' => ' + TRANSFORM(lnRes) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
IF lnRes < 0
|
||||||
|
lnSuccesFinal = -1
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- proba intermediara: starea NECOMISA dupa pasii 1-2, pe aceeasi conexiune
|
||||||
|
IF lnSuccesFinal > 0
|
||||||
|
lcSql = [select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ and sters = 0]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_activ')
|
||||||
|
lnNrLiniiInTranz = IIF(lnQ > 0, v_activ.nr, -1)
|
||||||
|
USE IN v_activ
|
||||||
|
lcSql = [select nvl(sters,0) as sters, cantitate from vanzari_detalii where id_vanzare_det = ] + TRANSFORM(lnDet1)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_det1')
|
||||||
|
lnStersDet1InTranz = IIF(lnQ > 0, v_det1.sters, -1)
|
||||||
|
STRTOFILE(' IN TRANZACTIE dupa pasii 1-2: linii active=' + TRANSFORM(lnNrLiniiInTranz) + ' det=' + TRANSFORM(lnDet1) + ;
|
||||||
|
' sters=' + TRANSFORM(lnStersDet1InTranz) + ' cantitate=' + IIF(lnQ > 0, TRANSFORM(v_det1.cantitate), '?') + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
USE IN v_det1
|
||||||
|
DO asserteaza WITH 'R2: dupa pasii 1-2, cele 3 linii pastrate sunt active (sters=0), NECOMIS', ;
|
||||||
|
lnNrLiniiInTranz = 3, 'linii active in tranzactie=' + TRANSFORM(lnNrLiniiInTranz)
|
||||||
|
DO asserteaza WITH 'R3: linia pastrata are cantitatea actualizata deja, NECOMIS (proba de executie partiala)', ;
|
||||||
|
lnStersDet1InTranz = 0, 'sters=' + TRANSFORM(lnStersDet1InTranz)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- PASUL 3 al helperului: INSERT linii noi (:519-530) - prima VALIDA, trebuie sa reuseasca
|
||||||
|
IF lnSuccesFinal > 0
|
||||||
|
lcSql = [insert into vanzari_detalii (id_vanzare, id_articol, cantitate, pret, pret_cu_tva, proc_tvav, ] + ;
|
||||||
|
[id_gestiune, pret_achizitie, id_utils, dataoras) values (] + TRANSFORM(tnIdVanzare) + [,] + TRANSFORM(lnArtValid) + ;
|
||||||
|
[,1,33.33,0,1.21,-1000,44.44,] + TRANSFORM(gnIdUtil) + [,sysdate)]
|
||||||
|
lnRes = SQLEXEC(gnHandle, lcSql)
|
||||||
|
STRTOFILE(' PAS3 insert linie noua VALIDA (id_articol=' + TRANSFORM(lnArtValid) + ') => ' + TRANSFORM(lnRes) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
IF lnRes < 0
|
||||||
|
lnSuccesFinal = -1
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- proba intermediara: linia noua e deja acolo, NECOMIS
|
||||||
|
IF lnSuccesFinal > 0
|
||||||
|
lcSql = [select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_cnt')
|
||||||
|
lnNrLiniiInTranz = IIF(lnQ > 0, v_cnt.nr, -1)
|
||||||
|
USE IN v_cnt
|
||||||
|
STRTOFILE(' IN TRANZACTIE dupa insertul valid: total linii=' + TRANSFORM(lnNrLiniiInTranz) + ' (erau ' + TRANSFORM(lnNrLiniiInainte) + ')' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
DO asserteaza WITH 'R4: linia noua VALIDA a fost inserata deja, NECOMIS (proba de executie partiala)', ;
|
||||||
|
lnNrLiniiInTranz = lnNrLiniiInainte + 1, 'linii=' + TRANSFORM(lnNrLiniiInTranz)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- PASUL 3, a doua linie: id_articol inexistent - trebuie sa ARUNCE ORA-02291 si sa opreasca aici
|
||||||
|
*-- (exact ce ar face SCAN-ul helperului: EXIT la primul esec, fara recalculeaza_totaluri_vanzari)
|
||||||
|
IF lnSuccesFinal > 0
|
||||||
|
lcSql = [insert into vanzari_detalii (id_vanzare, id_articol, cantitate, pret, pret_cu_tva, proc_tvav, ] + ;
|
||||||
|
[id_gestiune, pret_achizitie, id_utils, dataoras) values (] + TRANSFORM(tnIdVanzare) + [,] + TRANSFORM(lnArtLipsa) + ;
|
||||||
|
[,1,1,0,1.21,-1000,1,] + TRANSFORM(gnIdUtil) + [,sysdate)]
|
||||||
|
lnRes = SQLEXEC(gnHandle, lcSql)
|
||||||
|
STRTOFILE(' PAS3 insert linie noua INVALIDA (id_articol=' + TRANSFORM(lnArtLipsa) + ') => ' + TRANSFORM(lnRes) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
IF lnRes < 0
|
||||||
|
LOCAL laErrRb(1)
|
||||||
|
AERROR(laErrRb)
|
||||||
|
STRTOFILE(' eroare Oracle: ' + TRANSFORM(laErrRb(2)) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
DO asserteaza WITH 'R5: insertul invalid arunca eroarea asteptata (FK_VANZARE_DET002 / ORA-02291)', ;
|
||||||
|
'FK_VANZARE_DET002' $ TRANSFORM(laErrRb(2)) OR 'ORA-02291' $ TRANSFORM(laErrRb(2)), TRANSFORM(laErrRb(2))
|
||||||
|
lnSuccesFinal = -1
|
||||||
|
ELSE
|
||||||
|
DO asserteaza WITH 'R5: insertul invalid a esuat asa cum era asteptat', .F., 'lnRes=' + TRANSFORM(lnRes) + ' (nu a esuat!)'
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- pasul 4 al helperului (recalculeaza_totaluri_vanzari) NU se apeleaza aici - exact ca in helper,
|
||||||
|
*-- care s-ar opri la EXIT-ul din SCAN inainte sa ajunga la el
|
||||||
|
|
||||||
|
*-- tiparul apelantilor: lnSucces=Iif(...,1,-1) -> MyInchideTranzactie(Iif(lnSucces<0,2,1))
|
||||||
|
IF MyInchideTranzactie(IIF(lnSuccesFinal < 0, 2, 1))
|
||||||
|
STRTOFILE(' tranzactie inchisa cu ' + IIF(lnSuccesFinal < 0, 'ROLLBACK', 'COMMIT') + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' FAIL la inchiderea tranzactiei' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
CATCH TO loExc
|
||||||
|
STRTOFILE(' EXCEPTIE: ' + TRANSFORM(loExc.ErrorNo) + ' [' + loExc.Message + '] ' + ;
|
||||||
|
loExc.Procedure + ':' + TRANSFORM(loExc.LineNo) + ' -> ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
lnSuccesFinal = -99
|
||||||
|
MyInchideTranzactie(2)
|
||||||
|
ENDTRY
|
||||||
|
|
||||||
|
DO asserteaza WITH 'R6: secventa s-a oprit la insertul invalid (lnSuccesFinal<0)', lnSuccesFinal < 0, 'lnSuccesFinal=' + TRANSFORM(lnSuccesFinal)
|
||||||
|
DO asserteaza WITH 'R7: tranzactia s-a inchis cu ROLLBACK (nu COMMIT)', lnSuccesFinal < 0, 'lnSuccesFinal=' + TRANSFORM(lnSuccesFinal)
|
||||||
|
|
||||||
|
*-- verificarea de FOND: dupa rollback, documentul e EXACT cum era - pe aceeasi conexiune (prima
|
||||||
|
*-- linie de aparare); verificarea INDEPENDENTA, prin sqlplus dupa QUIT, e cea care conteaza
|
||||||
|
lcSql = [select cod from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_vz1')
|
||||||
|
lnCodDupa = IIF(lnQ > 0, v_vz1.cod, -1)
|
||||||
|
USE IN v_vz1
|
||||||
|
DO asserteaza WITH 'R8: dupa ROLLBACK, VANZARI.COD e neschimbat', lnCodDupa = lnCodInainte, TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(lnCodDupa)
|
||||||
|
|
||||||
|
lcSql = [select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_cnt1')
|
||||||
|
lnNrLiniiDupa = IIF(lnQ > 0, v_cnt1.nr, -1)
|
||||||
|
USE IN v_cnt1
|
||||||
|
DO asserteaza WITH 'R9: dupa ROLLBACK, numarul de linii ale documentului a revenit la valoarea initiala', ;
|
||||||
|
lnNrLiniiDupa = lnNrLiniiInainte, 'dupa=' + TRANSFORM(lnNrLiniiDupa) + ' inainte=' + TRANSFORM(lnNrLiniiInainte)
|
||||||
|
|
||||||
|
lcSql = [select id_vanzare_det, nvl(sters,0) as sters, nvl(cantitate,0) as cantitate, ] + ;
|
||||||
|
[nvl(pret,0) as pret, nvl(pret_achizitie,0) as pret_achizitie ] + ;
|
||||||
|
[from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ order by id_vanzare_det]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_lin1')
|
||||||
|
lcSnapshotDupa = ''
|
||||||
|
IF lnQ > 0
|
||||||
|
SELECT v_lin1
|
||||||
|
SCAN
|
||||||
|
lcSnapshotDupa = lcSnapshotDupa + TRANSFORM(id_vanzare_det) + ':' + TRANSFORM(sters) + ':' + ;
|
||||||
|
TRANSFORM(cantitate) + ':' + TRANSFORM(pret) + ':' + TRANSFORM(pret_achizitie) + '|'
|
||||||
|
ENDSCAN
|
||||||
|
ENDIF
|
||||||
|
IF USED('v_lin1')
|
||||||
|
USE IN v_lin1
|
||||||
|
ENDIF
|
||||||
|
STRTOFILE(' DUPA ROLLBACK: snapshot=[' + lcSnapshotDupa + ']' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
DO asserteaza WITH 'R10: dupa ROLLBACK, snapshot-ul liniilor (det:sters:cant:pret:pret_ach) e IDENTIC cu cel de dinaintea testului', ;
|
||||||
|
lcSnapshotDupa == lcSnapshotInainte, 'dupa=[' + lcSnapshotDupa + ']'
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
*-- mock de goExecutor pentru PARTEA M - esueaza la apelul cu numarul nFailAtCall (implicit 1 = chiar
|
||||||
|
*-- prima comanda); jurnalizeaza in crsMockSqlRb, separat de crsMockSql (folosit de alta suita)
|
||||||
|
DEFINE CLASS dummyexecutorrollback AS Custom
|
||||||
|
cEroare = ''
|
||||||
|
nFailAtCall = 1
|
||||||
|
nApeluri = 0
|
||||||
|
|
||||||
|
PROCEDURE oExecuta
|
||||||
|
LPARAMETERS tcSql, tcCursor
|
||||||
|
LOCAL lnUrmator
|
||||||
|
|
||||||
|
This.nApeluri = This.nApeluri + 1
|
||||||
|
IF !USED('crsMockSqlRb')
|
||||||
|
CREATE CURSOR crsMockSqlRb (nr I, sql M)
|
||||||
|
ENDIF
|
||||||
|
SELECT crsMockSqlRb
|
||||||
|
lnUrmator = RECCOUNT('crsMockSqlRb') + 1
|
||||||
|
INSERT INTO crsMockSqlRb (nr, sql) VALUES (m.lnUrmator, m.tcSql)
|
||||||
|
|
||||||
|
IF !EMPTY(m.tcCursor)
|
||||||
|
IF USED(m.tcCursor)
|
||||||
|
USE IN (m.tcCursor)
|
||||||
|
ENDIF
|
||||||
|
CREATE CURSOR (m.tcCursor) (id_temp N(1))
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF This.nFailAtCall > 0 AND This.nApeluri == This.nFailAtCall
|
||||||
|
This.cEroare = 'esec simulat de test la apelul ' + TRANSFORM(This.nApeluri)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
RETURN .T.
|
||||||
|
ENDPROC
|
||||||
|
ENDDEFINE
|
||||||
624
utile/Teste/editare_factura/test_s5_scriere_reala.prg
Normal file
624
utile/Teste/editare_factura/test_s5_scriere_reala.prg
Normal file
@@ -0,0 +1,624 @@
|
|||||||
|
* test_s5_scriere_reala.prg
|
||||||
|
* Test REAL de scriere in VANZARI_DETALII pentru lantul de editare a unei facturi emise -
|
||||||
|
* APROBAT explicit de Marius (09.08.2026) sa scrie in schema de dev MARIUSM_AUTO@ROA_CENTRAL.
|
||||||
|
*
|
||||||
|
* Ce dovedeste, si nu poate fi dovedit headless: pack_facturare.actualizeaza_vanzari (apelata din
|
||||||
|
* pack_contafin.finalizeaza_modificare_nota) face UPDATE VANZARI_DETALII SET STERS = 0 pe TOT
|
||||||
|
* documentul, deci INVIE liniile sterse la o editare anterioara. Idiomul "marcheaza tot sters,
|
||||||
|
* invie ce ramane" din ScrieArticoleFacturaEditate (ofacturare_editare.prg), apelat DUPA
|
||||||
|
* finalizeaza_modificare_nota si in aceeasi tranzactie, trebuie sa corecteze ambele consecinte.
|
||||||
|
*
|
||||||
|
* Ordinea testata (o singura tranzactie manuala), copiata din ofacturare_comun.vc2:3799-3837:
|
||||||
|
* do_deschide_tranzactie -> OSCRIE_IN_FISIERE(2) -> OSCRIE_IN_FISIERE(0) ->
|
||||||
|
* finalizeaza_modificare_nota -> ScrieArticoleFacturaEditate -> do_inchide_tranzactie
|
||||||
|
*
|
||||||
|
* Doua treceri pe acelasi document:
|
||||||
|
* TRECEREA 1 - o linie stearsa, o linie cu cantitatea schimbata, o linie noua adaugata.
|
||||||
|
* TRECEREA 2 - reeditare fara nicio modificare; singura care dovedeste ca linia stearsa la
|
||||||
|
* trecerea 1 RAMANE stearsa (consecinta 2 a resetului).
|
||||||
|
*
|
||||||
|
* In interiorul tranzactiei, dupa finalizeaza_modificare_nota si inainte de scrierea liniilor,
|
||||||
|
* se citeste starea necomisa a lui VANZARI_DETALII (aceeasi conexiune) - proba directa ca resetul
|
||||||
|
* STERS = 0 chiar ruleaza inainte, si ca scrierea liniilor il corecteaza dupa.
|
||||||
|
*
|
||||||
|
* Harness, nu UI: frm_modific2024 e ocolit (se blocheaza headless pe un dialog nativ - capcana j din
|
||||||
|
* testare-ui-vfp.md), buton=1 e fortat direct, deci inainte_de_do_termin NU se executa.
|
||||||
|
* do_deschide_tranzactie/do_inchide_tranzactie sunt reproduse inline dupa _frm_base.vc2:252-302.
|
||||||
|
* OSCRIE_IN_FISIERE, finalizeaza_modificare_nota si ScrieArticoleFacturaEditate ruleaza reale.
|
||||||
|
*
|
||||||
|
* CONSUMA DATE DE TEST: VANZARI.COD se realoca la fiecare salvare, iar liniile sterse raman sterse.
|
||||||
|
* Documentul e id_vanzare = 1049 (nu 1050, cel ales de descopera_caz_test pentru FACTURA_ARTICOLE).
|
||||||
|
* Nu modifica cod de aplicatie, nu atinge .PJX/.exe. QUIT la final.
|
||||||
|
|
||||||
|
SET SAFETY OFF
|
||||||
|
SET TALK OFF
|
||||||
|
|
||||||
|
LOCAL lcLog
|
||||||
|
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s5_scriere_reala_log.txt'
|
||||||
|
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
|
||||||
|
|
||||||
|
PUBLIC gcErrLog, gcTestLog, gnPass, gnFail
|
||||||
|
gcErrLog = lcLog
|
||||||
|
gcTestLog = lcLog
|
||||||
|
gnPass = 0
|
||||||
|
gnFail = 0
|
||||||
|
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||||
|
|
||||||
|
*-- mock amessagebox incarcat PRIMUL, inaintea lantului real (la nume duplicat castiga primul gasit)
|
||||||
|
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
|
||||||
|
|
||||||
|
LOCAL lnVerifMock
|
||||||
|
lnVerifMock = amessagebox('verificare mock', 4+32, 'test')
|
||||||
|
STRTOFILE('verificare mock amessagebox = ' + TRANSFORM(lnVerifMock) + ;
|
||||||
|
IIF(lnVerifMock = 6, ' (OK, mock activ)', ' (ATENTIE: amessagebox real, 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
|
||||||
|
*-- garda de referinte din do_editare_factura sta in odocumente.prg, care nu e in mediul de test
|
||||||
|
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\odocumente.prg ADDITIVE
|
||||||
|
|
||||||
|
IF TYPE('gnPC') <> 'N'
|
||||||
|
PUBLIC gnPC
|
||||||
|
gnPC = 2
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
PUBLIC gcMockUltimMesaj, gnMockUltimTip
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
gnMockUltimTip = 0
|
||||||
|
|
||||||
|
STRTOFILE('gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + ' gnIdUtil=' + TRANSFORM(gnIdUtil) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
|
||||||
|
*-- valorile alese pentru linia noua; pret_achizitie distinctiv, ca sa se poata urmari peste treceri
|
||||||
|
PUBLIC gnPretAchNou, gnCantNoua, gnPretNou
|
||||||
|
gnPretAchNou = 77.77
|
||||||
|
gnCantNoua = 3
|
||||||
|
gnPretNou = 50
|
||||||
|
|
||||||
|
PUBLIC gnIdVanzareTest
|
||||||
|
gnIdVanzareTest = 1049
|
||||||
|
|
||||||
|
*-- liniile urmarite peste ambele treceri: la trecerea 2 documentul se reincarca din Oracle, iar
|
||||||
|
*-- linia stearsa nu mai e in tvd - identitatea ei trebuie pastrata din trecerea 1
|
||||||
|
PUBLIC gnDetModificat, gnDetSters, gnDetNou
|
||||||
|
gnDetModificat = 0
|
||||||
|
gnDetSters = 0
|
||||||
|
gnDetNou = 0
|
||||||
|
|
||||||
|
*-- starea de plecare, inainte de orice scriere
|
||||||
|
DO LogStareLinii WITH 'STARE INITIALA', gnIdVanzareTest, lcLog
|
||||||
|
|
||||||
|
DO ruleaza_trecere WITH gnIdVanzareTest, 'TRECEREA 1 - sterge o linie, schimba o cantitate, adauga o linie', .T., lcLog
|
||||||
|
DO ruleaza_trecere WITH gnIdVanzareTest, 'TRECEREA 2 - reeditare fara nicio modificare', .F., lcLog
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + 'REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
QUIT
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE asserteaza
|
||||||
|
LPARAMETERS tcNume, tlConditie, tcValoare
|
||||||
|
|
||||||
|
IF m.tlConditie
|
||||||
|
gnPass = gnPass + 1
|
||||||
|
STRTOFILE('PASS ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ELSE
|
||||||
|
gnFail = gnFail + 1
|
||||||
|
STRTOFILE('FAIL ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- executa SELECT-ul prin goExecutor si intoarce codul de succes; cursorul vechi se inchide intai
|
||||||
|
PROCEDURE ExecSel
|
||||||
|
LPARAMETERS tcSql, tcCursor
|
||||||
|
LOCAL lnQ
|
||||||
|
IF USED(tcCursor)
|
||||||
|
USE IN (tcCursor)
|
||||||
|
ENDIF
|
||||||
|
lnQ = goExecutor.oExecute(tcSql, tcCursor)
|
||||||
|
RETURN lnQ
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- logheaza starea tuturor liniilor documentului (inclusiv cele sterse); folosit si INTRE pasii
|
||||||
|
*-- tranzactiei manuale - citirea merge pe aceeasi conexiune, deci vede si ce nu e inca comis
|
||||||
|
PROCEDURE LogStareLinii
|
||||||
|
LPARAMETERS tcEticheta, tnIdVanzare, tcLog
|
||||||
|
|
||||||
|
LOCAL lcSql, lnQ, lcRand
|
||||||
|
lcSql = [select id_vanzare_det, nvl(sters,0) as sters, nvl(cantitate,0) as cantitate, ] + ;
|
||||||
|
[nvl(pret,0) as pret, nvl(pret_achizitie,0) as pret_achizitie ] + ;
|
||||||
|
[from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ order by id_vanzare_det]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_stare')
|
||||||
|
IF lnQ <= 0
|
||||||
|
STRTOFILE(' [' + tcEticheta + '] EROARE citire linii: ' + ALLTRIM(TRANSFORM(NVL(goExecutor.cEroare, ''))) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
lcRand = ' [' + tcEticheta + '] linii:' + CHR(13) + CHR(10)
|
||||||
|
SELECT v_stare
|
||||||
|
SCAN
|
||||||
|
lcRand = lcRand + ' det=' + TRANSFORM(id_vanzare_det) + ' sters=' + TRANSFORM(sters) + ;
|
||||||
|
' cant=' + TRANSFORM(cantitate) + ' pret=' + TRANSFORM(pret) + ' pret_ach=' + TRANSFORM(pret_achizitie) + CHR(13) + CHR(10)
|
||||||
|
ENDSCAN
|
||||||
|
STRTOFILE(lcRand, tcLog, 1)
|
||||||
|
USE IN v_stare
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
*-- citeste STERS de pe o linie anume, direct din Oracle (si necomis, in tranzactie); -1 = eroare/lipsa
|
||||||
|
PROCEDURE CitesteSters
|
||||||
|
LPARAMETERS tnIdVanzareDet
|
||||||
|
LOCAL lcSql, lnQ, lnRez
|
||||||
|
lnRez = -1
|
||||||
|
lcSql = [select nvl(sters,0) as sters from vanzari_detalii where id_vanzare_det = ] + TRANSFORM(tnIdVanzareDet)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_unsters')
|
||||||
|
IF lnQ > 0 AND RECCOUNT('v_unsters') = 1
|
||||||
|
lnRez = v_unsters.sters
|
||||||
|
ENDIF
|
||||||
|
IF USED('v_unsters')
|
||||||
|
USE IN v_unsters
|
||||||
|
ENDIF
|
||||||
|
RETURN lnRez
|
||||||
|
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 ruleaza_trecere
|
||||||
|
LPARAMETERS tnIdVanzare, tcEticheta, tlAplicaModificari, tcLog
|
||||||
|
|
||||||
|
*-- pnAn/pnLuna/lnCod/lnIdFact PRIVATE (nu LOCAL), ca in ofacturare_comun.vc2:3730 -
|
||||||
|
*-- finalizeaza_modificare_nota le foloseste ca bind-variabile ?pnLuna/?pnAn in josul stivei
|
||||||
|
PRIVATE pnAn, pnLuna, lnCod, lnIdFact
|
||||||
|
LOCAL lnSters, llEProforma, lnIdSet, lnIdFactD, lnSucces, llGasitRand
|
||||||
|
LOCAL lcSql, lnQ, lnI
|
||||||
|
LOCAL lnDetModificat, lnDetSters, lnDetPastrat, lnCantVecheMod, lnPretAchMod
|
||||||
|
LOCAL lnMaxDetInainte, lnNrActiveInainte
|
||||||
|
LOCAL lnCodInainte, lnTotFtvaInainte, lnTotTvaInainte, lnTotCtvaInainte
|
||||||
|
LOCAL lnStersProbaDupaFinalizeaza, lnStersProbaDupaScriere
|
||||||
|
LOCAL lnCodDupa, lnStersDupa, lnTotFtvaDupa, lnTotTvaDupa, lnTotCtvaDupa
|
||||||
|
LOCAL lnDetNou, lnPretAchNouDupa, lnCantModDupa, lnPretAchModDupa, lnStersModDupa
|
||||||
|
LOCAL lnNrActiveDupa, lnBrutAsteptat, lnStersNouUrmarit, lnPretAchNouUrmarit
|
||||||
|
|
||||||
|
STRTOFILE(CHR(13) + CHR(10) + '========== ' + tcEticheta + ' (id_vanzare=' + TRANSFORM(tnIdVanzare) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
*-- 1) starea documentului din VANZARI (cod-ul se realoca la fiecare salvare)
|
||||||
|
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 = ExecSel(lcSql, 'v_vz_inainte')
|
||||||
|
IF lnQ <= 0 OR RECCOUNT('v_vz_inainte') <> 1
|
||||||
|
DO asserteaza WITH tcEticheta + ': VANZARI citit', .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
SELECT v_vz_inainte
|
||||||
|
lnCod = cod
|
||||||
|
lnSters = sters
|
||||||
|
lnIdFact = id_fact
|
||||||
|
llEProforma = (NVL(eproforma, 0) = 1)
|
||||||
|
pnAn = anact
|
||||||
|
pnLuna = lunaact
|
||||||
|
lnCodInainte = cod
|
||||||
|
lnTotFtvaInainte = total_fara_tva
|
||||||
|
lnTotTvaInainte = total_tva
|
||||||
|
lnTotCtvaInainte = total_cu_tva
|
||||||
|
USE IN v_vz_inainte
|
||||||
|
|
||||||
|
STRTOFILE(' VANZARI inainte: cod=' + TRANSFORM(lnCod) + ' sters=' + TRANSFORM(lnSters) + ' id_fact=' + TRANSFORM(lnIdFact) + ;
|
||||||
|
' an/luna=' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ' total_ftva=' + TRANSFORM(lnTotFtvaInainte) + ;
|
||||||
|
' total_tva=' + TRANSFORM(lnTotTvaInainte) + ' total_ctva=' + TRANSFORM(lnTotCtvaInainte) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
*-- 2) garzile din do_editare_factura (ofacturare_comun.vc2:3742-3767), fara UI
|
||||||
|
IF lnSters = 1 OR llEProforma
|
||||||
|
DO asserteaza WITH tcEticheta + ': document editabil (nesters, neproforma)', .F., 'sters=' + TRANSFORM(lnSters)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
IF (pnAn*12) + pnLuna <> (gnAn*12) + gnLuna
|
||||||
|
DO asserteaza WITH tcEticheta + ': document din luna curenta', .F., TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
IF ReferinteDocumenteNota(pnAn, pnLuna, lnCod) OR EsteInEFactura(lnIdFact)
|
||||||
|
DO asserteaza WITH tcEticheta + ': document fara referinte / netrimis in eFactura', .F., 'blocat de garda'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 3) instantaneul liniilor inainte de editare
|
||||||
|
lcSql = [select count(*) as nr, max(id_vanzare_det) as maxdet from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_max')
|
||||||
|
lnMaxDetInainte = IIF(lnQ > 0, NVL(v_max.maxdet, 0), 0)
|
||||||
|
IF USED('v_max')
|
||||||
|
USE IN v_max
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 4) cursoarele notei, exact ca do_editare_factura
|
||||||
|
IF !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.)
|
||||||
|
DO asserteaza WITH tcEticheta + ': IncarcaCursoareModificareNota', .F., 'a esuat'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
IF RECCOUNT('actactan') = 0
|
||||||
|
DO asserteaza WITH tcEticheta + ': exista nota contabila', .F., 'Reccount(actactan)=0'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
SELECT a.*, IIF(NVL(id_jtva_coloana, 0) = 0, 0, 1) AS cu_Tva FROM tact a INTO CURSOR tact READWRITE
|
||||||
|
|
||||||
|
*-- 5) tvanz + tvd, cursoarele pe care le lasa calea reala inainte de Createobject(frm_modific2024)
|
||||||
|
IF !IncarcaVanzareDinNota('tact')
|
||||||
|
DO asserteaza WITH tcEticheta + ': IncarcaVanzareDinNota', .F., 'nu a gasit randul din VANZARI'
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
IncarcaArticoleFactura(tnIdVanzare, 'tvd')
|
||||||
|
lnNrActiveInainte = RECCOUNT('tvd')
|
||||||
|
STRTOFILE(' tvd incarcat cu ' + TRANSFORM(lnNrActiveInainte) + ' linii active; tvanz.id_vanzare=' + TRANSFORM(tvanz.id_vanzare) + ;
|
||||||
|
' discount=' + TRANSFORM(NVL(tvanz.discount, 0)) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
IF lnNrActiveInainte < 3
|
||||||
|
DO asserteaza WITH tcEticheta + ': documentul are cel putin 3 linii active', .F., TRANSFORM(lnNrActiveInainte)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 6) editarile utilizatorului, aplicate pe tvd exact cum le lasa pagina de articole:
|
||||||
|
*-- randul 1 primeste cantitate dubla, randul 2 e marcat sters (sters=1, ramane in cursor),
|
||||||
|
*-- randul 3 ramane neatins, plus o linie noua cu id_vanzare_det = 0
|
||||||
|
lnDetPastrat = 0
|
||||||
|
lnCantVecheMod = 0
|
||||||
|
lnPretAchMod = 0
|
||||||
|
|
||||||
|
IF tlAplicaModificari
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
gnDetModificat = id_vanzare_det
|
||||||
|
lnCantVecheMod = NVL(cantitate, 0)
|
||||||
|
lnPretAchMod = NVL(pret_achizitie, 0)
|
||||||
|
SKIP
|
||||||
|
gnDetSters = id_vanzare_det
|
||||||
|
SKIP
|
||||||
|
lnDetPastrat = id_vanzare_det
|
||||||
|
ELSE
|
||||||
|
*-- linia stearsa la trecerea 1 nu mai e in tvd; identitatile vin din trecerea 1
|
||||||
|
SELECT tvd
|
||||||
|
LOCATE FOR id_vanzare_det = gnDetModificat
|
||||||
|
IF !FOUND()
|
||||||
|
DO asserteaza WITH tcEticheta + ': linia editata la trecerea 1 e reincarcata', .F., 'det=' + TRANSFORM(gnDetModificat)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
lnCantVecheMod = NVL(cantitate, 0)
|
||||||
|
lnPretAchMod = NVL(pret_achizitie, 0)
|
||||||
|
ENDIF
|
||||||
|
lnDetModificat = gnDetModificat
|
||||||
|
lnDetSters = gnDetSters
|
||||||
|
|
||||||
|
IF tlAplicaModificari
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
REPLACE cantitate WITH lnCantVecheMod * 2, lmodificat WITH .T.
|
||||||
|
SKIP
|
||||||
|
REPLACE sters WITH 1, lmodificat WITH .T.
|
||||||
|
|
||||||
|
*-- linia noua: coloanele care conteaza pentru INSERT se iau de pe prima linie, ca sa fie
|
||||||
|
*-- coerenta cu documentul (cota TVA, jurnal, valuta, cont); gestiunea e cea a adaugarii
|
||||||
|
*-- din dialog (gnScadereStoc = 0 -> id_gestiune = -1000)
|
||||||
|
LOCAL lnArtNou, lnPretCuTvaNou, lnProcTvavNou, lnIdValNou, lnJtvaNou, lnTaxcodeNou, lcContNou
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
lnArtNou = id_articol
|
||||||
|
lnPretCuTvaNou = NVL(pret_cu_tva, 0)
|
||||||
|
lnProcTvavNou = NVL(proc_tvav, 1)
|
||||||
|
lnIdValNou = id_valuta
|
||||||
|
lnJtvaNou = id_jtva_coloana
|
||||||
|
lnTaxcodeNou = taxcode
|
||||||
|
lcContNou = NVL(cont, '')
|
||||||
|
|
||||||
|
APPEND BLANK IN tvd
|
||||||
|
REPLACE id_vanzare WITH tnIdVanzare, id_vanzare_det WITH 0, id_articol WITH lnArtNou, ;
|
||||||
|
cantitate WITH gnCantNoua, pret WITH gnPretNou, pret_cu_tva WITH lnPretCuTvaNou, ;
|
||||||
|
proc_tvav WITH lnProcTvavNou, discount_unitar WITH 0, id_gestiune WITH -1000, ;
|
||||||
|
cont WITH lcContNou, id_valuta WITH lnIdValNou, id_jtva_coloana WITH lnJtvaNou, ;
|
||||||
|
taxcode WITH lnTaxcodeNou, sters WITH 0, pret_achizitie WITH gnPretAchNou, ;
|
||||||
|
lmodificat WITH .T. IN tvd
|
||||||
|
|
||||||
|
STRTOFILE(' editari in tvd: det=' + TRANSFORM(lnDetModificat) + ' cantitate ' + TRANSFORM(lnCantVecheMod) + ;
|
||||||
|
' -> ' + TRANSFORM(lnCantVecheMod * 2) + ' (pret_achizitie ramane ' + TRANSFORM(lnPretAchMod) + ')' + CHR(13) + CHR(10) + ;
|
||||||
|
' det=' + TRANSFORM(lnDetSters) + ' marcata stearsa (tvd.sters=1)' + CHR(13) + CHR(10) + ;
|
||||||
|
' det=' + TRANSFORM(lnDetPastrat) + ' neatinsa' + CHR(13) + CHR(10) + ;
|
||||||
|
' linie noua: id_articol=' + TRANSFORM(lnArtNou) + ' cantitate=' + TRANSFORM(gnCantNoua) + ;
|
||||||
|
' pret=' + TRANSFORM(gnPretNou) + ' pret_achizitie=' + TRANSFORM(gnPretAchNou) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' tvd nemodificat: det ' + TRANSFORM(lnDetModificat) + ' / ' + TRANSFORM(lnDetSters) + ' / ' + ;
|
||||||
|
TRANSFORM(lnDetPastrat) + ' (linia stearsa la trecerea 1 nici nu mai e incarcata)' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 7) frm_modific2024 ocolit, buton=1 fortat (inainte_de_do_termin NU se executa)
|
||||||
|
buton = 1
|
||||||
|
|
||||||
|
*-- 8) ramura buton=1 din do_editare_factura (ofacturare_comun.vc2:3799-3837), copiata identic;
|
||||||
|
*-- do_deschide/inchide_tranzactie sunt reproduse inline (MyDeschide/MyInchideTranzactie)
|
||||||
|
lnSucces = 0
|
||||||
|
lnStersProbaDupaFinalizeaza = -1
|
||||||
|
lnStersProbaDupaScriere = -1
|
||||||
|
TRY
|
||||||
|
IF MyDeschideTranzactie()
|
||||||
|
SELECT actactan
|
||||||
|
lnSucces = OSCRIE_IN_FISIERE(2, .T., .T.)
|
||||||
|
STRTOFILE(' OSCRIE_IN_FISIERE(2,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
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.)
|
||||||
|
STRTOFILE(' OSCRIE_IN_FISIERE(0,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
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)
|
||||||
|
STRTOFILE(' finalizeaza_modificare_nota => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- PROBA DE ORDONARE: starea necomisa, dupa finalizeaza_modificare_nota si INAINTE de
|
||||||
|
*-- scrierea liniilor - aici se vede resetul STERS = 0 din actualizeaza_vanzari
|
||||||
|
IF lnSucces > 0
|
||||||
|
DO LogStareLinii WITH 'IN TRANZACTIE, dupa finalizeaza_modificare_nota', tnIdVanzare, tcLog
|
||||||
|
IF lnDetSters > 0
|
||||||
|
lnStersProbaDupaFinalizeaza = CitesteSters(lnDetSters)
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- blocul nou, identic cu ofacturare_comun.vc2:3828-3830 si comun.vc2:2491
|
||||||
|
IF lnSucces > 0 AND "OFACTURARE_EDITARE" $ UPPER(SET("Procedure")) AND USED('tvanz') AND RECCOUNT('tvanz') = 1
|
||||||
|
lnSucces = IIF(ScrieArticoleFacturaEditate(tvanz.id_vanzare), 1, -1)
|
||||||
|
STRTOFILE(' ScrieArticoleFacturaEditate => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' ATENTIE: blocul ScrieArticoleFacturaEditate NU s-a executat' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF lnSucces > 0
|
||||||
|
DO LogStareLinii WITH 'IN TRANZACTIE, dupa ScrieArticoleFacturaEditate', tnIdVanzare, tcLog
|
||||||
|
IF lnDetSters > 0
|
||||||
|
lnStersProbaDupaScriere = CitesteSters(lnDetSters)
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
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 inchiderea tranzactiei' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
ENDIF
|
||||||
|
ELSE
|
||||||
|
STRTOFILE(' FAIL: deschiderea tranzactiei 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
|
||||||
|
|
||||||
|
DO asserteaza WITH tcEticheta + ': lantul de scriere a mers pana la capat (lnSucces>0, COMMIT)', ;
|
||||||
|
lnSucces > 0, 'lnSucces=' + TRANSFORM(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
|
||||||
|
|
||||||
|
IF lnSucces <= 0
|
||||||
|
STRTOFILE(' scrierea nu s-a produs - fara verificari dupa' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- 9) verificarile de dupa commit
|
||||||
|
DO LogStareLinii WITH 'DUPA COMMIT', tnIdVanzare, tcLog
|
||||||
|
|
||||||
|
*-- proba de ordonare, singura care nu poate fi obtinuta din afara tranzactiei
|
||||||
|
DO asserteaza WITH tcEticheta + ': resetul STERS=0 din actualizeaza_vanzari a rulat inainte de scrierea liniilor', ;
|
||||||
|
lnStersProbaDupaFinalizeaza = 0, 'sters pe det=' + TRANSFORM(lnDetSters) + ' dupa finalizeaza = ' + TRANSFORM(lnStersProbaDupaFinalizeaza)
|
||||||
|
|
||||||
|
*-- starea liniilor dupa commit
|
||||||
|
lcSql = [select id_vanzare_det, nvl(sters,0) as sters, nvl(cantitate,0) as cantitate, ] + ;
|
||||||
|
[nvl(pret,0) as pret, nvl(pret_achizitie,0) as pret_achizitie ] + ;
|
||||||
|
[from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ order by id_vanzare_det]
|
||||||
|
lnQ = ExecSel(lcSql, 'v_dupa')
|
||||||
|
IF lnQ <= 0
|
||||||
|
DO asserteaza WITH tcEticheta + ': citirea liniilor dupa commit', .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
lnStersModDupa = -1
|
||||||
|
lnCantModDupa = -1
|
||||||
|
lnPretAchModDupa = -1
|
||||||
|
lnDetNou = 0
|
||||||
|
lnPretAchNouDupa = -1
|
||||||
|
lnStersNouUrmarit = -1
|
||||||
|
lnPretAchNouUrmarit = -1
|
||||||
|
lnNrActiveDupa = 0
|
||||||
|
lnBrutAsteptat = 0
|
||||||
|
|
||||||
|
SELECT v_dupa
|
||||||
|
SCAN
|
||||||
|
IF sters = 0
|
||||||
|
lnNrActiveDupa = lnNrActiveDupa + 1
|
||||||
|
lnBrutAsteptat = lnBrutAsteptat + ROUND(cantitate * pret, 2)
|
||||||
|
ENDIF
|
||||||
|
IF id_vanzare_det = lnDetModificat
|
||||||
|
lnStersModDupa = sters
|
||||||
|
lnCantModDupa = cantitate
|
||||||
|
lnPretAchModDupa = pret_achizitie
|
||||||
|
ENDIF
|
||||||
|
IF id_vanzare_det > lnMaxDetInainte
|
||||||
|
lnDetNou = id_vanzare_det
|
||||||
|
lnPretAchNouDupa = pret_achizitie
|
||||||
|
ENDIF
|
||||||
|
*-- linia adaugata la trecerea 1, urmarita si la trecerea 2 (acolo e deja linie existenta)
|
||||||
|
IF gnDetNou > 0 AND id_vanzare_det = gnDetNou
|
||||||
|
lnStersNouUrmarit = sters
|
||||||
|
lnPretAchNouUrmarit = pret_achizitie
|
||||||
|
ENDIF
|
||||||
|
ENDSCAN
|
||||||
|
USE IN v_dupa
|
||||||
|
|
||||||
|
*-- linia marcata stearsa: STERS=1 dupa ce s-a intors finalizeaza_modificare_nota
|
||||||
|
LOCAL lnStersDetSters
|
||||||
|
lnStersDetSters = CitesteSters(lnDetSters)
|
||||||
|
DO asserteaza WITH tcEticheta + ': linia marcata stearsa are STERS=1 in VANZARI_DETALII', ;
|
||||||
|
lnStersDetSters = 1, 'det=' + TRANSFORM(lnDetSters) + ' sters=' + TRANSFORM(lnStersDetSters)
|
||||||
|
|
||||||
|
*-- si dovada ca scrierea liniilor e cea care a corectat resetul
|
||||||
|
DO asserteaza WITH tcEticheta + ': ScrieArticoleFacturaEditate a re-marcat linia stearsa in aceeasi tranzactie', ;
|
||||||
|
lnStersProbaDupaScriere = 1, 'sters pe det=' + TRANSFORM(lnDetSters) + ' dupa scriere = ' + TRANSFORM(lnStersProbaDupaScriere)
|
||||||
|
|
||||||
|
*-- liniile pastrate raman active, cu cantitatea editata
|
||||||
|
DO asserteaza WITH tcEticheta + ': linia pastrata e activa cu cantitatea editata', ;
|
||||||
|
lnStersModDupa = 0 AND ABS(lnCantModDupa - IIF(tlAplicaModificari, lnCantVecheMod * 2, lnCantVecheMod)) < 0.001, ;
|
||||||
|
'det=' + TRANSFORM(lnDetModificat) + ' sters=' + TRANSFORM(lnStersModDupa) + ' cant=' + TRANSFORM(lnCantModDupa)
|
||||||
|
|
||||||
|
*-- PRET_ACHIZITIE pe linia existenta ramane neatins (omis din SET-ul de UPDATE)
|
||||||
|
DO asserteaza WITH tcEticheta + ': PRET_ACHIZITIE pe linia existenta editata a ramas neatins', ;
|
||||||
|
ABS(lnPretAchModDupa - lnPretAchMod) < 0.0001, ;
|
||||||
|
'det=' + TRANSFORM(lnDetModificat) + ' inainte=' + TRANSFORM(lnPretAchMod) + ' dupa=' + TRANSFORM(lnPretAchModDupa)
|
||||||
|
|
||||||
|
IF tlAplicaModificari
|
||||||
|
*-- linia noua a intrat prin INSERT, cu ID_VANZARE_DET alocat de trigger
|
||||||
|
DO asserteaza WITH tcEticheta + ': linia noua a fost inserata cu ID_VANZARE_DET alocat de trigger', ;
|
||||||
|
lnDetNou > lnMaxDetInainte, 'det nou=' + TRANSFORM(lnDetNou) + ' (max inainte=' + TRANSFORM(lnMaxDetInainte) + ')'
|
||||||
|
DO asserteaza WITH tcEticheta + ': linia noua are PRET_ACHIZITIE exact valoarea tastata', ;
|
||||||
|
ABS(lnPretAchNouDupa - gnPretAchNou) < 0.0001, 'pret_achizitie=' + TRANSFORM(lnPretAchNouDupa) + ' (tastat ' + TRANSFORM(gnPretAchNou) + ')'
|
||||||
|
DO asserteaza WITH tcEticheta + ': documentul are 3 linii active (una stearsa, una noua)', ;
|
||||||
|
lnNrActiveDupa = 3, 'active=' + TRANSFORM(lnNrActiveDupa)
|
||||||
|
gnDetNou = lnDetNou
|
||||||
|
ELSE
|
||||||
|
DO asserteaza WITH tcEticheta + ': nicio linie noua nu a fost inserata', ;
|
||||||
|
lnDetNou = 0, 'det peste maximul dinainte=' + TRANSFORM(lnDetNou)
|
||||||
|
DO asserteaza WITH tcEticheta + ': numarul de linii active nu s-a schimbat', ;
|
||||||
|
lnNrActiveDupa = lnNrActiveInainte, 'active=' + TRANSFORM(lnNrActiveDupa) + ' (erau ' + TRANSFORM(lnNrActiveInainte) + ')'
|
||||||
|
DO asserteaza WITH tcEticheta + ': linia adaugata la trecerea 1 e activa si la reeditare', ;
|
||||||
|
lnStersNouUrmarit = 0, 'det=' + TRANSFORM(gnDetNou) + ' sters=' + TRANSFORM(lnStersNouUrmarit)
|
||||||
|
DO asserteaza WITH tcEticheta + ': PRET_ACHIZITIE al liniei adaugate la trecerea 1 a ramas neatins', ;
|
||||||
|
ABS(lnPretAchNouUrmarit - gnPretAchNou) < 0.0001, ;
|
||||||
|
'det=' + TRANSFORM(gnDetNou) + ' pret_achizitie=' + TRANSFORM(lnPretAchNouUrmarit) + ' (tastat ' + TRANSFORM(gnPretAchNou) + ')'
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- totalurile din VANZARI dupa recalculeaza_totaluri_vanzari
|
||||||
|
lcSql = [select cod, nvl(sters,0) as sters, total_fara_tva, total_tva, total_cu_tva from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
|
||||||
|
lnQ = ExecSel(lcSql, 'v_vz_dupa')
|
||||||
|
IF lnQ <= 0 OR RECCOUNT('v_vz_dupa') <> 1
|
||||||
|
DO asserteaza WITH tcEticheta + ': VANZARI citit dupa commit', .F., 'lnQ=' + TRANSFORM(lnQ)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
SELECT v_vz_dupa
|
||||||
|
lnCodDupa = cod
|
||||||
|
lnStersDupa = sters
|
||||||
|
lnTotFtvaDupa = total_fara_tva
|
||||||
|
lnTotTvaDupa = total_tva
|
||||||
|
lnTotCtvaDupa = total_cu_tva
|
||||||
|
USE IN v_vz_dupa
|
||||||
|
|
||||||
|
STRTOFILE(' VANZARI dupa: cod=' + TRANSFORM(lnCodDupa) + ' (era ' + TRANSFORM(lnCodInainte) + ') sters=' + TRANSFORM(lnStersDupa) + ;
|
||||||
|
' total_ftva=' + TRANSFORM(lnTotFtvaDupa) + ' total_tva=' + TRANSFORM(lnTotTvaDupa) + ;
|
||||||
|
' total_ctva=' + TRANSFORM(lnTotCtvaDupa) + ' (brut din linii active=' + TRANSFORM(lnBrutAsteptat) + ')' + CHR(13) + CHR(10), tcLog, 1)
|
||||||
|
|
||||||
|
DO asserteaza WITH tcEticheta + ': VANZARI.COD realocat, documentul ramane activ', ;
|
||||||
|
lnCodDupa <> lnCodInainte AND lnStersDupa = 0, TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(lnCodDupa)
|
||||||
|
|
||||||
|
DO asserteaza WITH tcEticheta + ': totalurile din VANZARI sunt coerente (fara_tva + tva = cu_tva)', ;
|
||||||
|
ABS((lnTotFtvaDupa + lnTotTvaDupa) - lnTotCtvaDupa) < 0.01, ;
|
||||||
|
TRANSFORM(lnTotFtvaDupa) + ' + ' + TRANSFORM(lnTotTvaDupa) + ' = ' + TRANSFORM(lnTotCtvaDupa)
|
||||||
|
|
||||||
|
*-- toate liniile documentului au preturile cu TVA (pret_cu_tva=1), deci totalul brut al
|
||||||
|
*-- documentului e suma cantitate*pret pe liniile active - relatie verificata si inainte de editare
|
||||||
|
DO asserteaza WITH tcEticheta + ': total_cu_tva corespunde liniilor active dupa recalcul', ;
|
||||||
|
ABS(lnTotCtvaDupa - lnBrutAsteptat) < 0.01, ;
|
||||||
|
'total_cu_tva=' + TRANSFORM(lnTotCtvaDupa) + ' suma linii active=' + TRANSFORM(lnBrutAsteptat)
|
||||||
|
|
||||||
|
IF USED('tvd')
|
||||||
|
USE IN tvd
|
||||||
|
ENDIF
|
||||||
|
IF USED('tvanz')
|
||||||
|
USE IN tvanz
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
STRTOFILE(' REZUMAT ' + tcEticheta + ': cod ' + TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(lnCodDupa) + 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
|
||||||
588
utile/Teste/editare_factura/test_s5_validari_articole.prg
Normal file
588
utile/Teste/editare_factura/test_s5_validari_articole.prg
Normal file
@@ -0,0 +1,588 @@
|
|||||||
|
* test_s5_validari_articole.prg
|
||||||
|
* Acopera S5 (scrierea sumelor editate in Oracle - decizii 38-41, docs\handoff_s5.md), functionalitate
|
||||||
|
* NETESTATA la data scrierii acestui fisier (niciun test nu atingea inca pret_achizitie/id_vanzare_set
|
||||||
|
* sau helperul de scriere). Doua sectiuni independente:
|
||||||
|
*
|
||||||
|
* A) Cele 5 validari noi din frm_modific2024.inainte_de_do_termin (omodificari.vc2:14328-14366),
|
||||||
|
* apelate DIRECT pe o instanta reala (nu prin UI): cantitate<=0, pret NULL, id_articol nul/0
|
||||||
|
* blocheaza (RETURN .F.); zero linii active cu document in VANZARI si linie noua cu pret_achizitie
|
||||||
|
* 0/NULL cer CONFIRMARE (amessagebox 4+32), nu blocare - ambele ramuri (Da continua, Nu opreste)
|
||||||
|
* sunt verificate, plus un caz de control (cursor valid, nicio validare nu se declanseaza).
|
||||||
|
* Documentul e real (FACTURA_ARTICOLE, descoperit prin proprietate - descopera_caz_test.prg),
|
||||||
|
* tvd e mutat manual intre stari valide/invalide si restaurat dupa fiecare sub-caz.
|
||||||
|
*
|
||||||
|
* B) Garda de no-op si SQL-ul generat de ScrieArticoleFacturaEditate (ofacturare_editare.prg) -
|
||||||
|
* complet headless, PE CURSOARE CONSTRUITE IN TEST (crstvdtest/crstvanztest, structura reala din
|
||||||
|
* CreeazaCursorArticoleGol), FARA Oracle: goExecutor e inlocuit cu un mock (dummyexecutor) care
|
||||||
|
* doar inregistreaza textul comenzilor intr-un cursor si intoarce o valoare configurabila -
|
||||||
|
* goExecutor real (conectat la MARIUSM_AUTO) ramane neatins tot timpul sectiunii B.
|
||||||
|
* Garda de no-op: tnIdVanzare<=0, alias articole neinchis, alias vanzare fara exact 1 rand,
|
||||||
|
* Reccount(alias articole)=0 (cazul critic - un esec de incarcare Oracle NU trebuie sa goleasca
|
||||||
|
* factura, vezi handoff_s5.md "Cale de pierdere de date, inchisa") - toate patru trebuie sa intoarca
|
||||||
|
* .T. FARA sa apeleze goExecutor.oExecuta vreodata.
|
||||||
|
* Clasificarea liniilor (pastrata/noua/noua-si-stearsa/stearsa/componenta de set) e verificata prin
|
||||||
|
* SQL-ul efectiv generat de helper pe un cursor cu cate un rand din fiecare categorie.
|
||||||
|
* Oprirea la primul esec Oracle e verificata explicit (mock configurat sa esueze la un apel anume).
|
||||||
|
*
|
||||||
|
* Nu scrie in Oracle (mock pe goExecutor in sectiunea B; sectiunea A nu apeleaza deloc scriere -
|
||||||
|
* inainte_de_do_termin e doar validare). Nu da COMMIT. QUIT la final.
|
||||||
|
|
||||||
|
SET SAFETY OFF
|
||||||
|
SET TALK OFF
|
||||||
|
|
||||||
|
LOCAL lcLog
|
||||||
|
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s5_validari_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()
|
||||||
|
|
||||||
|
*!* mock amessagebox INCARCAT PRIMUL (testare-ui-vfp.md, capcana g - verificat pe teren in
|
||||||
|
*!* test_writeback_buton1.prg, acelasi folder): la nume duplicat de procedura VFP foloseste
|
||||||
|
*!* fisierul cautat PRIMUL, deci trebuie deschis inaintea lantului din test_init_env_auto
|
||||||
|
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
|
||||||
|
|
||||||
|
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||||
|
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\descopera_caz_test.prg ADDITIVE
|
||||||
|
|
||||||
|
*!* test_init_env_auto incarca clasa omodificari din working copy-ul ROACONT (alt SET PATH) -
|
||||||
|
*!* o eliberam si o reincarcam pe cea DE SUB TEST, cu cale completa
|
||||||
|
RELEASE CLASSLIB omodificari
|
||||||
|
SET CLASSLIB TO D:\ROA\ROAFACTURARE\COMUN\clase\omodificari.vcx ADDITIVE
|
||||||
|
|
||||||
|
PUBLIC gnPass, gnFail
|
||||||
|
gnPass = 0
|
||||||
|
gnFail = 0
|
||||||
|
|
||||||
|
PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
|
||||||
|
gnMockRaspuns = 6
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
gnMockUltimTip = 0
|
||||||
|
|
||||||
|
LOCAL lnVerifMock
|
||||||
|
lnVerifMock = amessagebox('verificare mock', 4+32, 'test')
|
||||||
|
DO asserteaza WITH 'mock amessagebox activ (umbreste amessagebox real)', lnVerifMock == 6, TRANSFORM(lnVerifMock)
|
||||||
|
|
||||||
|
|
||||||
|
*============================================================================================
|
||||||
|
* SECTIUNEA A - validarile din inainte_de_do_termin, pe o instanta reala frm_modific2024
|
||||||
|
*============================================================================================
|
||||||
|
|
||||||
|
LOCAL llCazA
|
||||||
|
llCazA = DescoperaCazTest('FACTURA_ARTICOLE', 'crscaz_a')
|
||||||
|
IF !llCazA
|
||||||
|
STRTOFILE('EROARE: cazul FACTURA_ARTICOLE nu a fost gasit' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
QUIT
|
||||||
|
ENDIF
|
||||||
|
STRTOFILE('caz A: cod=' + TRANSFORM(crscaz_a.cod) + ' an=' + TRANSFORM(crscaz_a.an) + ' luna=' + TRANSFORM(crscaz_a.luna) + ;
|
||||||
|
' id_vanzare=' + TRANSFORM(crscaz_a.id_vanzare) + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
|
||||||
|
LOCAL llOk, lnIdSet, loForm
|
||||||
|
|
||||||
|
llOk = IncarcaCursoareModificareNota(crscaz_a.cod, crscaz_a.an, crscaz_a.luna, .F.)
|
||||||
|
IF !llOk OR !Used('tact') OR Reccount('tact') = 0
|
||||||
|
STRTOFILE('EROARE: IncarcaCursoareModificareNota a esuat pe caz A' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
QUIT
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
DO asserteaza WITH 'formularul are articole (lAreArticoleVanzari)', loForm.lAreArticoleVanzari, TRANSFORM(loForm.lAreArticoleVanzari)
|
||||||
|
DO asserteaza WITH 'conditie initiala: tvd are cel putin o linie activa', Used('tvd') AND Reccount('tvd') > 0, TRANSFORM(Reccount('tvd'))
|
||||||
|
|
||||||
|
IF !Used('tvd') OR Reccount('tvd') = 0
|
||||||
|
STRTOFILE('EROARE: tvd fara linii, sectiunea A sarita' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
ELSE
|
||||||
|
*!* --- A1: caz de control - cursorul incarcat din Oracle e valid, nicio validare nu trebuie sa se declanseze ---
|
||||||
|
LOCAL llRet1
|
||||||
|
gnMockRaspuns = 6
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet1 = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'caz de control: document real valid -> inainte_de_do_termin() = .T., nicio validare S5 declansata', ;
|
||||||
|
llRet1 == .T. AND !('cantitatea' $ Lower(gcMockUltimMesaj)) AND !('pret' $ Lower(gcMockUltimMesaj)) AND !('articol' $ Lower(gcMockUltimMesaj)), ;
|
||||||
|
'llRet=' + TRANSFORM(llRet1) + ' ultimMesaj=[' + gcMockUltimMesaj + ']'
|
||||||
|
|
||||||
|
*!* --- A2: cantitate <= 0 pe o linie activa -> blocheaza ---
|
||||||
|
LOCAL lnOrigCant, llRet2
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
lnOrigCant = tvd.cantitate
|
||||||
|
REPLACE cantitate WITH 0 IN tvd
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet2 = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'cantitate<=0 pe linie activa -> blocheaza (RETURN .F.)', llRet2 == .F., TRANSFORM(llRet2)
|
||||||
|
DO asserteaza WITH 'cantitate<=0 -> mesajul mentioneaza cantitatea', 'cantitatea' $ Lower(gcMockUltimMesaj), gcMockUltimMesaj
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
REPLACE cantitate WITH lnOrigCant IN tvd
|
||||||
|
|
||||||
|
*!* --- A3: pret NULL pe o linie activa -> ar trebui sa blocheze, DAR verificat empiric ca
|
||||||
|
*!* tvd.pret (populat de IncarcaArticoleFactura din VVANZARI_ARTICOLE, singura cale reala cand
|
||||||
|
*!* ofacturare_editare.prg e incarcat) e structural NOT NULL - REPLACE ... WITH .NULL. arunca
|
||||||
|
*!* eroarea VFP 1581 "Field PRET does not accept null values", nu doar pe liniile persistate
|
||||||
|
*!* (VANZARI_DETALII.PRET e NOT NULL in Oracle - coloana provine din view), ci si pe o linie
|
||||||
|
*!* noua adaugata prin APPEND BLANK pe ACELASI cursor (restrictia e la nivel de coloana, nu de
|
||||||
|
*!* rand). Concluzie: validarea Isnull(pret) din inainte_de_do_termin (omodificari.vc2:14340)
|
||||||
|
*!* e cod NEATINGIBIL pe fluxul real - nu poate fi provocata nici pe linii existente, nici pe
|
||||||
|
*!* linii noi construite prin fluxul aplicatiei. Se raporteaza, nu se repara (fara UI, cod
|
||||||
|
*!* de productie interzis pentru acest agent) - marcat FAIL asteptat, ca sa nu se numere ca regresie.
|
||||||
|
LOCAL lnOrigPret, llRet3, llPretNullPosibil
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
lnOrigPret = tvd.pret
|
||||||
|
llPretNullPosibil = .T.
|
||||||
|
TRY
|
||||||
|
REPLACE pret WITH .NULL. IN tvd
|
||||||
|
CATCH
|
||||||
|
llPretNullPosibil = .F.
|
||||||
|
ENDTRY
|
||||||
|
IF llPretNullPosibil
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet3 = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'pret NULL pe linie activa -> blocheaza (RETURN .F.)', llRet3 == .F., TRANSFORM(llRet3)
|
||||||
|
DO asserteaza WITH 'pret NULL -> mesajul mentioneaza pretul', 'pret' $ Lower(gcMockUltimMesaj), gcMockUltimMesaj
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
REPLACE pret WITH lnOrigPret IN tvd
|
||||||
|
ELSE
|
||||||
|
STRTOFILE('FAIL asteptat pret NULL pe linie activa: tvd.pret e structural NOT NULL (eroare VFP 1581 la REPLACE) - ' + ;
|
||||||
|
'validarea Isnull(pret) din inainte_de_do_termin e neatingibila pe fluxul real, de raportat echipei' + CHR(13) + CHR(10), gcErrLog, 1)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*!* --- A4: id_articol nul sau 0 pe o linie activa -> blocheaza ---
|
||||||
|
LOCAL lnOrigIdArt, llRet4
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
lnOrigIdArt = tvd.id_articol
|
||||||
|
REPLACE id_articol WITH 0 IN tvd
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet4 = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'id_articol=0 pe linie activa -> blocheaza (RETURN .F.)', llRet4 == .F., TRANSFORM(llRet4)
|
||||||
|
DO asserteaza WITH 'id_articol=0 -> mesajul mentioneaza articolul', 'articol' $ Lower(gcMockUltimMesaj), gcMockUltimMesaj
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
REPLACE id_articol WITH lnOrigIdArt IN tvd
|
||||||
|
|
||||||
|
*!* --- A5: zero linii active, document cu rand in tvanz -> CONFIRMARE, nu blocare (ambele ramuri) ---
|
||||||
|
LOCAL llRet5da, llRet5nu
|
||||||
|
SELECT tvd
|
||||||
|
REPLACE ALL sters WITH 1 IN tvd
|
||||||
|
gnMockRaspuns = 6
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet5da = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'zero linii active + Da la confirmare -> continua (.T.)', llRet5da == .T., TRANSFORM(llRet5da)
|
||||||
|
DO asserteaza WITH 'zero linii active -> mesajul de confirmare mentioneaza liniile sterse', 'linii' $ Lower(gcMockUltimMesaj), gcMockUltimMesaj
|
||||||
|
|
||||||
|
gnMockRaspuns = 7
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet5nu = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'zero linii active + Nu la confirmare -> opreste (.F.)', llRet5nu == .F., TRANSFORM(llRet5nu)
|
||||||
|
|
||||||
|
gnMockRaspuns = 6
|
||||||
|
SELECT tvd
|
||||||
|
REPLACE ALL sters WITH 0 IN tvd
|
||||||
|
|
||||||
|
*!* --- A6: linie NOUA (id_vanzare_det=0) cu pret_achizitie 0/NULL -> CONFIRMARE, nu blocare (ambele ramuri) ---
|
||||||
|
*!* linia noua e altfel valida (cantitate/pret/id_articol completate) ca sa nu declanseze A2/A3/A4 mai devreme
|
||||||
|
LOCAL llRet6da, llRet6nu
|
||||||
|
SELECT tvd
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare WITH loForm.nIdVanzare, id_vanzare_det WITH 0, id_articol WITH 999999, ;
|
||||||
|
cantitate WITH 1, pret WITH 10, pret_cu_tva WITH 0, proc_tvav WITH 1.19, sters WITH 0, ;
|
||||||
|
denumire WITH 'LINIE TEST S5', pret_achizitie WITH 0 IN tvd
|
||||||
|
|
||||||
|
gnMockRaspuns = 6
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet6da = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'linie noua cu pret_achizitie=0 + Da la confirmare -> continua (.T.)', llRet6da == .T., TRANSFORM(llRet6da)
|
||||||
|
DO asserteaza WITH 'linie noua cu pret_achizitie=0 -> mesajul mentioneaza pretul de achizitie', 'achizitie' $ Lower(gcMockUltimMesaj), gcMockUltimMesaj
|
||||||
|
|
||||||
|
gnMockRaspuns = 7
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
llRet6nu = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'linie noua cu pret_achizitie=0 + Nu la confirmare -> opreste (.F.)', llRet6nu == .F., TRANSFORM(llRet6nu)
|
||||||
|
|
||||||
|
*!* linia de test nu trebuie sa ramana dupa pret_achizitie NULL (nu doar 0) - verificare suplimentara, apoi curatare
|
||||||
|
gnMockRaspuns = 6
|
||||||
|
SELECT tvd
|
||||||
|
GO BOTTOM
|
||||||
|
REPLACE pret_achizitie WITH .NULL. IN tvd
|
||||||
|
gcMockUltimMesaj = ''
|
||||||
|
LOCAL llRet6null
|
||||||
|
llRet6null = loForm.inainte_de_do_termin()
|
||||||
|
DO asserteaza WITH 'linie noua cu pret_achizitie NULL (nu doar 0) -> aceeasi confirmare', 'achizitie' $ Lower(gcMockUltimMesaj), gcMockUltimMesaj
|
||||||
|
|
||||||
|
SELECT tvd
|
||||||
|
GO BOTTOM
|
||||||
|
DELETE IN tvd
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
loForm.Release()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
*============================================================================================
|
||||||
|
* SECTIUNEA B - ScrieArticoleFacturaEditate: garda de no-op + SQL generat, FARA Oracle (mock pe goExecutor)
|
||||||
|
*============================================================================================
|
||||||
|
|
||||||
|
LOCAL loExecutorReal
|
||||||
|
loExecutorReal = goExecutor
|
||||||
|
|
||||||
|
*!* obiectul mock se construieste O SINGURA DATA, INLINE in programul principal (nu intr-un helper -
|
||||||
|
*!* CREATEOBJECT apelat dintr-o PROCEDURA se comporta gresit in acest runtime headless, capcana l,
|
||||||
|
*!* testare-ui-vfp.md) - ResetMockSql de mai jos doar goleste cursorul si reseteaza contorul pe
|
||||||
|
*!* obiectul deja existent, fara sa mai construiasca altul
|
||||||
|
goExecutor = Createobject('dummyexecutor')
|
||||||
|
|
||||||
|
*!* --- B0: garda de no-op, patru cazuri - niciunul nu trebuie sa apeleze goExecutor.oExecuta ---
|
||||||
|
DO ResetMockSql
|
||||||
|
|
||||||
|
*!* tnIdVanzare <= 0
|
||||||
|
CreeazaCursorArticoleGol('crstvdtest')
|
||||||
|
SELECT crstvdtest
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 100, id_articol WITH 1, cantitate WITH 1, pret WITH 1, sters WITH 0 IN crstvdtest
|
||||||
|
IF Used('crstvanztest')
|
||||||
|
Use In crstvanztest
|
||||||
|
ENDIF
|
||||||
|
CREATE CURSOR crstvanztest (id_vanzare I, discount N(18,4) NULL)
|
||||||
|
INSERT INTO crstvanztest (id_vanzare, discount) VALUES (12345, NULL)
|
||||||
|
|
||||||
|
LOCAL llRetB1, llRetB1b
|
||||||
|
llRetB1 = ScrieArticoleFacturaEditate(0, 'crstvdtest', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'no-op: tnIdVanzare=0 -> .T. fara sa scrie', llRetB1 == .T. AND Reccount('crsMockSql') == 0, 'ret=' + TRANSFORM(llRetB1) + ' comenzi=' + TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
llRetB1b = ScrieArticoleFacturaEditate(-5, 'crstvdtest', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'no-op: tnIdVanzare negativ -> .T. fara sa scrie', llRetB1b == .T. AND Reccount('crsMockSql') == 0, 'ret=' + TRANSFORM(llRetB1b) + ' comenzi=' + TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
*!* alias articole neinchis (nume inexistent)
|
||||||
|
LOCAL llRetB2
|
||||||
|
llRetB2 = ScrieArticoleFacturaEditate(12345, 'crstvd_nu_exista', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'no-op: alias articole neinchis -> .T. fara sa scrie', llRetB2 == .T. AND Reccount('crsMockSql') == 0, 'ret=' + TRANSFORM(llRetB2) + ' comenzi=' + TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
*!* alias vanzare fara exact 1 rand: 0 randuri
|
||||||
|
LOCAL llRetB3zero, llRetB3doi
|
||||||
|
SELECT crstvanztest
|
||||||
|
ZAP
|
||||||
|
llRetB3zero = ScrieArticoleFacturaEditate(12345, 'crstvdtest', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'no-op: alias vanzare cu 0 randuri -> .T. fara sa scrie', llRetB3zero == .T. AND Reccount('crsMockSql') == 0, 'ret=' + TRANSFORM(llRetB3zero) + ' comenzi=' + TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
*!* alias vanzare fara exact 1 rand: 2 randuri
|
||||||
|
INSERT INTO crstvanztest (id_vanzare, discount) VALUES (12345, NULL)
|
||||||
|
INSERT INTO crstvanztest (id_vanzare, discount) VALUES (12345, NULL)
|
||||||
|
llRetB3doi = ScrieArticoleFacturaEditate(12345, 'crstvdtest', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'no-op: alias vanzare cu 2 randuri -> .T. fara sa scrie', llRetB3doi == .T. AND Reccount('crsMockSql') == 0, 'ret=' + TRANSFORM(llRetB3doi) + ' comenzi=' + TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
*!* Reccount(alias articole)=0 - cazul critic: un esec de incarcare Oracle nu trebuie sa goleasca factura
|
||||||
|
LOCAL llRetB4
|
||||||
|
SELECT crstvanztest
|
||||||
|
ZAP
|
||||||
|
INSERT INTO crstvanztest (id_vanzare, discount) VALUES (12345, NULL)
|
||||||
|
SELECT crstvdtest
|
||||||
|
ZAP
|
||||||
|
DO asserteaza WITH 'conditie initiala B4: crstvdtest deschis, 0 randuri', Used('crstvdtest') AND Reccount('crstvdtest') == 0, TRANSFORM(Reccount('crstvdtest'))
|
||||||
|
llRetB4 = ScrieArticoleFacturaEditate(12345, 'crstvdtest', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'no-op CRITIC: Reccount(alias articole)=0 -> .T. fara sa scrie (nu goleste factura la esec de incarcare)', ;
|
||||||
|
llRetB4 == .T. AND Reccount('crsMockSql') == 0, 'ret=' + TRANSFORM(llRetB4) + ' comenzi=' + TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
|
||||||
|
*!* --- B1: scriere normala - un rand din fiecare categorie, verifica SQL-ul si clasificarea ---
|
||||||
|
DO ResetMockSql
|
||||||
|
|
||||||
|
IF Used('crstvdtest')
|
||||||
|
Use In crstvdtest
|
||||||
|
ENDIF
|
||||||
|
CreeazaCursorArticoleGol('crstvdtest')
|
||||||
|
SELECT crstvdtest
|
||||||
|
|
||||||
|
*!* rand 1: pastrata, modificata (lmodificat ignorat de helper - decizia 38 invie TOATE liniile pastrate)
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 555, id_articol WITH 111, cantitate WITH 3, pret WITH 12.5, pret_cu_tva WITH 0, sters WITH 0, lmodificat WITH .T., denumire WITH 'PASTRATA MODIFICATA' IN crstvdtest
|
||||||
|
*!* rand 2: pastrata, nemodificata - trebuie sa primeasca UPDATE la fel ca randul 1 (decizia 38)
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 556, id_articol WITH 112, cantitate WITH 1, pret WITH 5, pret_cu_tva WITH 0, sters WITH 0, lmodificat WITH .F., denumire WITH 'PASTRATA NEMODIFICATA' IN crstvdtest
|
||||||
|
*!* rand 3: stearsa (linie persistata, sters=1) - ramane sters prin pasul 1 (marcheaza tot), fara UPDATE propriu
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 557, id_articol WITH 113, cantitate WITH 1, pret WITH 1, sters WITH 1, denumire WITH 'STEARSA' IN crstvdtest
|
||||||
|
*!* rand 4: linie noua (id_vanzare_det=0) - INSERT; explicatie cu apostrof, ca sa verifice OracleSpecialCharacters
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 0, id_articol WITH 222, cantitate WITH 2, pret WITH 20, pret_cu_tva WITH 0, sters WITH 0, ;
|
||||||
|
pret_achizitie WITH 15.5, explicatie WITH "test 'x'", denumire WITH 'NOUA' IN crstvdtest
|
||||||
|
*!* rand 5: noua-si-stearsa (id_vanzare_det=0, sters=1) - se ignora, fara SQL propriu
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 0, id_articol WITH 223, cantitate WITH 1, pret WITH 1, sters WITH 1, denumire WITH 'NOUA STEARSA' IN crstvdtest
|
||||||
|
*!* rand 6: componenta de set, pastrata (id_vanzare_set<>0, id_vanzare_det>0) - scrisa la fel ca o linie pastrata normala
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 558, id_articol WITH 114, id_vanzare_set WITH 999, cantitate WITH 1, pret WITH 7, sters WITH 0, denumire WITH 'COMPONENTA SET' IN crstvdtest
|
||||||
|
|
||||||
|
IF Used('crstvanztest')
|
||||||
|
Use In crstvanztest
|
||||||
|
ENDIF
|
||||||
|
CREATE CURSOR crstvanztest (id_vanzare I, discount N(18,4) NULL)
|
||||||
|
INSERT INTO crstvanztest (id_vanzare, discount) VALUES (12345, NULL)
|
||||||
|
|
||||||
|
LOCAL llRetB5
|
||||||
|
llRetB5 = ScrieArticoleFacturaEditate(12345, 'crstvdtest', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'scriere normala: intoarce .T.', llRetB5 == .T., TRANSFORM(llRetB5)
|
||||||
|
DO asserteaza WITH 'total comenzi = 6 (1 marcheaza-tot + 3 UPDATE pastrate + 1 INSERT noua + 1 recalcul)', ;
|
||||||
|
Reccount('crsMockSql') == 6, TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
LOCAL lnCntMarcheazaTot, lnCntUpdate, lnCntInsert, lnCntRecalc
|
||||||
|
SELECT crsMockSql
|
||||||
|
lnCntMarcheazaTot = 0
|
||||||
|
lnCntUpdate = 0
|
||||||
|
lnCntInsert = 0
|
||||||
|
lnCntRecalc = 0
|
||||||
|
SCAN
|
||||||
|
IF 'update vanzari_detalii set sters = 1,' $ Lower(sql) AND 'and sters = 0' $ Lower(sql) AND 'where id_vanzare = 12345' $ Lower(sql)
|
||||||
|
lnCntMarcheazaTot = lnCntMarcheazaTot + 1
|
||||||
|
ENDIF
|
||||||
|
IF 'update vanzari_detalii set sters = 0, cantitate' $ Lower(sql)
|
||||||
|
lnCntUpdate = lnCntUpdate + 1
|
||||||
|
ENDIF
|
||||||
|
IF 'insert into vanzari_detalii' $ Lower(sql)
|
||||||
|
lnCntInsert = lnCntInsert + 1
|
||||||
|
ENDIF
|
||||||
|
IF 'recalculeaza_totaluri_vanzari' $ Lower(sql)
|
||||||
|
lnCntRecalc = lnCntRecalc + 1
|
||||||
|
ENDIF
|
||||||
|
ENDSCAN
|
||||||
|
|
||||||
|
DO asserteaza WITH 'clasificare: exact 1 comanda "marcheaza tot sters" (pasul 1, decizia 38)', lnCntMarcheazaTot == 1, TRANSFORM(lnCntMarcheazaTot)
|
||||||
|
DO asserteaza WITH 'clasificare: exact 3 UPDATE (liniile pastrate 555/556/558, inclusiv nemodificata si componenta de set)', lnCntUpdate == 3, TRANSFORM(lnCntUpdate)
|
||||||
|
DO asserteaza WITH 'clasificare: exact 1 INSERT (linia noua 4, id_vanzare_det=0/sters<>1)', lnCntInsert == 1, TRANSFORM(lnCntInsert)
|
||||||
|
DO asserteaza WITH 'clasificare: exact 1 recalcul de totaluri (pasul final)', lnCntRecalc == 1, TRANSFORM(lnCntRecalc)
|
||||||
|
|
||||||
|
LOCAL llU555, llU556, llU558, llU557Absent, llU0Absent
|
||||||
|
SELECT crsMockSql
|
||||||
|
llU555 = .F.
|
||||||
|
llU556 = .F.
|
||||||
|
llU558 = .F.
|
||||||
|
llU557Absent = .T.
|
||||||
|
llU0Absent = .T.
|
||||||
|
SCAN FOR 'update vanzari_detalii set sters = 0, cantitate' $ Lower(sql)
|
||||||
|
IF 'where id_vanzare_det = 555 and' $ Lower(sql)
|
||||||
|
llU555 = .T.
|
||||||
|
ENDIF
|
||||||
|
IF 'where id_vanzare_det = 556 and' $ Lower(sql)
|
||||||
|
llU556 = .T.
|
||||||
|
ENDIF
|
||||||
|
IF 'where id_vanzare_det = 558 and' $ Lower(sql)
|
||||||
|
llU558 = .T.
|
||||||
|
ENDIF
|
||||||
|
IF 'where id_vanzare_det = 557 and' $ Lower(sql)
|
||||||
|
llU557Absent = .F.
|
||||||
|
ENDIF
|
||||||
|
IF 'where id_vanzare_det = 0 and' $ Lower(sql)
|
||||||
|
llU0Absent = .F.
|
||||||
|
ENDIF
|
||||||
|
ENDSCAN
|
||||||
|
DO asserteaza WITH 'clasificare: UPDATE-ul contine exact liniile pastrate asteptate (555, 556, 558) si niciuna in plus (557 stearsa, 0 = noua, absente)', ;
|
||||||
|
llU555 AND llU556 AND llU558 AND llU557Absent AND llU0Absent, ;
|
||||||
|
'555=' + TRANSFORM(llU555) + ' 556=' + TRANSFORM(llU556) + ' 558=' + TRANSFORM(llU558) + ' 557absent=' + TRANSFORM(llU557Absent) + ' 0absent=' + TRANSFORM(llU0Absent)
|
||||||
|
|
||||||
|
LOCAL llUpdateAncorat
|
||||||
|
SELECT crsMockSql
|
||||||
|
llUpdateAncorat = .T.
|
||||||
|
SCAN FOR 'update vanzari_detalii set sters = 0, cantitate' $ Lower(sql)
|
||||||
|
IF !('and id_vanzare = 12345' $ Lower(sql))
|
||||||
|
llUpdateAncorat = .F.
|
||||||
|
ENDIF
|
||||||
|
ENDSCAN
|
||||||
|
DO asserteaza WITH 'fiecare UPDATE de linie pastrata e ancorat pe document (and id_vanzare = 12345)', llUpdateAncorat, TRANSFORM(llUpdateAncorat)
|
||||||
|
|
||||||
|
LOCAL lcSqlInsert, llInsertOk
|
||||||
|
lcSqlInsert = ''
|
||||||
|
SELECT crsMockSql
|
||||||
|
SCAN FOR 'insert into vanzari_detalii' $ Lower(sql)
|
||||||
|
lcSqlInsert = sql
|
||||||
|
ENDSCAN
|
||||||
|
llInsertOk = ('15.5000' $ lcSqlInsert) AND ("test ''x''" $ lcSqlInsert) AND ('12345' $ lcSqlInsert) AND ('222' $ lcSqlInsert)
|
||||||
|
DO asserteaza WITH 'INSERT: pret_achizitie citit din cursor (15.5000), explicatie escapata (apostrof dublat), id_vanzare/id_articol corecte', llInsertOk, lcSqlInsert
|
||||||
|
|
||||||
|
LOCAL lcSqlRecalc
|
||||||
|
lcSqlRecalc = ''
|
||||||
|
SELECT crsMockSql
|
||||||
|
SCAN FOR 'recalculeaza_totaluri_vanzari' $ Lower(sql)
|
||||||
|
lcSqlRecalc = sql
|
||||||
|
ENDSCAN
|
||||||
|
*!* NULL e literal in sursa helperului ([NULL], majuscul) - comparatia se face pe textul lowercase in ambele parti
|
||||||
|
DO asserteaza WITH 'recalcul: discount NULL in cursor -> parametru NULL (pastreaza discountul curent din baza, decizia 41)', ;
|
||||||
|
'recalculeaza_totaluri_vanzari(12345,null)' $ Lower(Strtran(lcSqlRecalc, ' ', '')), lcSqlRecalc
|
||||||
|
|
||||||
|
*!* --- B2: recalcul cu discount NEnul in cursor - parametrul trebuie sa fie valoarea, nu NULL ---
|
||||||
|
DO ResetMockSql
|
||||||
|
SELECT crstvanztest
|
||||||
|
ZAP
|
||||||
|
INSERT INTO crstvanztest (id_vanzare, discount) VALUES (12345, 5)
|
||||||
|
LOCAL llRetB6, lcSqlRecalc2
|
||||||
|
llRetB6 = ScrieArticoleFacturaEditate(12345, 'crstvdtest', 'crstvanztest')
|
||||||
|
lcSqlRecalc2 = ''
|
||||||
|
SELECT crsMockSql
|
||||||
|
SCAN FOR 'recalculeaza_totaluri_vanzari' $ Lower(sql)
|
||||||
|
lcSqlRecalc2 = sql
|
||||||
|
ENDSCAN
|
||||||
|
DO asserteaza WITH 'recalcul: discount=5 in cursor -> parametrul e 5.0000, nu NULL', ;
|
||||||
|
llRetB6 == .T. AND ('recalculeaza_totaluri_vanzari(12345,5.0000)' $ Lower(Strtran(lcSqlRecalc2, ' ', ''))), lcSqlRecalc2
|
||||||
|
|
||||||
|
|
||||||
|
*!* --- B3: oprire la primul esec Oracle - mock configurat sa esueze la a doua comanda ---
|
||||||
|
DO ResetMockSql
|
||||||
|
goExecutor.nFailAtCall = 2
|
||||||
|
|
||||||
|
IF Used('crstvdtest2')
|
||||||
|
Use In crstvdtest2
|
||||||
|
ENDIF
|
||||||
|
CreeazaCursorArticoleGol('crstvdtest2')
|
||||||
|
SELECT crstvdtest2
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 601, id_articol WITH 1, cantitate WITH 1, pret WITH 1, sters WITH 0 IN crstvdtest2
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare_det WITH 602, id_articol WITH 2, cantitate WITH 1, pret WITH 1, sters WITH 0 IN crstvdtest2
|
||||||
|
|
||||||
|
SELECT crstvanztest
|
||||||
|
ZAP
|
||||||
|
INSERT INTO crstvanztest (id_vanzare, discount) VALUES (12345, NULL)
|
||||||
|
|
||||||
|
LOCAL llRetB7
|
||||||
|
llRetB7 = ScrieArticoleFacturaEditate(12345, 'crstvdtest2', 'crstvanztest')
|
||||||
|
DO asserteaza WITH 'esec Oracle la a doua comanda -> functia intoarce .F.', llRetB7 == .F., TRANSFORM(llRetB7)
|
||||||
|
DO asserteaza WITH 'esec Oracle: se opreste la primul esec, nu mai incearca a treia comanda (2 comenzi total, nu 3+)', ;
|
||||||
|
Reccount('crsMockSql') == 2, TRANSFORM(Reccount('crsMockSql'))
|
||||||
|
|
||||||
|
goExecutor.nFailAtCall = 0
|
||||||
|
|
||||||
|
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
|
||||||
|
|
||||||
|
goExecutor = loExecutorReal
|
||||||
|
|
||||||
|
IF Used('crstvdtest')
|
||||||
|
Use In crstvdtest
|
||||||
|
ENDIF
|
||||||
|
IF Used('crstvdtest2')
|
||||||
|
Use In crstvdtest2
|
||||||
|
ENDIF
|
||||||
|
IF Used('crstvanztest')
|
||||||
|
Use In crstvanztest
|
||||||
|
ENDIF
|
||||||
|
IF Used('crsMockSql')
|
||||||
|
Use In crsMockSql
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
QUIT
|
||||||
|
|
||||||
|
|
||||||
|
*!* goleste jurnalul de comenzi si contorul de apeluri PE OBIECTUL DEJA EXISTENT (nu recreeaza
|
||||||
|
*!* goExecutor - vezi comentariul de la constructia lui in main, capcana l). crsMockSql ramane
|
||||||
|
*!* MEREU deschis (recreat gol, nu doar inchis) - RECCOUNT() pe un alias niciodata deschis arunca
|
||||||
|
*!* eroarea 13 "Alias is not found" in loc sa intoarca 0 (verificat empiric, nu asa cum presupunea
|
||||||
|
*!* prima varianta a acestui fisier)
|
||||||
|
PROCEDURE ResetMockSql
|
||||||
|
IF Used('crsMockSql')
|
||||||
|
Use In crsMockSql
|
||||||
|
ENDIF
|
||||||
|
CREATE CURSOR crsMockSql (nr I, sql M)
|
||||||
|
goExecutor.nApeluri = 0
|
||||||
|
goExecutor.nFailAtCall = 0
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE asserteaza
|
||||||
|
LPARAMETERS tcNume, tlConditie, tcValoare
|
||||||
|
|
||||||
|
IF m.tlConditie
|
||||||
|
gnPass = gnPass + 1
|
||||||
|
STRTOFILE('PASS ' + m.tcNume + CHR(13) + CHR(10), gcErrLog, 1)
|
||||||
|
ELSE
|
||||||
|
gnFail = gnFail + 1
|
||||||
|
STRTOFILE('FAIL ' + m.tcNume + ' (valoare: ' + m.tcValoare + ')' + CHR(13) + CHR(10), gcErrLog, 1)
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
*!* mock de goExecutor pentru sectiunea B - NU atinge Oracle: doar inregistreaza textul fiecarei
|
||||||
|
*!* comenzi intr-un cursor (crsMockSql) si intoarce .T., sau .F. o singura data la apelul cu numarul
|
||||||
|
*!* nFailAtCall (0 = nu esueaza niciodata) - ca sa verifice oprirea la primul esec fara sa opreasca
|
||||||
|
*!* toate apelurile ulterioare din suita. DEFINE CLASS la finalul fisierului (capcana depanare_testare_vfp.md #7)
|
||||||
|
DEFINE CLASS dummyexecutor AS Custom
|
||||||
|
cEroare = ''
|
||||||
|
nFailAtCall = 0
|
||||||
|
nApeluri = 0
|
||||||
|
|
||||||
|
PROCEDURE oExecuta
|
||||||
|
LPARAMETERS tcSql, tcCursor
|
||||||
|
LOCAL lnUrmator
|
||||||
|
|
||||||
|
This.nApeluri = This.nApeluri + 1
|
||||||
|
IF !Used('crsMockSql')
|
||||||
|
CREATE CURSOR crsMockSql (nr I, sql M)
|
||||||
|
ENDIF
|
||||||
|
SELECT crsMockSql
|
||||||
|
lnUrmator = Reccount('crsMockSql') + 1
|
||||||
|
INSERT INTO crsMockSql (nr, sql) VALUES (m.lnUrmator, m.tcSql)
|
||||||
|
|
||||||
|
IF !Empty(m.tcCursor)
|
||||||
|
IF Used(m.tcCursor)
|
||||||
|
Use In (m.tcCursor)
|
||||||
|
ENDIF
|
||||||
|
CREATE CURSOR (m.tcCursor) (id_temp N(1))
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF This.nFailAtCall > 0 AND This.nApeluri == This.nFailAtCall
|
||||||
|
This.cEroare = 'esec simulat de test la apelul ' + Transform(This.nApeluri)
|
||||||
|
RETURN .F.
|
||||||
|
ENDIF
|
||||||
|
RETURN .T.
|
||||||
|
ENDPROC
|
||||||
|
ENDDEFINE
|
||||||
202
utile/Teste/editare_factura/test_ui_s5_grid_pret_achizitie.prg
Normal file
202
utile/Teste/editare_factura/test_ui_s5_grid_pret_achizitie.prg
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
* test_ui_s5_grid_pret_achizitie.prg - verificare UI (formular vizibil, nu headless - coloanele
|
||||||
|
* gridului NU se materializeaza sub -A -T, memoria recurenta) a S5.B/C (docs\cercetare\rec_s5_grid_articole.md):
|
||||||
|
* grdArticoleFactura are 15 coloane (era 14), coloana noua cPretAchizitieArt, si editabilitatea
|
||||||
|
* PER RAND (nu per coloana - ReadOnly ramane .F. la nivel de coloana, gating-ul e in When):
|
||||||
|
* - pe o linie din SET (tvd.id_vanzare_set<>0): cantitate/pret/pret_achizitie/pret_cu_tva NU
|
||||||
|
* primesc focus (When()=.F.) si linia are marcaj vizual (DynamicForeColor albastru RGB(0,70,153));
|
||||||
|
* - pret_achizitie primeste focus DOAR pe o linie noua (id_vanzare_det=0, id_vanzare_set=0), NU
|
||||||
|
* pe una existenta;
|
||||||
|
* - marcajul de linie stearsa (gri RGB(150,150,150)) ramane neregresat.
|
||||||
|
*
|
||||||
|
* Document real: cod=1139934/an=2021/luna=12 (id_vanzare=882) - acelasi folosit deja de
|
||||||
|
* test_ui_sterge_linie.prg/test_ui_grid_articole.prg (are rulaje, altfel Show() ascunde tot
|
||||||
|
* pgfArticole indiferent de tvd). Documentul NU are linii de set in date reale (in toata schema
|
||||||
|
* exista doar 4 randuri in VANZARI_SETURI - insuficient ca sa gaseasca un caz real prin proprietate,
|
||||||
|
* si oricum absenta/prezenta pe 1-2 documente nu ar fi dovada). CAZUL DE SET E SINTETIC: un rand
|
||||||
|
* real din tvd e marcat manual cu id_vanzare_set - tipar deja folosit in test_adauga_linie_valuta.prg
|
||||||
|
* (tvanz suprascris manual pentru cazul de valuta). Verificarile de editabilitate se fac prin apel
|
||||||
|
* DIRECT al metodei .When() a controlului (echivalentul programatic al "celula primeste focus"),
|
||||||
|
* nu prin navigare cu input real (masina partajata - fara SendInput/click real).
|
||||||
|
* Nu scrie in Oracle. QUIT la final.
|
||||||
|
|
||||||
|
SET SAFETY OFF
|
||||||
|
SET TALK OFF
|
||||||
|
|
||||||
|
PUBLIC gcUILog, gcSyncDir
|
||||||
|
gcSyncDir = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\uisync_s5grid\'
|
||||||
|
gcUILog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_ui_s5_grid_pret_achizitie_log.txt'
|
||||||
|
STRTOFILE('start' + CHR(13) + CHR(10), gcUILog)
|
||||||
|
|
||||||
|
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
|
||||||
|
|
||||||
|
PUBLIC gnPass, gnFail
|
||||||
|
gnPass = 0
|
||||||
|
gnFail = 0
|
||||||
|
|
||||||
|
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\utile\Teste\ui_harness.prg ADDITIVE
|
||||||
|
DO HarnessInit
|
||||||
|
|
||||||
|
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), gcUILog, 1)
|
||||||
|
DO HarnessDone WITH 'error'
|
||||||
|
QUIT
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
|
||||||
|
|
||||||
|
*!* test_init_env_auto incarca intai copia omodificari din ROACONT - o eliberam si o reincarcam pe cea de sub test
|
||||||
|
RELEASE CLASSLIB omodificari
|
||||||
|
SET CLASSLIB TO D:\ROA\ROAFACTURARE\COMUN\clase\omodificari.vcx ADDITIVE
|
||||||
|
|
||||||
|
LOCAL llOk, lnIdSet, loForm, loGrid
|
||||||
|
LOCAL lnReccountInitial, lnIdArtRow1, lnIdArtRow2
|
||||||
|
|
||||||
|
llOk = IncarcaCursoareModificareNota(1139934, 2021, 12, .F.)
|
||||||
|
IF !llOk OR !Used('tact') OR Reccount('tact') = 0
|
||||||
|
STRTOFILE('EROARE: IncarcaCursoareModificareNota a esuat pe cod=1139934' + CHR(13) + CHR(10), gcUILog, 1)
|
||||||
|
DO HarnessDone WITH 'error'
|
||||||
|
QUIT
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
IncarcaArticoleFactura(882, 'crsArticoleFactura')
|
||||||
|
|
||||||
|
Select tact
|
||||||
|
loForm = Createobject([frm_modific2024], lnIdSet)
|
||||||
|
loForm.WindowType = 0
|
||||||
|
loForm.Show()
|
||||||
|
loForm.pgfArticole.ActivePage = 3
|
||||||
|
DOEVENTS FORCE
|
||||||
|
|
||||||
|
loGrid = loForm.pgfArticole.Page3.grdArticoleFactura
|
||||||
|
|
||||||
|
DO asserteaza WITH 'gridul are 15 coloane (S5: +1 fata de S4, pret_achizitie)', loGrid.ColumnCount == 15, TRANSFORM(loGrid.ColumnCount)
|
||||||
|
DO asserteaza WITH 'coloana cPretAchizitieArt exista', Type('loGrid.cPretAchizitieArt.ControlSource') == 'C', Type('loGrid.cPretAchizitieArt.ControlSource')
|
||||||
|
DO asserteaza WITH 'coloana cPretAchizitieArt legata pe tvd.pret_achizitie', Alltrim(loGrid.cPretAchizitieArt.ControlSource) == 'tvd.pret_achizitie', loGrid.cPretAchizitieArt.ControlSource
|
||||||
|
DO asserteaza WITH 'eticheta coloanei = "Pret achizitie"', Alltrim(loGrid.cPretAchizitieArt.Header1.Caption) == 'Pret achizitie', loGrid.cPretAchizitieArt.Header1.Caption
|
||||||
|
|
||||||
|
lnReccountInitial = Reccount('tvd')
|
||||||
|
DO asserteaza WITH 'documentul are cel putin 2 linii reale (necesar pentru cazurile de mai jos)', lnReccountInitial >= 2, TRANSFORM(lnReccountInitial)
|
||||||
|
|
||||||
|
IF lnReccountInitial >= 2
|
||||||
|
|
||||||
|
*!* --- linie existenta, NEdinSet: pret_achizitie NU primeste focus (id_vanzare_det<>0) ---
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
lnIdArtRow1 = tvd.id_vanzare_det
|
||||||
|
DO asserteaza WITH 'linie existenta (id_vanzare_det<>0): pret_achizitie NU primeste focus', ;
|
||||||
|
loGrid.cPretAchizitieArt.Text1.When() == .F., 'id_vanzare_det=' + TRANSFORM(lnIdArtRow1)
|
||||||
|
|
||||||
|
*!* --- CAZ SINTETIC: a doua linie marcata manual ca si componenta de set (id_vanzare_set<>0) ---
|
||||||
|
SELECT tvd
|
||||||
|
SKIP
|
||||||
|
lnIdArtRow2 = tvd.id_vanzare_det
|
||||||
|
REPLACE id_vanzare_set WITH 777, sters WITH 0 IN tvd
|
||||||
|
|
||||||
|
DO asserteaza WITH 'CAZ SINTETIC linie de set: cantitate NU primeste focus', loGrid.cCantitateArt.Text1.When() == .F., ''
|
||||||
|
DO asserteaza WITH 'CAZ SINTETIC linie de set: pret NU primeste focus', loGrid.cPretArt.Text1.When() == .F., ''
|
||||||
|
DO asserteaza WITH 'CAZ SINTETIC linie de set: pret_achizitie NU primeste focus', loGrid.cPretAchizitieArt.Text1.When() == .F., ''
|
||||||
|
DO asserteaza WITH 'CAZ SINTETIC linie de set: checkbox pret_cu_tva NU primeste focus', loGrid.cPretCuTvaArt._checkbox1.When() == .F., ''
|
||||||
|
DO asserteaza WITH 'CAZ SINTETIC linie de set: marcaj vizual albastru RGB(0,70,153)', ;
|
||||||
|
Evaluate(loGrid.cDenumireArt.DynamicForeColor) == Rgb(0,70,153), Transform(Evaluate(loGrid.cDenumireArt.DynamicForeColor))
|
||||||
|
|
||||||
|
*!* restaurare linie 2 la starea normala (nu de set), ca sa nu contamineze verificarile urmatoare
|
||||||
|
SELECT tvd
|
||||||
|
REPLACE id_vanzare_set WITH 0 IN tvd
|
||||||
|
|
||||||
|
*!* --- marcaj de linie stearsa (gri) - regresie fata de S4, folosind linia 1 ---
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
REPLACE sters WITH 1 IN tvd
|
||||||
|
DO asserteaza WITH 'linie stearsa: marcaj vizual gri RGB(150,150,150) neregresat', ;
|
||||||
|
Evaluate(loGrid.cDenumireArt.DynamicForeColor) == Rgb(150,150,150), Transform(Evaluate(loGrid.cDenumireArt.DynamicForeColor))
|
||||||
|
REPLACE sters WITH 0 IN tvd
|
||||||
|
|
||||||
|
*!* --- linie NOUA (id_vanzare_det=0, id_vanzare_set=0): pret_achizitie PRIMESTE focus ---
|
||||||
|
SELECT tvd
|
||||||
|
APPEND BLANK
|
||||||
|
REPLACE id_vanzare WITH loForm.nIdVanzare, id_vanzare_det WITH 0, id_vanzare_set WITH 0, id_articol WITH 999999, ;
|
||||||
|
cantitate WITH 1, pret WITH 10, sters WITH 0, denumire WITH 'LINIE NOUA TEST S5 UI' IN tvd
|
||||||
|
DO asserteaza WITH 'linie noua (id_vanzare_det=0): pret_achizitie PRIMESTE focus', loGrid.cPretAchizitieArt.Text1.When() == .T., ''
|
||||||
|
DO asserteaza WITH 'linie noua: cantitate/pret raman editabile ca inainte (id_vanzare_set=0)', ;
|
||||||
|
loGrid.cCantitateArt.Text1.When() == .T. AND loGrid.cPretArt.Text1.When() == .T., ''
|
||||||
|
|
||||||
|
*!* linia de test se sterge din cursor (nu ramane in captura finala)
|
||||||
|
SELECT tvd
|
||||||
|
GO BOTTOM
|
||||||
|
DELETE IN tvd
|
||||||
|
|
||||||
|
*!* pozitionare pentru captura: linia 1 grizata ramane vizibila la mijlocul verificarii, se
|
||||||
|
*!* repozitioneaza pe linia 2 (revenita la normal) ca fundalul de selectie sa nu acopere culoarea
|
||||||
|
SELECT tvd
|
||||||
|
GO TOP
|
||||||
|
REPLACE sters WITH 1 IN tvd
|
||||||
|
SKIP
|
||||||
|
loGrid.SetFocus()
|
||||||
|
DOEVENTS FORCE
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcUILog, 1)
|
||||||
|
|
||||||
|
DO HarnessStep WITH 0, 'pagina3 articole S5 - 15 coloane, linie 1 grizata (sters=1), pret_achizitie vizibila', 25
|
||||||
|
|
||||||
|
loForm.Release()
|
||||||
|
|
||||||
|
IF Used('crsArticoleFactura')
|
||||||
|
Use In crsArticoleFactura
|
||||||
|
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
|
||||||
|
IF Used('tvanz')
|
||||||
|
Use In tvanz
|
||||||
|
ENDIF
|
||||||
|
IF Used('tvd')
|
||||||
|
Use In tvd
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
DO HarnessDone WITH 'done'
|
||||||
|
QUIT
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE asserteaza
|
||||||
|
LPARAMETERS tcNume, tlConditie, tcValoare
|
||||||
|
|
||||||
|
IF m.tlConditie
|
||||||
|
gnPass = gnPass + 1
|
||||||
|
STRTOFILE('PASS ' + m.tcNume + CHR(13) + CHR(10), gcUILog, 1)
|
||||||
|
ELSE
|
||||||
|
gnFail = gnFail + 1
|
||||||
|
STRTOFILE('FAIL ' + m.tcNume + ' (valoare: ' + m.tcValoare + ')' + CHR(13) + CHR(10), gcUILog, 1)
|
||||||
|
ENDIF
|
||||||
|
ENDPROC
|
||||||
|
|
||||||
|
|
||||||
|
PROCEDURE test_error_handler
|
||||||
|
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
|
||||||
|
|
||||||
|
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcUILog, 1)
|
||||||
|
ENDPROC
|
||||||
Reference in New Issue
Block a user