diff --git a/clase/_cus_odata_base.vc2 b/clase/_cus_odata_base.vc2
index 0048c17..47d4dbf 100644
--- a/clase/_cus_odata_base.vc2
+++ b/clase/_cus_odata_base.vc2
@@ -175,6 +175,8 @@ DEFINE CLASS _cusodatabase AS _custom OF "_baza.vcx"
lcMesaj = "Inregistrarea a fost stearsa!"
AMESSAGE(lcMesaj,0+48,lctip)
Endif
+ Else
+ llSucces = .F.
Endif
Endif
diff --git a/clase/ofacturare.vc2 b/clase/ofacturare.vc2
index 2db5583..21d37aa 100644
--- a/clase/ofacturare.vc2
+++ b/clase/ofacturare.vc2
@@ -18687,14 +18687,14 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
*!* marius.mutu
*!* daca cantitatea ramasa dupa adaugarea articolului gestionabil este < 0, atunci pun 0 ca sa pot intra pe ramura facturare fara stoc
- Lparameters tlImplicit, tlContract, tlRetur
+ Lparameters tlImplicit, tlContract, tlRetur, tlDoarAvertisment
* llImplicit = .T. => daca exista o singura linie in stoc, atunci nu mai apare formularul de completare a datelor
* tlContract = .T. => provine din gridul cu articole din contract
* tlRetur = .T. => se face retur la articolul selectat (trebuie selectat din rulaj in loc de stoc)
Private pnProcentDiscountMem
Local ofrmadarticol As "frm_articol_factura"
- Local lcSelectActualizare, lcSql, llActualizat, llSucces, lnListaIdOld, lnRecno, lnSucces
+ Local lcMesajContVenit, lcSelectActualizare, lcSql, llActualizat, llSucces, lnListaIdOld, lnRecno, lnSucces
Local lnTotalCantitate, loCauta
*:Global gnButon, poArtLista
pnProcentDiscountMem = 0
@@ -18734,6 +18734,17 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
gnButon = 2
If Thisform.do_verifica_articol(poArticol, tlContract, lnCantitate)
+ lcMesajContVenit = verifica_cont_venit_linie(poArticol.id_articol, poArticol.Id_Pol)
+ If !Empty(lcMesajContVenit)
+ If Type('pcAcumulatorContVenit') = 'C'
+ pcAcumulatorContVenit = pcAcumulatorContVenit + Chr(13) + lcMesajContVenit
+ Else
+ AMESSAGEBOX(lcMesajContVenit, 0+48, "Atentie")
+ Endif
+ If !tlDoarAvertisment
+ Return
+ Endif
+ Endif
Do Case
Case (poArticol.gestionabil = 0 Or gnScadereStoc = 0 Or poDate.tip = 45) && 45 = ROARESTAURANT
* initializez frm_articol_factura, sa se initializeze toate calculele si daca nu arat formularul (adaugare toate articolele)
@@ -18953,6 +18964,16 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
Endif
Endif
+ Local lcMesajContVenit, lnIdPolLinie
+ lnIdPolLinie = Iif(Type('toArticol.Id_Pol')='N', toArticol.Id_Pol, Nvl(gnId_pol_pret_stoc,0))
+ If Type('toArticol.Id_Pol') <> 'N'
+ AddProperty(toArticol, 'Id_Pol', lnIdPolLinie)
+ Endif
+ lcMesajContVenit = verifica_cont_venit_linie(toArticol.id_articol, lnIdPolLinie)
+ If !Empty(lcMesajContVenit)
+ AMESSAGEBOX(lcMesajContVenit, 0+48, "Atentie")
+ Return .F.
+ Endif
If Inlist(poDate.tip, 3, 4, 21, 25, 28, 42, 47) And !Thisform.do_verifica_articol(toArticol, .F., tnCantitate)
save_grid_tag(Thisform.grd_factura)
Select crsfactura
@@ -19097,6 +19118,8 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
PROCEDURE do_adauga_tot
If Used('crsarticole') And Reccount('crsarticole')>0
Local lnNrInregistrare,lnRaspuns,lcArticol,llGestionabil
+ Private pcAcumulatorContVenit
+ pcAcumulatorContVenit = []
Select crsarticole
Scan
lnNrInregistrare = Recno()
@@ -19105,7 +19128,7 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
llGestionabil = (Type('crsArticole.gestionabil') = 'N' And Nvl(crsarticole.gestionabil, 0) = 1)
Do While lnRaspuns = 7
If (cantitate > 0 And m.llGestionabil) Or (!m.llGestionabil) && adaug si articolele cu cantitate negativa (ex: articolul de discount)
- Thisform.do_adauga_articol(.T.)
+ Thisform.do_adauga_articol(.T., .F., .F., .T.)
Endif
Select crsarticole
Go lnNrInregistrare
@@ -19118,6 +19141,9 @@ DEFINE CLASS frm_facturare_articole2 AS _frmbase OF "_frm_base.vcx"
Select crsarticole
Go lnNrInregistrare
Endscan
+ If !Empty(pcAcumulatorContVenit)
+ AMESSAGEBOX("Articole fara cont de venit configurat:" + pcAcumulatorContVenit, 0+48, "Atentie")
+ Endif
Local lcJtvaLipsa, lnRecFactura, lnSelFactura
lcJtvaLipsa = []
lnSelFactura = Select()
@@ -22607,6 +22633,8 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="pgfrm_optiuni.Page1.Op_coeficient_k" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="pgfrm_optiuni.Page1.op_aviz_bon_fiscal" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="pgfrm_optiuni.Page1.op_factura_email" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="pgfrm_optiuni.Page1.Clb_nota_stoc_debit" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="pgfrm_optiuni.Page1.Clb_nota_stoc_credit" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="pgfrm_optiuni.Page2.Ed_txt_subsol_fact" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="pgfrm_optiuni.Page2.Ct_clb_fdoc_factura" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="pgfrm_optiuni.Page2.op_printdenumire" UniqueID="" Timestamp="" />
@@ -22664,6 +22692,8 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
*p: cpolpretk
*p: cpolpretstoc
*p: cpolprettr
+ *p: csccnotastoc
+ *p: cscdnotastoc
*p: natasamentefact
*p: nidfdocaviz
*p: nidfdocavizretur
@@ -22697,6 +22727,8 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
cpolpretk =
cpolpretstoc =
cpolprettr =
+ csccnotastoc =
+ cscdnotastoc =
DoCreate = .T.
FontCharSet = 238
Height = 586
@@ -22815,6 +22847,38 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
Lb_simplu1.Name = "Lb_simplu1"
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+ ADD OBJECT 'pgfrm_optiuni.Page1.Clb_nota_stoc_credit' AS clb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Clb_nota_stoc_credit", ;
+ TabIndex = 16, ;
+ Top = 469, ;
+ Width = 510, ;
+ Text_simplu1.Height = 23, ;
+ Text_simplu1.Left = 254, ;
+ Text_simplu1.Name = "Text_simplu1", ;
+ Text_simplu1.Top = 3, ;
+ Text_simplu1.Width = 90, ;
+ Lb_simplu1.Caption = "Nota implicita stoc - cont creditor", ;
+ Lb_simplu1.Name = "Lb_simplu1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT 'pgfrm_optiuni.Page1.Clb_nota_stoc_debit' AS clb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Clb_nota_stoc_debit", ;
+ TabIndex = 15, ;
+ Top = 440, ;
+ Width = 510, ;
+ Text_simplu1.Height = 23, ;
+ Text_simplu1.Left = 254, ;
+ Text_simplu1.Name = "Text_simplu1", ;
+ Text_simplu1.Top = 3, ;
+ Text_simplu1.Width = 90, ;
+ Lb_simplu1.Caption = "Nota implicita stoc - cont debitor", ;
+ Lb_simplu1.Name = "Lb_simplu1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
ADD OBJECT 'pgfrm_optiuni.Page1.Clb_zile_scadenta' AS clb_tx_simplu WITH ;
Height = 29, ;
Left = 9, ;
@@ -24113,6 +24177,7 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
Local lcTextConformFact5, lcTextConformFact6, lcTextFooterFact1, lcTextFooterFact2
Local lcTextFooterFact3, lcTextFooterFact4, lcTextFooterFact5, lnPrintDenumire, lnTextConformitate, lnId_fdoc_card
Local lcTextConformFact7, lcTextConformFact8, lnFacturaSold
+ Local lcScdNotaStoc, lcSccNotaStoc
*:Global gcTextConformFact7, gcTextConformFact8, gnFacturaSold, gnId_fdoc_card
*:Global gcTextConformFact1, gcTextConformFact2, gcTextConformFact3, gcTextConformFact4
*:Global gcTextConformFact5, gcTextConformFact6, gcTextFooterFact1, gcTextFooterFact2
@@ -24172,6 +24237,8 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
lnId_part_casa = Thisform.nidpartcasa
lnId_pol_pret_tr = Thisform.nidpolprettr
lnId_pol_pret_stoc = Thisform.nidpolpretstoc
+ lcScdNotaStoc = Alltrim(.page1.clb_nota_stoc_debit.text_simplu1.Value)
+ lcSccNotaStoc = Alltrim(.page1.clb_nota_stoc_credit.text_simplu1.Value)
*!* modificare v 2.0.58
lnAtasamenteFact = .page1.op_salvare_pdf._optiongrup1.Value
*!* modificare v 2.0.58 ^
@@ -24451,6 +24518,18 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
Endif
*!* modificare v 2.0.93 ^
+ If lcScdNotaStoc <> This.cScdNotaStoc Or lcSccNotaStoc <> This.cSccNotaStoc
+ Local loNotaStoc
+ loNotaStoc = Createobject('cus_pret_nomenclator')
+ If !loNotaStoc.salveaza_nota_politica(lnId_pol_pret_stoc, lcScdNotaStoc, lcSccNotaStoc)
+ Release loNotaStoc
+ Return .F.
+ Endif
+ Release loNotaStoc
+ This.cScdNotaStoc = lcScdNotaStoc
+ This.cSccNotaStoc = lcSccNotaStoc
+ Endif
+
Set Exact &lcSetare
If !Empty(lcOptiuni) And !Empty(lcValori)
@@ -24571,6 +24650,21 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
actualizeaza_politica_pret(23,@gnId_pol_pret_tr,@lcPolPretTr)
actualizeaza_politica_pret(1,@gnId_pol_pret_stoc,@lcPolPretStoc)
+ If Empty(Nvl(gnId_pol_pret_stoc,0))
+ Local loPolStoc, lnIdPolStoc
+ loPolStoc = Createobject('cus_pret_nomenclator')
+ lnIdPolStoc = loPolStoc.asigura_politica()
+ Release loPolStoc
+ If lnIdPolStoc > 0
+ actualizeaza_politica_pret(1,@gnId_pol_pret_stoc,@lcPolPretStoc)
+ Endif
+ Endif
+ Local loNotaStoc
+ loNotaStoc = Createobject('cus_pret_nomenclator')
+ loNotaStoc.incarca_nota_politica(Nvl(gnId_pol_pret_stoc,0))
+ This.cScdNotaStoc = loNotaStoc.cScd
+ This.cSccNotaStoc = loNotaStoc.cScc
+ Release loNotaStoc
*!* modificare v 2.0.58
Thisform.natasamentefact = 2-Nvl(citeste_optiune_firma([ATASAMENTEFACT]),0)
*!* modificare v 2.0.58 ^
@@ -24647,6 +24741,9 @@ DEFINE CLASS frm_optiuni_facturare AS _frmbase OF "_frm_base.vcx"
.op_factura_email._optiongrup1.Value = IIF(Nvl(m.gnFacturaEmail,0) = 0, 2, IIF(Nvl(m.gnFacturaEmail,0) = 1, 1, 3))
.ct_clb_pol_pret_stoc.clb_tx_cautare.teXT_SIMPLU1.Refresh()
+ .ct_clb_pol_pret_stoc.Enabled = Empty(Thisform.nidpolpretstoc)
+ .clb_nota_stoc_debit.text_simplu1.Value = This.cScdNotaStoc
+ .clb_nota_stoc_credit.text_simplu1.Value = This.cSccNotaStoc
*!* modificare v 2.0.58
.op_salvare_pdf._optiongrup1.Value = Thisform.natasamentefact
.op_salvare_pdf.Refresh()
diff --git a/clase/onom_articole.vc2 b/clase/onom_articole.vc2
index 2b05341..613f562 100644
--- a/clase/onom_articole.vc2
+++ b/clase/onom_articole.vc2
@@ -85,7 +85,7 @@ DEFINE CLASS cus_odata_catalog_articole AS _cusodatabase OF "_cus_odata_base.vcx
IIF(Isnull(pnId_part),[NULL],Alltrim(Str(pnId_part)))+[,] + ;
Alltrim(Str(pnTaxaReconditionare,18,4)) + [,] + ;
Alltrim(Str(pnListareCodBare)) + [,?@pnIdAMS,] + ;
- alltrim(str(pnTip)) + [,0] + [, '] + m.pcCodNC8 + [',] + ALLTRIM(STR(NVL(m.pnGreutate, 0),12,4)) + [,] + ALLTRIM(STR(m.pnIdTaraOrigine)) + [, '] + m.pcCodCPV + [','] + m.pcCodUMISO + ['); end;]
+ alltrim(str(pnTip)) + [,0] + [, '] + m.pcCodNC8 + [',] + ALLTRIM(STR(NVL(m.pnGreutate, 0),12,4)) + [,] + IIF(ISNULL(m.pnIdTaraOrigine), [NULL], ALLTRIM(STR(m.pnIdTaraOrigine))) + [, '] + m.pcCodCPV + [','] + m.pcCodUMISO + ['); end;]
Case lcActiune = "UPDATE"
lcSql = [begin pack_preturi.modifica_articol(?gnAn,]+Alltrim(Str(pnId))+[, ']+;
pccodmat+ [', '] + pccodmatf + [', '] + pcconditii_pastrare + [','] + pcdenumire+[',] + ;
@@ -707,6 +707,14 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
*< OBJECTDATA: ObjPath="_pageframe1.Page2.ct_tara_origine" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_pageframe1.Page2.lblIntrastat" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="_pageframe1.Page2.Clb_tx_simplu2" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Clb_tx_pret_ftva" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Clb_tx_pret_ctva" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Cb_tx_proc_tvav" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Cb_tx_venit" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Clb_tx_scd" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Clb_tx_scc" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Clb_tx_cont_dedus" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_pageframe1.Page3.Lb_info_conturi" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Cus_odata_parteneri_articole_coduri" UniqueID="" Timestamp="" />
*
@@ -720,6 +728,7 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
*p: nid
*p: ogeneratorcodbare
*p: ogeneratorcodmat
+ *p: opretnom
*p: orec
*
@@ -731,10 +740,12 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
nid = 0
ogeneratorcodbare = .NULL.
ogeneratorcodmat = .NULL.
+ opretnom = .NULL.
Width = 610
_memberdata =
+
_shape1.Height = 29
_shape1.Left = 0
@@ -766,14 +777,16 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
Height = 415, ;
Left = 1, ;
Name = "_pageframe1", ;
- PageCount = 2, ;
+ PageCount = 3, ;
TabIndex = 1, ;
Top = 27, ;
Width = 610, ;
Page1.Caption = "Articol", ;
Page1.Name = "Page1", ;
Page2.Caption = "Alte informatii", ;
- Page2.Name = "Page2"
+ Page2.Name = "Page2", ;
+ Page3.Caption = "Vanzare", ;
+ Page3.Name = "Page3"
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="pageframe" />
ADD OBJECT '_pageframe1.Page1._checkbox1' AS _checkbox WITH ;
@@ -1459,6 +1472,146 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
Top = 8
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
+ ADD OBJECT '_pageframe1.Page3.Cb_tx_proc_tvav' AS cb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Cb_tx_proc_tvav", ;
+ TabIndex = 3, ;
+ Top = 82, ;
+ Width = 380, ;
+ ZOrderSet = 2, ;
+ _cbbase1.Height = 23, ;
+ _cbbase1.Left = 185, ;
+ _cbbase1.Name = "_cbbase1", ;
+ _cbbase1.Top = 3, ;
+ _cbbase1.Width = 163, ;
+ _lbbase1.Caption = "Cota TVA", ;
+ _lbbase1.Name = "_lbbase1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT '_pageframe1.Page3.Cb_tx_venit' AS cb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Cb_tx_venit", ;
+ TabIndex = 4, ;
+ Top = 118, ;
+ Width = 380, ;
+ ZOrderSet = 3, ;
+ _cbbase1.BoundColumn = 2, ;
+ _cbbase1.BoundTo = .T., ;
+ _cbbase1.ColumnCount = 2, ;
+ _cbbase1.ColumnLines = .F., ;
+ _cbbase1.ColumnWidths = "184,0", ;
+ _cbbase1.Height = 23, ;
+ _cbbase1.Left = 185, ;
+ _cbbase1.Name = "_cbbase1", ;
+ _cbbase1.Top = 3, ;
+ _cbbase1.Width = 184, ;
+ _lbbase1.Caption = "Tip venit", ;
+ _lbbase1.Name = "_lbbase1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT '_pageframe1.Page3.Clb_tx_cont_dedus' AS clb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Clb_tx_cont_dedus", ;
+ TabIndex = 7, ;
+ Top = 226, ;
+ Width = 380, ;
+ ZOrderSet = 6, ;
+ Text_simplu1.Height = 23, ;
+ Text_simplu1.Left = 185, ;
+ Text_simplu1.MaxLength = 12, ;
+ Text_simplu1.Name = "Text_simplu1", ;
+ Text_simplu1.ReadOnly = .T., ;
+ Text_simplu1.Top = 3, ;
+ Text_simplu1.Width = 113, ;
+ Lb_simplu1.Caption = "Cont venit articol", ;
+ Lb_simplu1.Name = "Lb_simplu1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT '_pageframe1.Page3.Clb_tx_pret_ctva' AS clb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Clb_tx_pret_ctva", ;
+ TabIndex = 2, ;
+ Top = 46, ;
+ Width = 380, ;
+ ZOrderSet = 1, ;
+ Text_simplu1.Format = "RK", ;
+ Text_simplu1.Height = 23, ;
+ Text_simplu1.InputMask = (GET_MASK(14,gnPC)), ;
+ Text_simplu1.Left = 185, ;
+ Text_simplu1.Name = "Text_simplu1", ;
+ Text_simplu1.Top = 3, ;
+ Text_simplu1.Width = 113, ;
+ Lb_simplu1.Caption = "Pret cu TVA", ;
+ Lb_simplu1.Name = "Lb_simplu1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT '_pageframe1.Page3.Clb_tx_pret_ftva' AS clb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Clb_tx_pret_ftva", ;
+ TabIndex = 1, ;
+ Top = 10, ;
+ Width = 380, ;
+ ZOrderSet = 0, ;
+ Text_simplu1.Format = "RK", ;
+ Text_simplu1.Height = 23, ;
+ Text_simplu1.InputMask = (GET_MASK(14,gnPC)), ;
+ Text_simplu1.Left = 185, ;
+ Text_simplu1.Name = "Text_simplu1", ;
+ Text_simplu1.Top = 3, ;
+ Text_simplu1.Width = 113, ;
+ Lb_simplu1.Caption = "Pret fara TVA", ;
+ Lb_simplu1.Name = "Lb_simplu1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT '_pageframe1.Page3.Clb_tx_scc' AS clb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Clb_tx_scc", ;
+ TabIndex = 6, ;
+ Top = 190, ;
+ Width = 380, ;
+ ZOrderSet = 5, ;
+ Text_simplu1.Height = 23, ;
+ Text_simplu1.Left = 185, ;
+ Text_simplu1.MaxLength = 12, ;
+ Text_simplu1.Name = "Text_simplu1", ;
+ Text_simplu1.Top = 3, ;
+ Text_simplu1.Width = 113, ;
+ Lb_simplu1.Caption = "Cont creditor", ;
+ Lb_simplu1.Name = "Lb_simplu1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT '_pageframe1.Page3.Clb_tx_scd' AS clb_tx_simplu WITH ;
+ Height = 29, ;
+ Left = 9, ;
+ Name = "Clb_tx_scd", ;
+ TabIndex = 5, ;
+ Top = 154, ;
+ Width = 380, ;
+ ZOrderSet = 4, ;
+ Text_simplu1.Height = 23, ;
+ Text_simplu1.Left = 185, ;
+ Text_simplu1.MaxLength = 12, ;
+ Text_simplu1.Name = "Text_simplu1", ;
+ Text_simplu1.Top = 3, ;
+ Text_simplu1.Width = 113, ;
+ Lb_simplu1.Caption = "Cont debitor", ;
+ Lb_simplu1.Name = "Lb_simplu1"
+ *< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+
+ ADD OBJECT '_pageframe1.Page3.Lb_info_conturi' AS _label WITH ;
+ Caption = "Necompletate: debit 4111, credit contul de venit al articolului", ;
+ Left = 9, ;
+ Name = "Lb_info_conturi", ;
+ TabIndex = 8, ;
+ Top = 262
+ *< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
+
ADD OBJECT 'But_renunt1' AS but_renunt WITH ;
Left = 551, ;
Name = "But_renunt1", ;
@@ -1686,6 +1839,10 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
Endscan
Set Deleted &lcDeleted
+
+ If m.llReturn And Vartype(Thisform.oPretNom) = "O"
+ llReturn = Thisform.oPretNom.salveaza(m.lnIdArticol)
+ Endif
Endif && cus_odata_catalog_articole
Thisform.do_inchide_tranzactie(Iif(m.llReturn, 1, 2))
@@ -1767,8 +1924,65 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
If gnCodBareAutomat = 2
This.oGeneratorCodBare= Createobject("oGeneratorNumere")
lnRezultat2 = This.oGeneratorCodBare.creeaza_cursor_serii(15)
- EndIf
+ EndIf
*!* 07.09.2009 ^
+
+ If gcNumeProgram = [ROAFACTURARE]
+ This.oPretNom = Createobject("cus_pret_nomenclator")
+ This.oPretNom.incarca(Iif(Upper(Alltrim(m.tcActiune)) = [UPDATE], m.tnId, 0))
+ This._pageframe1.Page3.Clb_tx_pret_ftva.Text_simplu1.ControlSource = "Thisform.oPretNom.nPretFtva"
+ This._pageframe1.Page3.Clb_tx_pret_ctva.Text_simplu1.ControlSource = "Thisform.oPretNom.nPretCtva"
+ This._pageframe1.Page3.Clb_tx_scd.Text_simplu1.ControlSource = "Thisform.oPretNom.cScd"
+ This._pageframe1.Page3.Clb_tx_scc.Text_simplu1.ControlSource = "Thisform.oPretNom.cScc"
+ This._pageframe1.Page3.Clb_tx_cont_dedus.Text_simplu1.ControlSource = "Thisform.oPretNom.cContDedus"
+ If Used('crsvenchelt')
+ Use In crsvenchelt
+ Endif
+ goExecutor.oExecute([select id_venchelt, explicatie as venchelt from vnom_venchel where inactiv = 0 order by explicatie],[crsvenchelt])
+ This._pageframe1.Page3.Cb_tx_venit._cbbase1.RowSourceType = 6
+ This._pageframe1.Page3.Cb_tx_venit._cbbase1.RowSource = "crsvenchelt.venchelt,id_venchelt"
+ This._pageframe1.Page3.Cb_tx_venit._cbbase1.ControlSource = "Thisform.oPretNom.nIdVenchelt"
+ If Used('crs_cote_tva')
+ Use In crs_cote_tva
+ Endif
+ If Used('crs_cote_tva2')
+ Use In crs_cote_tva2
+ Endif
+ goExecutor.oExecute([select procent, proc_tva from ] + gcS + [.vcote_tva where an = ?gnAn and luna = ?gnLuna order by proc_tva desc],[crs_cote_tva2])
+ Create Cursor crs_cote_tva (procent C(100), proc_tva N(10,2) Null)
+ If Used('crs_cote_tva2')
+ Insert Into crs_cote_tva (procent, proc_tva) Select Alltrim(Str(procent,10,2)), proc_tva From crs_cote_tva2
+ Use In crs_cote_tva2
+ Endif
+ Select crs_cote_tva
+ Append Blank
+ Replace procent With []
+ This._pageframe1.Page3.Cb_tx_proc_tvav._cbbase1.RowSourceType = 2
+ This._pageframe1.Page3.Cb_tx_proc_tvav._cbbase1.RowSource = "crs_cote_tva"
+ If Isnull(This.oPretNom.nProcTvav)
+ Locate For Isnull(proc_tva)
+ Else
+ Locate For !Isnull(proc_tva) And proc_tva = This.oPretNom.nProcTvav
+ Endif
+ If !Found()
+ Go Bottom
+ Endif
+ This._pageframe1.Page3.Cb_tx_proc_tvav._cbbase1.ListIndex = Recno()
+ If This.oPretNom.lPreturiCuTva
+ This._pageframe1.Page3.Clb_tx_pret_ctva.Lb_simplu1.Caption = "Pret cu TVA (pret lista)"
+ This._pageframe1.Page3.Clb_tx_pret_ctva.Lb_simplu1.FontBold = .T.
+ This._pageframe1.Page3.Clb_tx_pret_ftva.Lb_simplu1.Caption = "Pret fara TVA"
+ This._pageframe1.Page3.Clb_tx_pret_ftva.Lb_simplu1.FontBold = .F.
+ Else
+ This._pageframe1.Page3.Clb_tx_pret_ftva.Lb_simplu1.Caption = "Pret fara TVA (pret lista)"
+ This._pageframe1.Page3.Clb_tx_pret_ftva.Lb_simplu1.FontBold = .T.
+ This._pageframe1.Page3.Clb_tx_pret_ctva.Lb_simplu1.Caption = "Pret cu TVA"
+ This._pageframe1.Page3.Clb_tx_pret_ctva.Lb_simplu1.FontBold = .F.
+ Endif
+ This._pageframe1.PageCount = 3
+ Else
+ This._pageframe1.PageCount = 2
+ Endif
ENDPROC
PROCEDURE Load
@@ -1927,6 +2141,30 @@ DEFINE CLASS frm_catalog_articole_nou AS _frmbase OF "_frm_base.vcx"
thisform.do_alege_partener()
ENDPROC
+ PROCEDURE _pageframe1.Page3.Cb_tx_proc_tvav._cbbase1.InteractiveChange
+ Select crs_cote_tva
+ Thisform.oPretNom.nProcTvav = crs_cote_tva.proc_tva
+ If Thisform.oPretNom.lPreturiCuTva
+ Thisform.oPretNom.nPretFtva = Thisform.oPretNom.recalculeaza_pret(Thisform.oPretNom.nPretCtva, .F.)
+ Thisform._pageframe1.Page3.Clb_tx_pret_ftva.Text_simplu1.Refresh()
+ Else
+ Thisform.oPretNom.nPretCtva = Thisform.oPretNom.recalculeaza_pret(Thisform.oPretNom.nPretFtva, .T.)
+ Thisform._pageframe1.Page3.Clb_tx_pret_ctva.Text_simplu1.Refresh()
+ Endif
+ ENDPROC
+
+ PROCEDURE _pageframe1.Page3.Clb_tx_pret_ctva.Text_simplu1.Valid
+ Thisform.oPretNom.nPretCtva = This.Value
+ Thisform.oPretNom.nPretFtva = Thisform.oPretNom.recalculeaza_pret(This.Value, .F.)
+ Thisform._pageframe1.Page3.Clb_tx_pret_ftva.Text_simplu1.Refresh()
+ ENDPROC
+
+ PROCEDURE _pageframe1.Page3.Clb_tx_pret_ftva.Text_simplu1.Valid
+ Thisform.oPretNom.nPretFtva = This.Value
+ Thisform.oPretNom.nPretCtva = Thisform.oPretNom.recalculeaza_pret(This.Value, .T.)
+ Thisform._pageframe1.Page3.Clb_tx_pret_ctva.Text_simplu1.Refresh()
+ ENDPROC
+
ENDDEFINE
DEFINE CLASS frm_config_codbare AS frm_termin_renunt OF "_frm_child.vcx"
diff --git a/programe/ofacturare_comun.prg b/programe/ofacturare_comun.prg
index 9846759..7b6b46b 100644
--- a/programe/ofacturare_comun.prg
+++ b/programe/ofacturare_comun.prg
@@ -64,6 +64,17 @@
*!* prelucreaza_facturacrs + vpretctva/vdiscountctva in lista de insert (pretul si discountul
*!* unitar in valuta cu TVA inclus, care plecau 0 la Oracle la reemiterea documentelor in valuta)
+*!* 14.09.2026
+*!* agent
+*!* + clasa cus_pret_nomenclator - politica de stoc pe pagina Vanzare din fisa articolului (plan #12b, S6b)
+*!* + incarca_nota_politica/salveaza_nota_politica - nota implicita (cont debitor/creditor) a politicii
+*!* de stoc, editabila din optiunile de facturare (plan #12b, S7b)
+
+*!* 15.09.2026
+*!* marius.mutu
+*!* + verifica_cont_venit_linie - verificare prietenoasa a contului de venit rezolvat pentru o linie
+*!* de factura, la adaugarea articolului
+
***************************************************************************************************************
**** Clase:
**** oDateFactura
@@ -76,6 +87,14 @@
**** scrieAtasamente
**** oDateGestiune
**** Reset
+**** cus_pret_nomenclator
+**** asigura_politica
+**** incarca
+**** valideaza
+**** salveaza
+**** recalculeaza_pret
+**** incarca_nota_politica
+**** salveaza_nota_politica
**** Functii:
**** actualizeaza_document
**** actualizeaza_partener_fact
@@ -819,6 +838,44 @@ Function deriva_cont_venit_fara_pol
Endfunc && deriva_cont_venit_fara_pol
*********************************************************************************************************
*********************************************************************************************************
+* verificare prietenoasa D10 la adaugarea liniei; intoarce [] daca linia are cont de venit rezolvat, altfel mesajul de afisat
+Function verifica_cont_venit_linie
+ Lparameters tnIdArticol, tnIdPol
+ Local lcSql, lnSucces, lcMesaj, lcIdPolStoc, lcIdPol, lcIdArt
+ lcMesaj = []
+ If Isnull(tnIdArticol) Or Isnull(tnIdPol)
+ Return lcMesaj
+ Endif
+ * fisa poate ajunge aici fara sa fi trecut prin optiunile facturarii - globalul nu exista inca
+ lcIdPolStoc = Iif(Type('gnId_pol_pret_stoc')='N',Alltrim(Str(gnId_pol_pret_stoc)),'0')
+ lcIdPol = Alltrim(Str(tnIdPol))
+ lcIdArt = Alltrim(Str(tnIdArticol))
+ * replica exacta a rezolvarii din pack_facturare.contabilizeaza_articol.cursor_articol: deducerea
+ * cont_venit_articol_stoc are prioritate doar pe politica de stoc si doar fara nota pe rand
+ lcSql = [select nom_articole.denumire, b.nume_lista_preturi, ] + ;
+ [nvl(case when a.id_pol = ] + lcIdPolStoc + [ and a.id_nota is null then pack_facturare.cont_venit_articol_stoc(] + lcIdArt + [) end, d.scc) as scc_rezolvat ] + ;
+ [from nom_articole ] + ;
+ [left join crm_politici_pret_art a on a.id_pol = ] + lcIdPol + [ and a.id_articol = nom_articole.id_articol ] + ;
+ [join crm_politici_preturi b on b.id_pol = ] + lcIdPol + [ ] + ;
+ [left join crm_note_vanzari c on c.id_nota = (case when ] + lcIdPol + [ = ] + lcIdPolStoc + [ then nvl(a.id_nota, b.id_nota) else b.id_nota end) ] + ;
+ [left join note_contabile d on d.id_set = c.id_set ] + ;
+ [where nom_articole.id_articol = ] + lcIdArt
+ If Used('crsverifcontvenit')
+ Use In crsverifcontvenit
+ Endif
+ lnSucces = goExecutor.oExecute(lcSql,[crsverifcontvenit])
+ If lnSucces >= 0 And Used('crsverifcontvenit') And Reccount('crsverifcontvenit') > 0 And Isnull(crsverifcontvenit.scc_rezolvat)
+ lcMesaj = [Articolul ] + Alltrim(Nvl(crsverifcontvenit.denumire,[])) + ;
+ [ nu are cont de venit configurat pe politica ] + Alltrim(Nvl(crsverifcontvenit.nume_lista_preturi,[])) + ;
+ [ - completati contul articolului sau nota contabila a politicii!]
+ Endif
+ If Used('crsverifcontvenit')
+ Use In crsverifcontvenit
+ Endif
+ Return lcMesaj
+Endfunc && verifica_cont_venit_linie
+*********************************************************************************************************
+*********************************************************************************************************
*!* Function recalculeaza_pret_vanzare_lei_set
*!* Lparameters tcTabel,tnCurs
*!* Local llReturn
@@ -2304,3 +2361,249 @@ Function scrie_legatura_proforma
Endfunc && scrie_legatura_proforma
******************************* SFARSIT: scrie_legatura_proforma *****************************************
*********************************************************************************************************
+*********************************************************************************************************
+****************************************** INCEPUT: cus_pret_nomenclator ***************************************
+Define Class cus_pret_nomenclator As Custom
+ nIdArticol = 0
+ nIdPolitica = 0
+ lIncarcat = .F.
+ lPreturiCuTva = .F.
+ nPretFtva = 0
+ nPretCtva = 0
+ nProcTvav = 1
+ nIdVenchelt = .NULL.
+ nIdNota = .NULL.
+ cScd = []
+ cScc = []
+ cContDedus = []
+ cEroare = []
+
+ * asigura politica de stoc (o creeaza daca lipseste); intoarce id politica, 0 la esec
+ Procedure asigura_politica
+ Local lcSql, lnSucces
+ Private pnIdUtil, pnIdPolitica
+ pnIdUtil = gnIdUtil
+ pnIdPolitica = 0
+ lcSql = [begin pack_preturi.asigura_politica_stoc(?pnIdUtil,?@pnIdPolitica); end;]
+ lnSucces = goExecutor.oExecute(lcSql)
+ If lnSucces < 0
+ AMESSAGEBOX(goExecutor.oPrelucrareEroare(),16,"Eroare")
+ This.nIdPolitica = 0
+ Else
+ This.nIdPolitica = Nvl(pnIdPolitica,0)
+ Endif
+ Release pnIdUtil, pnIdPolitica
+ Return This.nIdPolitica
+ Endproc && asigura_politica
+
+ * citeste randul politicii de stoc pentru articol, contul dedus si conturile notei asociate
+ Procedure incarca
+ Lparameters tnIdArticol
+ Local lcSql, lnSucces
+ This.nIdArticol = tnIdArticol
+ This.lIncarcat = .F.
+ This.nPretFtva = 0
+ This.nPretCtva = 0
+ This.nProcTvav = (GetProcTvaStandard()+100)/100
+ This.lPreturiCuTva = .F.
+ This.nIdVenchelt = .NULL.
+ This.nIdNota = .NULL.
+ This.cScd = []
+ This.cScc = []
+ This.cContDedus = []
+ If This.asigura_politica() <= 0
+ Return .F.
+ Endif
+ lcSql = [select nvl(preturi_cu_tva,0) as preturi_cu_tva from crm_politici_preturi where id_pol = ] + Alltrim(Str(This.nIdPolitica))
+ If Used('crspreturi')
+ Use In crspreturi
+ Endif
+ lnSucces = goExecutor.oExecute(lcSql,[crspreturi])
+ If lnSucces >= 0 And Reccount('crspreturi') > 0
+ This.lPreturiCuTva = (crspreturi.preturi_cu_tva = 1)
+ Endif
+ If Used('crspreturi')
+ Use In crspreturi
+ Endif
+ lcSql = [select pretftva, pretctva, proc_tvav, id_venchelt, id_nota from crm_politici_pret_art ] + ;
+ [where id_pol = ] + Alltrim(Str(This.nIdPolitica)) + [ and id_articol = ] + Alltrim(Str(tnIdArticol))
+ If Used('crspolart')
+ Use In crspolart
+ Endif
+ lnSucces = goExecutor.oExecute(lcSql,[crspolart])
+ If lnSucces < 0
+ AMESSAGEBOX(goExecutor.oPrelucrareEroare(),16,"Eroare")
+ Return .F.
+ Endif
+ If Reccount('crspolart') > 0
+ This.nPretFtva = Nvl(crspolart.pretftva,0)
+ This.nPretCtva = Nvl(crspolart.pretctva,0)
+ This.nProcTvav = crspolart.proc_tvav
+ If !Isnull(crspolart.id_venchelt)
+ This.nIdVenchelt = crspolart.id_venchelt
+ Endif
+ If !Isnull(crspolart.id_nota)
+ This.nIdNota = crspolart.id_nota
+ Endif
+ Endif
+ If Used('crspolart')
+ Use In crspolart
+ Endif
+ If !Isnull(This.nIdNota)
+ lcSql = [select n.scd, n.scc from crm_note_vanzari v, note_contabile n ] + ;
+ [where v.id_nota = ] + Alltrim(Str(This.nIdNota)) + [ and n.id_set = v.id_set]
+ If Used('crsnotapol')
+ Use In crsnotapol
+ Endif
+ lnSucces = goExecutor.oExecute(lcSql,[crsnotapol])
+ If lnSucces >= 0 And Reccount('crsnotapol') > 0
+ This.cScd = Alltrim(Nvl(crsnotapol.scd,[]))
+ This.cScc = Alltrim(Nvl(crsnotapol.scc,[]))
+ Endif
+ If Used('crsnotapol')
+ Use In crsnotapol
+ Endif
+ Endif
+ lcSql = [select pack_facturare.cont_venit_articol_stoc(] + Alltrim(Str(tnIdArticol)) + [) as cont_dedus from dual]
+ If Used('crscontded')
+ Use In crscontded
+ Endif
+ lnSucces = goExecutor.oExecute(lcSql,[crscontded])
+ If lnSucces >= 0 And Reccount('crscontded') > 0
+ This.cContDedus = Alltrim(Nvl(crscontded.cont_dedus,[]))
+ Endif
+ If Used('crscontded')
+ Use In crscontded
+ Endif
+ This.lIncarcat = .T.
+ Return .T.
+ Endproc && incarca
+
+ * valideaza conturile si pretul curente; mesaj + .F. la refuz
+ Procedure valideaza
+ This.cEroare = []
+ If (!Empty(This.cScd) And Empty(This.cScc)) Or (Empty(This.cScd) And !Empty(This.cScc))
+ This.cEroare = [Trebuie completate ambele conturi (debit si credit) sau niciunul.]
+ Else
+ If This.nPretFtva < 0 Or This.nPretCtva < 0
+ This.cEroare = [Pretul nu poate fi negativ.]
+ Endif
+ Endif
+ If !Empty(This.cEroare)
+ AMESSAGEBOX(This.cEroare,0+48,"Atentie")
+ Return .F.
+ Endif
+ Return .T.
+ Endproc && valideaza
+
+ * scrie pretul si, daca sunt conturi, nota de vanzare aferenta; fara tranzactie proprie
+ Procedure salveaza
+ Lparameters tnIdArticol
+ Local lcSql, lnSucces
+ Private pnIdArticol, pnPretFtva, pnPretCtva, pnProcTvav, pnIdVenchelt, pnIdNota, pnScrieNota
+ If !This.valideaza()
+ Return .F.
+ Endif
+ If !Empty(This.cScd) And !Empty(This.cScc)
+ Private pcScd, pcScc, pnIdUtil
+ pcScd = This.cScd
+ pcScc = This.cScc
+ pnIdUtil = gnIdUtil
+ pnIdNota = 0
+ lcSql = [begin pack_preturi.gaseste_sau_creeaza_nota_vanzare(?pcScd,?pcScc,?pnIdUtil,?@pnIdNota); end;]
+ lnSucces = goExecutor.oExecute(lcSql)
+ Release pcScd, pcScc, pnIdUtil
+ If lnSucces < 0
+ AMESSAGEBOX(goExecutor.oPrelucrareEroare(),16,"Eroare")
+ Release pnIdArticol, pnPretFtva, pnPretCtva, pnProcTvav, pnIdVenchelt, pnIdNota, pnScrieNota
+ Return .F.
+ Endif
+ This.nIdNota = Nvl(pnIdNota,0)
+ Else
+ This.nIdNota = .NULL.
+ Endif
+ pnIdArticol = tnIdArticol
+ pnPretFtva = This.nPretFtva
+ pnPretCtva = This.nPretCtva
+ pnProcTvav = This.nProcTvav
+ pnIdVenchelt = This.nIdVenchelt
+ pnIdNota = This.nIdNota
+ pnScrieNota = Iif(This.lIncarcat, 1, 0)
+ lcSql = [begin pack_preturi.salveaza_pret_nomenclator(?pnIdArticol,?pnPretFtva,?pnPretCtva,?pnProcTvav,?pnIdVenchelt,?pnIdNota,?pnScrieNota); end;]
+ lnSucces = goExecutor.oExecute(lcSql)
+ If lnSucces < 0
+ AMESSAGEBOX(goExecutor.oPrelucrareEroare(),16,"Eroare")
+ Endif
+ Release pnIdArticol, pnPretFtva, pnPretCtva, pnProcTvav, pnIdVenchelt, pnIdNota, pnScrieNota
+ Return (lnSucces >= 0)
+ Endproc && salveaza
+
+ * recalculeaza pretul opus (cu/fara TVA) dupa proc_tvav curent
+ Procedure recalculeaza_pret
+ Lparameters tnPret, tlSpreCuTva
+ Local lnProcTvav
+ lnProcTvav = Iif(Isnull(This.nProcTvav), (GetProcTvaStandard()+100)/100, This.nProcTvav)
+ If tlSpreCuTva
+ Return Round(tnPret * lnProcTvav, gnPc)
+ Endif
+ Return Round(tnPret / lnProcTvav, gnPc)
+ Endproc && recalculeaza_pret
+
+ * citeste scd/scc din nota curenta a politicii date (goala daca politica nu are nota)
+ Procedure incarca_nota_politica
+ Lparameters tnIdPol
+ Local lcSql, lnSucces
+ This.cScd = []
+ This.cScc = []
+ lcSql = [select n.scd, n.scc from crm_politici_preturi p, crm_note_vanzari v, note_contabile n ] + ;
+ [where p.id_pol = ] + Alltrim(Str(tnIdPol)) + [ and v.id_nota = p.id_nota and n.id_set = v.id_set]
+ If Used('crsnotapolstoc')
+ Use In crsnotapolstoc
+ Endif
+ lnSucces = goExecutor.oExecute(lcSql,[crsnotapolstoc])
+ If lnSucces >= 0 And Reccount('crsnotapolstoc') > 0
+ This.cScd = Alltrim(Nvl(crsnotapolstoc.scd,[]))
+ This.cScc = Alltrim(Nvl(crsnotapolstoc.scc,[]))
+ Endif
+ If Used('crsnotapolstoc')
+ Use In crsnotapolstoc
+ Endif
+ Return !Empty(This.cScd) And !Empty(This.cScc)
+ Endproc && incarca_nota_politica
+
+ * valideaza (ambele conturi sau niciunul) si scrie nota implicita a politicii date
+ Procedure salveaza_nota_politica
+ Lparameters tnIdPol, tcScd, tcScc
+ Local lcSql, lnSucces
+ If (!Empty(tcScd) And Empty(tcScc)) Or (Empty(tcScd) And !Empty(tcScc))
+ This.cEroare = [Trebuie completate ambele conturi (debit si credit) sau niciunul.]
+ AMESSAGEBOX(This.cEroare,0+48,"Atentie")
+ Return .F.
+ Endif
+ If Empty(tcScd) And Empty(tcScc)
+ Return .T.
+ Endif
+ Private pcScd, pcScc, pnIdUtil, pnIdNota, pnIdPol
+ pcScd = tcScd
+ pcScc = tcScc
+ pnIdUtil = gnIdUtil
+ pnIdNota = 0
+ lcSql = [begin pack_preturi.gaseste_sau_creeaza_nota_vanzare(?pcScd,?pcScc,?pnIdUtil,?@pnIdNota); end;]
+ lnSucces = goExecutor.oExecute(lcSql)
+ If lnSucces < 0
+ AMESSAGEBOX(goExecutor.oPrelucrareEroare(),16,"Eroare")
+ Release pcScd, pcScc, pnIdUtil, pnIdNota, pnIdPol
+ Return .F.
+ Endif
+ pnIdPol = tnIdPol
+ lcSql = [begin pack_preturi.seteaza_nota_politica_stoc(?pnIdPol,?pnIdNota); end;]
+ lnSucces = goExecutor.oExecute(lcSql)
+ If lnSucces < 0
+ AMESSAGEBOX(goExecutor.oPrelucrareEroare(),16,"Eroare")
+ Endif
+ Release pcScd, pcScc, pnIdUtil, pnIdNota, pnIdPol
+ Return (lnSucces >= 0)
+ Endproc && salveaza_nota_politica
+Enddefine
+****************************************** SFARSIT: cus_pret_nomenclator ****************************************
+*********************************************************************************************************
diff --git a/utile/Teste/facturare_unificat/probe_12b_s4b_matrice.prg b/utile/Teste/facturare_unificat/probe_12b_s4b_matrice.prg
new file mode 100644
index 0000000..e98c113
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s4b_matrice.prg
@@ -0,0 +1,626 @@
+* probe_12b_s4b_matrice.prg
+* Plan #12b, S4b - proba A (matrice, zero date) + "mutatie de control" pe pachetul de DINAINTE
+* de S4b. Starea curenta a schemei (MARIUSM_AUTO) la data rularii: S4a aplicat (functia
+* pack_facturare.cont_venit_articol_stoc exista), dar cursor_articol din contabilizeaza_articol
+* NU citeste inca A.ID_NOTA, nu deduce SCC din cont si nu are garda FACT-033 - SCD/SCC/ASCD/ASCC
+* vin azi INTOTDEAUNA din nota politicii (B.ID_NOTA), indiferent de politica sau de articol.
+*
+* Apeleaza direct pack_facturare.contabilizeaza_articol(v_row) cu un rand
+* VANZARI_DETALII_TEMP%ROWTYPE construit in PL/SQL (fara sa treaca prin RPC-ul de adaugare
+* linie/UI), citeste rezultatul din ACT_TEMP (GTT ON COMMIT DELETE ROWS) in aceeasi tranzactie
+* manuala (Transactions=2). Fiecare caz care muta date (ID_NOTA pe rand sau pe politica, CONT pe
+* articol) isi restaureaza mutatia INAUNTRUL propriului bloc PL/SQL (pe calea de succes SI pe
+* exceptie, ca sa nu contamineze cazurile urmatoare cand acest script va fi rerulat dupa ce S4b
+* va introduce chiar erorile FACT-033 asteptate) - ROLLBACK-ul final e doar plasa de siguranta.
+*
+* Asteptarile (valorile "S4b" din sectiunea 3 a planului) sunt calculate independent de codul
+* testat: din baseline_12b.md sectiunea 6 (notele 5 si 6, statice) si din interogari separate
+* (nota politicii reale, pack_facturare.GetAnaliticByGrupUtilizatori) - nu din cursor_articol.
+*
+* Rulare: powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume probe_12b_s4b_matrice
+* Log: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\probe_12b_s4b_matrice.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail, gnTransOriginal, gcErrMsg
+gcErrMsg = ""
+gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\probe_12b_s4b_matrice.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out")
+ MD "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+gnIdUtil = 8
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle)
+
+gnTransOriginal = SQLGETPROP(gnHandle, "Transactions")
+SQLSETPROP(gnHandle, "Transactions", 2)
+DO AfLog WITH "Transactions manual, original=" + TRANSFORM(gnTransOriginal)
+
+*----------------------------------------------------------------------------------------
+* precondition: nid_politica_stoc = 41 dupa initializeaza_facturare(8) - altfel ramurile
+* "politica reala" ar trece tautologic (nimic nu ar mai fi cu adevarat "politica de stoc")
+gcCaz = "[precondition] "
+LOCAL lnOk, lcSql
+* pack_facturare are propriile variabile de antet de document (nnumar_act, cserie_act, datele,
+* nid_moneda_nationala, nperechec, nid_fdoc, nid_factc, nid_part, nid_partc, nid_set - toate
+* NOT NULL in ACT_TEMP sau folosite in DECODE-uri care ajung acolo) - neinitializate de
+* initializeaza_facturare (care seteaza doar politica de stoc) si nici de test_init_env_auto_*.
+* Fara ele contabilizeaza_articol pica pe ORA-01400 (NRACT/PERECHEC/ID_SET) inainte sa ajunga la
+* SCD/SCC - descoperit prin proba directa pe sqlplus, nu presupus.
+lcSql = [begin pack_facturare.initializeaza_facturare(8); ] + ;
+ [if nvl(pack_facturare.nid_politica_stoc,0) <> 41 then raise_application_error(-20900,'nid_politica_stoc='||to_char(pack_facturare.nid_politica_stoc)); end if; ] + ;
+ [pack_facturare.nnumar_act := 999999; pack_facturare.cserie_act := 'TST'; ] + ;
+ [pack_facturare.ddata_ireg := sysdate; pack_facturare.ddata_act := sysdate; pack_facturare.ddata_scadenta := sysdate; ] + ;
+ [pack_facturare.nid_moneda_nationala := 3; pack_facturare.nperechec := 0; pack_facturare.nid_fdoc := 0; ] + ;
+ [pack_facturare.nid_factc := 0; pack_facturare.nid_part := 0; pack_facturare.nid_partc := 0; pack_facturare.nid_set := 25000; ] + ;
+ [pack_facturare.nid_sectie_stoc := nvl(pack_facturare.nid_sectie_stoc,1); end;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "initializeaza_facturare(8) + antet document proba + precondition nid_politica_stoc=41"
+IF lnOk <= 0
+ DO AfLog WITH "BLOCAT: precondition esuata, opresc"
+ DO Final
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* descoperire (read-only): articolul singurei politici 32/33, politica reala a articolului 1
+* (D5), nota acelei politici reale, si analiticele de grup (GetAnaliticByGrupUtilizatori) pentru
+* conturile folosite mai jos - toate independente de cursor_articol
+gcCaz = "[descoperire] "
+LOCAL lnArtPol32, lnArtPol33, lnPolReala1, lnNotaRealaOrig
+lnArtPol32 = 0
+lnArtPol33 = 0
+lnPolReala1 = 0
+lnNotaRealaOrig = 0
+
+lnOk = SQLEXEC(gnHandle, "select id_articol from crm_politici_pret_art where id_pol = 32 and rownum = 1", "crsp32")
+IF lnOk > 0 AND USED('crsp32') AND RECCOUNT('crsp32') = 1
+ lnArtPol32 = crsp32.id_articol
+ENDIF
+IF USED('crsp32')
+ USE IN crsp32
+ENDIF
+DO AfLog WITH "articol politica 32 (HOTEL TAXE) = " + TRANSFORM(lnArtPol32)
+
+lnOk = SQLEXEC(gnHandle, "select id_articol from crm_politici_pret_art where id_pol = 33 and rownum = 1", "crsp33")
+IF lnOk > 0 AND USED('crsp33') AND RECCOUNT('crsp33') = 1
+ lnArtPol33 = crsp33.id_articol
+ENDIF
+IF USED('crsp33')
+ USE IN crsp33
+ENDIF
+DO AfLog WITH "articol politica 33 (HOTEL CAZARE) = " + TRANSFORM(lnArtPol33)
+
+lnOk = SQLEXEC(gnHandle, "select id_pol from crm_politici_pret_art where id_articol = 1 and id_pol <> 41 and rownum = 1", "crspr1")
+IF lnOk > 0 AND USED('crspr1') AND RECCOUNT('crspr1') = 1
+ lnPolReala1 = crspr1.id_pol
+ENDIF
+IF USED('crspr1')
+ USE IN crspr1
+ENDIF
+DO AfLog WITH "politica reala a articolului 1 (D5) = " + TRANSFORM(lnPolReala1)
+
+IF lnArtPol32 = 0 OR lnArtPol33 = 0 OR lnPolReala1 = 0
+ DO AfLog WITH "BLOCAT: descoperire incompleta (art32=" + TRANSFORM(lnArtPol32) + " art33=" + TRANSFORM(lnArtPol33) + " polreala1=" + TRANSFORM(lnPolReala1) + ")"
+ DO Final
+ENDIF
+
+LOCAL lcScdReal, lcAscdReal, lcSccReal, lcAsccReal
+lcScdReal = ""
+lcAscdReal = ""
+lcSccReal = ""
+lcAsccReal = ""
+lcSql = "select b.id_nota, nvl(d.scd,'') scd, nvl(d.ascd,'') ascd, nvl(d.scc,'') scc, nvl(d.ascc,'') ascc" + ;
+ " from crm_politici_preturi b join crm_note_vanzari c on b.id_nota = c.id_nota join note_contabile d on c.id_set = d.id_set" + ;
+ " where b.id_pol = " + TRANSFORM(lnPolReala1)
+lnOk = SQLEXEC(gnHandle, lcSql, "crsnr")
+IF lnOk > 0 AND USED('crsnr') AND RECCOUNT('crsnr') = 1
+ lnNotaRealaOrig = crsnr.id_nota
+ lcScdReal = ALLTRIM(crsnr.scd)
+ lcAscdReal = ALLTRIM(crsnr.ascd)
+ lcSccReal = ALLTRIM(crsnr.scc)
+ lcAsccReal = ALLTRIM(crsnr.ascc)
+ELSE
+ DO AfLog WITH "BLOCAT: nu am gasit nota politicii reale " + TRANSFORM(lnPolReala1)
+ DO Final
+ENDIF
+IF USED('crsnr')
+ USE IN crsnr
+ENDIF
+DO AfLog WITH "nota politicii reale " + TRANSFORM(lnPolReala1) + " = id_nota " + TRANSFORM(lnNotaRealaOrig) + " SCD=" + lcScdReal + " ASCD=" + lcAscdReal + " SCC=" + lcSccReal + " ASCC=" + lcAsccReal
+
+LOCAL lcAsc4111, lcAsc461, lcAsc7583, lcAsc707, lcAsc7015, lcAsc418, lcAscScdReal, lcAscSccReal
+lcSql = "select nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'4111'),'') a1, nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'461'),'') a2," + ;
+ " nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'7583'),'') a3, nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'707'),'') a4," + ;
+ " nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'7015'),'') a5, nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'418'),'') a6," + ;
+ " nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'" + lcScdReal + "'),'') a7, nvl(pack_facturare.GetAnaliticByGrupUtilizatori(8,'" + lcSccReal + "'),'') a8" + ;
+ " from dual"
+lnOk = SQLEXEC(gnHandle, lcSql, "crsga")
+IF lnOk > 0 AND USED('crsga') AND RECCOUNT('crsga') = 1
+ lcAsc4111 = ALLTRIM(crsga.a1)
+ lcAsc461 = ALLTRIM(crsga.a2)
+ lcAsc7583 = ALLTRIM(crsga.a3)
+ lcAsc707 = ALLTRIM(crsga.a4)
+ lcAsc7015 = ALLTRIM(crsga.a5)
+ lcAsc418 = ALLTRIM(crsga.a6)
+ lcAscScdReal = ALLTRIM(crsga.a7)
+ lcAscSccReal = ALLTRIM(crsga.a8)
+ELSE
+ DO AfLog WITH "BLOCAT: nu am putut citi analiticele de grup"
+ DO Final
+ENDIF
+IF USED('crsga')
+ USE IN crsga
+ENDIF
+* fallback NVL ca in cod: daca nota nu are ASCD/ASCC propriu, cel efectiv e cel din grup
+IF lcAscdReal == ""
+ lcAscdReal = lcAscScdReal
+ENDIF
+IF lcAsccReal == ""
+ lcAsccReal = lcAscSccReal
+ENDIF
+DO AfLog WITH "GetAnaliticByGrupUtilizatori(8,.): 4111=" + lcAsc4111 + " 461=" + lcAsc461 + " 7583=" + lcAsc7583 + " 707=" + lcAsc707 + " 7015=" + lcAsc7015 + " 418=" + lcAsc418
+DO AfLog WITH "ASCD/ASCC efective (dupa fallback NVL) ale politicii reale " + TRANSFORM(lnPolReala1) + ": ASCD=" + lcAscdReal + " ASCC=" + lcAsccReal
+
+* nota 6 (PRODUCTIE, politica 41) si nota 5 (VANZARE MARFA) - statice, din baseline_12b.md sect. 6
+LOCAL lcN6Scd, lcN6Ascd, lcN6Scc, lcN6Ascc, lcN5Scd, lcN5Ascd, lcN5Scc, lcN5Ascc
+lcN6Scd = "4111"
+lcN6Ascd = lcAsc4111 && nota 6 are ASCD gol -> fallback grup
+lcN6Scc = "7015"
+lcN6Ascc = lcAsc7015 && nota 6 are ASCC gol -> fallback grup
+lcN5Scd = "4111"
+lcN5Ascd = "11"
+lcN5Scc = "707"
+lcN5Ascc = "11"
+
+*----------------------------------------------------------------------------------------
+* CAZ 1: nota pe rand (A.ID_NOTA) 461=7583, creata in tranzactie pe un articol fara nota proprie
+* Tinta S4b (D10 regula 1): SCD/SCC/ASCD/ASCC din nota RANDULUI = 461/7583/asc461/asc7583
+gcCaz = "[caz1-nota-pe-rand-461-7583] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; v_id_nota crm_note_vanzari.id_nota%TYPE; v_id_set crm_note_vanzari.id_set%TYPE; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901000; ] + ;
+ [INSERT INTO crm_note_vanzari (denumire, id_util, id_sectie, dataora) VALUES ('PROBA S4B CAZ1', 8, 1, SYSDATE) RETURNING id_nota, id_set INTO v_id_nota, v_id_set; ] + ;
+ [INSERT INTO note_contabile (explicatie, scd, scc, ordine, cu_tva, ptva, id_set, in_valuta, id_jtva_coloana) VALUES ('PROBA S4B CAZ1', '461', '7583', 1, 1, 21, v_id_set, 0, 35); ] + ;
+ [UPDATE crm_politici_pret_art SET id_nota = v_id_nota WHERE id_pol = 41 AND id_articol = 4294507216; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := 4294507216; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ1'; v_row.proc_tvav := 1.19; ] + ;
+ [BEGIN v_res := pack_facturare.contabilizeaza_articol(v_row); ] + ;
+ [EXCEPTION WHEN OTHERS THEN UPDATE crm_politici_pret_art SET id_nota = NULL WHERE id_pol = 41 AND id_articol = 4294507216; RAISE; END; ] + ;
+ [UPDATE crm_politici_pret_art SET id_nota = NULL WHERE id_pol = 41 AND id_articol = 4294507216; END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "apelul a trecut fara eroare (azi nicio garda pe nota randului)"
+IF lnOk > 0
+ DO LeaActTemp WITH -900999
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " ASCD=" + ALLTRIM(crsact.ascd) + " SCC=" + ALLTRIM(crsact.scc) + " ASCC=" + ALLTRIM(crsact.ascc)
+ DO AfLog WITH "asteptat S4b: SCD=461 ASCD=" + lcAsc461 + " SCC=7583 ASCC=" + lcAsc7583
+ DO Verdict WITH ALLTRIM(crsact.scd) == "461" AND ALLTRIM(crsact.scc) == "7583", "SCD/SCC = nota randului (461/7583) - tinta S4b regula 1"
+ ELSE
+ DO Verdict WITH .F., "nicio linie in ACT_TEMP (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 2: articol CONT=371 (CORESP->707) pe politica 41, cu nota 5 (ASCC=11) fortata temporar ca
+* nota implicita a politicii 41. Tinta S4b (D10 regula 2): SCC=707 (dedus), ASCC din grup - NU 11
+gcCaz = "[caz2-cont371-nota5-ascc-grup] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; v_orig NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901100; ] + ;
+ [SELECT id_nota INTO v_orig FROM crm_politici_preturi WHERE id_pol = 41; ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = 5 WHERE id_pol = 41; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := 2910202427; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ2'; v_row.proc_tvav := 1.19; ] + ;
+ [BEGIN v_res := pack_facturare.contabilizeaza_articol(v_row); ] + ;
+ [EXCEPTION WHEN OTHERS THEN UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = 41; RAISE; END; ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = 41; END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "apelul a trecut fara eroare"
+IF lnOk > 0
+ DO LeaActTemp WITH -901099
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " ASCD=" + ALLTRIM(crsact.ascd) + " SCC=" + ALLTRIM(crsact.scc) + " ASCC=" + ALLTRIM(crsact.ascc)
+ DO AfLog WITH "asteptat S4b: SCD=" + lcN5Scd + " ASCD=" + lcN5Ascd + " SCC=707 ASCC(grup)=" + lcAsc707 + " [azi foloseste ASCC-ul notei=11, nu grupul]"
+ DO Verdict WITH ALLTRIM(crsact.scc) == "707" AND ALLTRIM(crsact.ascc) == lcAsc707, "SCC dedus (707) SI ASCC din grup (nu 11 din nota) - tinta S4b regula 2"
+ ELSE
+ DO Verdict WITH .F., "nicio linie in ACT_TEMP (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 3: articol scratch (4294507213, DISCOUNT) cu CONT temporar '707' (incepe cu 7 -> dedus =
+* el insusi), pe politica 41 cu nota implicita neatinsa (nota 6). Tinta S4b: SCC=707 (dedus),
+* nu 7015 (nota politicii, cum e azi)
+gcCaz = "[caz3-cont707-dedus] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; v_orig_cont nom_articole.cont%TYPE; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901200; ] + ;
+ [SELECT cont INTO v_orig_cont FROM nom_articole WHERE id_articol = 4294507213; ] + ;
+ [UPDATE nom_articole SET cont = '707' WHERE id_articol = 4294507213; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := 4294507213; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ3'; v_row.proc_tvav := 1.19; ] + ;
+ [BEGIN v_res := pack_facturare.contabilizeaza_articol(v_row); ] + ;
+ [EXCEPTION WHEN OTHERS THEN UPDATE nom_articole SET cont = v_orig_cont WHERE id_articol = 4294507213; RAISE; END; ] + ;
+ [UPDATE nom_articole SET cont = v_orig_cont WHERE id_articol = 4294507213; END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "apelul a trecut fara eroare"
+IF lnOk > 0
+ DO LeaActTemp WITH -901199
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " ASCD=" + ALLTRIM(crsact.ascd) + " SCC=" + ALLTRIM(crsact.scc) + " ASCC=" + ALLTRIM(crsact.ascc)
+ DO AfLog WITH "asteptat S4b: SCD=" + lcN6Scd + " ASCD=" + lcN6Ascd + " SCC=707 ASCC(grup)=" + lcAsc707
+ DO Verdict WITH ALLTRIM(crsact.scc) == "707", "SCC = cont dedus (707), nu nota politicii (7015) - tinta S4b regula 2"
+ ELSE
+ DO Verdict WITH .F., "nicio linie in ACT_TEMP (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 4: articol fara cont (CONT NULL), pe politica 41, fara nicio mutatie. Tinta S4b (regula 3,
+* fallback) = nota politicii = azi (4111/7015) - neschimbat de S4b
+gcCaz = "[caz4-faracont-notapolitica] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901300; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := 4294507216; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ4'; v_row.proc_tvav := 1.19; ] + ;
+ [v_res := pack_facturare.contabilizeaza_articol(v_row); END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "apelul a trecut fara eroare"
+IF lnOk > 0
+ DO LeaActTemp WITH -901299
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " ASCD=" + ALLTRIM(crsact.ascd) + " SCC=" + ALLTRIM(crsact.scc) + " ASCC=" + ALLTRIM(crsact.ascc)
+ DO AfLog WITH "asteptat S4b: SCD=" + lcN6Scd + " ASCD=" + lcN6Ascd + " SCC=" + lcN6Scc + " ASCC=" + lcN6Ascc
+ DO Verdict WITH ALLTRIM(crsact.scd) == lcN6Scd AND ALLTRIM(crsact.scc) == lcN6Scc, "SCD/SCC = nota politicii (4111/7015) - neschimbat de S4b"
+ ELSE
+ DO Verdict WITH .F., "nicio linie in ACT_TEMP (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 5: politica de stoc cu ID_NOTA (al politicii) NULL temporar + articol fara cont. Tinta S4b:
+* FACT-033 (SCC final NULL -> refuz). Azi: nicio garda, linia se scrie cu SCD/SCC NULL (gaura V2)
+gcCaz = "[caz5-politicastoc-faranota-faracont] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; v_orig NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901400; ] + ;
+ [SELECT id_nota INTO v_orig FROM crm_politici_preturi WHERE id_pol = 41; ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = NULL WHERE id_pol = 41; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := 4294507216; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ5'; v_row.proc_tvav := 1.19; ] + ;
+ [BEGIN v_res := pack_facturare.contabilizeaza_articol(v_row); ] + ;
+ [EXCEPTION WHEN OTHERS THEN UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = 41; RAISE; END; ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = 41; END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+IF lnOk <= 0
+ DO LogErr
+ DO Verdict WITH .T., "S4b implementat: garda a refuzat linia fara cont de venit (asteptarea planului)"
+ DO VerifMesajFact033 WITH 4294507216, 41
+ELSE
+ DO LeaActTemp WITH -901399
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " SCC=" + ALLTRIM(crsact.scc) + " (asteptat S4b: eroare FACT-033, nicio linie)"
+ DO Verdict WITH .F., "FACT-033 absenta - linia s-a scris cu SCD/SCC NULL (gaura V2, S4b trebuie sa o astupe)"
+ ELSE
+ DO Verdict WITH .F., "nicio linie si nicio eroare (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 6: nota politicii cu AL DOILEA rand adaugat in NOTE_CONTABILE (acelasi ID_SET). Tinta S4b:
+* FACT-033 (garda pe nota cu mai mult de un rand). Azi: WHILE cursor_articol%FOUND dubleaza
+* venitul - 2 randuri in ACT_TEMP, fara nicio eroare
+gcCaz = "[caz6-nota-dublu-rand] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; v_orig NUMBER; v_id_nota crm_note_vanzari.id_nota%TYPE; v_id_set crm_note_vanzari.id_set%TYPE; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901500; ] + ;
+ [SELECT id_nota INTO v_orig FROM crm_politici_preturi WHERE id_pol = 41; ] + ;
+ [INSERT INTO crm_note_vanzari (denumire, id_util, id_sectie, dataora) VALUES ('PROBA S4B CAZ6', 8, 1, SYSDATE) RETURNING id_nota, id_set INTO v_id_nota, v_id_set; ] + ;
+ [INSERT INTO note_contabile (explicatie, scd, scc, ordine, cu_tva, ptva, id_set, in_valuta, id_jtva_coloana) VALUES ('PROBA S4B CAZ6 rand1', '461', '7583', 1, 1, 21, v_id_set, 0, 35); ] + ;
+ [INSERT INTO note_contabile (explicatie, scd, scc, ordine, cu_tva, ptva, id_set, in_valuta, id_jtva_coloana) VALUES ('PROBA S4B CAZ6 rand2', '462', '7584', 2, 1, 21, v_id_set, 0, 35); ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = v_id_nota WHERE id_pol = 41; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := 4294507216; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ6'; v_row.proc_tvav := 1.19; ] + ;
+ [BEGIN v_res := pack_facturare.contabilizeaza_articol(v_row); ] + ;
+ [EXCEPTION WHEN OTHERS THEN UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = 41; RAISE; END; ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = 41; END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+IF lnOk <= 0
+ DO LogErr
+ DO Verdict WITH .T., "S4b implementat: garda a refuzat nota cu mai mult de un rand (asteptarea planului)"
+ DO VerifMesajFact033 WITH 4294507216, 41
+ELSE
+ LOCAL lnCnt
+ lnCnt = 0
+ IF USED('crscnt')
+ USE IN crscnt
+ ENDIF
+ lnOk = SQLEXEC(gnHandle, "select count(*) cnt from act_temp where id_act between -901499 and -901498", "crscnt")
+ IF lnOk > 0 AND USED('crscnt')
+ lnCnt = crscnt.cnt
+ ENDIF
+ IF USED('crscnt')
+ USE IN crscnt
+ ENDIF
+ DO AfLog WITH "obtinut azi: " + TRANSFORM(lnCnt) + " randuri in ACT_TEMP (asteptat S4b: 0, eroare FACT-033)"
+ IF lnCnt = 2
+ DO LeaActTemp WITH -901499
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH " rand1: SCD=" + ALLTRIM(crsact.scd) + " SCC=" + ALLTRIM(crsact.scc)
+ ENDIF
+ IF USED('crsact')
+ USE IN crsact
+ ENDIF
+ DO LeaActTemp WITH -901498
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH " rand2: SCD=" + ALLTRIM(crsact.scd) + " SCC=" + ALLTRIM(crsact.scc)
+ ENDIF
+ IF USED('crsact')
+ USE IN crsact
+ ENDIF
+ ENDIF
+ DO Verdict WITH .F., "FACT-033 absenta - venitul se dubleaza tacut (" + TRANSFORM(lnCnt) + " randuri), S4b trebuie sa refuze"
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 7: acelasi articol D5 (id=1, CONT=371) pe politica REALA (nu de stoc), fara nicio mutatie.
+* Tinta S4b: nota politicii reale, neschimbata - regulile D9/D10 nu ating politicile reale
+gcCaz = "[caz7-articol1-politica-reala] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901600; ] + ;
+ [v_row.id_pol := ] + TRANSFORM(lnPolReala1) + [; v_row.id_articol := 1; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ7'; v_row.proc_tvav := 1.19; ] + ;
+ [v_res := pack_facturare.contabilizeaza_articol(v_row); END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "apelul a trecut fara eroare"
+IF lnOk > 0
+ DO LeaActTemp WITH -901599
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " ASCD=" + ALLTRIM(crsact.ascd) + " SCC=" + ALLTRIM(crsact.scc) + " ASCC=" + ALLTRIM(crsact.ascc)
+ DO AfLog WITH "asteptat (azi si dupa S4b, neschimbat): SCD=" + lcScdReal + " ASCD=" + lcAscdReal + " SCC=" + lcSccReal + " ASCC=" + lcAsccReal
+ DO Verdict WITH ALLTRIM(crsact.scd) == lcScdReal AND ALLTRIM(crsact.scc) == lcSccReal, "SCD/SCC = nota politicii reale, neschimbat de S4b"
+ ELSE
+ DO Verdict WITH .F., "nicio linie in ACT_TEMP (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 8: politica 32 (HOTEL TAXE), fara nota deloc. Tinta S4b: FACT-033. Azi: SCD/SCC NULL, fara eroare
+gcCaz = "[caz8-politica32-faranota] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901700; ] + ;
+ [v_row.id_pol := 32; v_row.id_articol := ] + TRANSFORM(lnArtPol32) + [; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ8'; v_row.proc_tvav := 1.19; ] + ;
+ [v_res := pack_facturare.contabilizeaza_articol(v_row); END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+IF lnOk <= 0
+ DO LogErr
+ DO Verdict WITH .T., "S4b implementat: garda a refuzat politica 32 fara nota (asteptarea planului)"
+ DO VerifMesajFact033 WITH lnArtPol32, 32
+ELSE
+ DO LeaActTemp WITH -901699
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " SCC=" + ALLTRIM(crsact.scc) + " (asteptat S4b: eroare FACT-033)"
+ ENDIF
+ DO Verdict WITH .F., "FACT-033 absenta - politica reala fara nota trece tacut azi"
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 9: politica 33 (HOTEL CAZARE), fara nota deloc. Tinta S4b: FACT-033. Azi: idem caz 8
+gcCaz = "[caz9-politica33-faranota] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901800; ] + ;
+ [v_row.id_pol := 33; v_row.id_articol := ] + TRANSFORM(lnArtPol33) + [; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ9'; v_row.proc_tvav := 1.19; ] + ;
+ [v_res := pack_facturare.contabilizeaza_articol(v_row); END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+IF lnOk <= 0
+ DO LogErr
+ DO Verdict WITH .T., "S4b implementat: garda a refuzat politica 33 fara nota (asteptarea planului)"
+ DO VerifMesajFact033 WITH lnArtPol33, 33
+ELSE
+ DO LeaActTemp WITH -901799
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " SCC=" + ALLTRIM(crsact.scc) + " (asteptat S4b: eroare FACT-033)"
+ ENDIF
+ DO Verdict WITH .F., "FACT-033 absenta - politica reala fara nota trece tacut azi"
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 10: politica reala D5 (a articolului 1) cu ID_NOTA pus pe NULL temporar. Tinta S4b:
+* FACT-033 (garda "pe orice politica", nu doar de stoc). Azi: SCD/SCC NULL, fara eroare
+gcCaz = "[caz10-politicareala-notanull] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; v_orig NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -901900; ] + ;
+ [SELECT id_nota INTO v_orig FROM crm_politici_preturi WHERE id_pol = ] + TRANSFORM(lnPolReala1) + [; ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = NULL WHERE id_pol = ] + TRANSFORM(lnPolReala1) + [; ] + ;
+ [v_row.id_pol := ] + TRANSFORM(lnPolReala1) + [; v_row.id_articol := 1; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ10'; v_row.proc_tvav := 1.19; ] + ;
+ [BEGIN v_res := pack_facturare.contabilizeaza_articol(v_row); ] + ;
+ [EXCEPTION WHEN OTHERS THEN UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = ] + TRANSFORM(lnPolReala1) + [; RAISE; END; ] + ;
+ [UPDATE crm_politici_preturi SET id_nota = v_orig WHERE id_pol = ] + TRANSFORM(lnPolReala1) + [; END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+IF lnOk <= 0
+ DO LogErr
+ DO Verdict WITH .T., "S4b implementat: garda a refuzat politica reala fara nota (asteptarea planului)"
+ DO VerifMesajFact033 WITH 1, lnPolReala1
+ELSE
+ DO LeaActTemp WITH -901899
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " SCC=" + ALLTRIM(crsact.scc) + " (asteptat S4b: eroare FACT-033)"
+ ENDIF
+ DO Verdict WITH .F., "FACT-033 absenta - garda azi nu exista pe nicio politica"
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+* verificare restaurare politica reala (defensiv, inainte de ROLLBACK-ul final)
+lnOk = SQLEXEC(gnHandle, "select id_nota from crm_politici_preturi where id_pol = " + TRANSFORM(lnPolReala1), "crschk")
+IF lnOk > 0 AND USED('crschk') AND RECCOUNT('crschk') = 1
+ DO Verdict WITH crschk.id_nota == lnNotaRealaOrig, "restaurare in tranzactie: politica reala " + TRANSFORM(lnPolReala1) + " are din nou id_nota=" + TRANSFORM(lnNotaRealaOrig)
+ENDIF
+IF USED('crschk')
+ USE IN crschk
+ENDIF
+
+*----------------------------------------------------------------------------------------
+* CAZ 11 (aviz, ntip=22): articol CONT=371 (CORESP->707) pe politica 41, nota implicita restaurata
+* (nota 6). SCD e fortat 418 pe avize INDIFERENT de S4b (cod neschimbat); SCC: azi=nota (7015),
+* tinta S4b=dedus (707)
+gcCaz = "[caz11-aviz-scd418-sccdedus] "
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 22; pack_facturare.nid_act := -902000; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := 2910202427; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 10; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S4B CAZ11'; v_row.proc_tvav := 1.19; ] + ;
+ [v_res := pack_facturare.contabilizeaza_articol(v_row); END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "apelul a trecut fara eroare"
+IF lnOk > 0
+ DO LeaActTemp WITH -901999
+ IF USED('crsact') AND RECCOUNT('crsact') = 1
+ DO AfLog WITH "obtinut azi: SCD=" + ALLTRIM(crsact.scd) + " ASCD=" + ALLTRIM(crsact.ascd) + " SCC=" + ALLTRIM(crsact.scc) + " ASCC=" + ALLTRIM(crsact.ascc)
+ DO AfLog WITH "asteptat S4b: SCD=418 ASCD=" + lcAsc418 + " SCC=707 ASCC(grup)=" + lcAsc707
+ DO Verdict WITH ALLTRIM(crsact.scd) == "418", "SCD=418 pe aviz - neschimbat de S4b (cod deja existent)"
+ DO Verdict WITH ALLTRIM(crsact.scc) == "707", "SCC = cont dedus (707), nu nota politicii (7015) - tinta S4b regula 2, valabila si pe aviz"
+ ELSE
+ DO Verdict WITH .F., "nicio linie in ACT_TEMP (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact')
+ USE IN crsact
+ENDIF
+
+DO Final
+
+*----------------------------------------------------------------------------------------
+PROCEDURE LogErr
+ LOCAL laErr[1]
+ AERROR(laErr)
+ gcErrMsg = TRANSFORM(laErr[2])
+ DO AfLog WITH " eroare reala: " + TRANSFORM(laErr[1]) + " / " + gcErrMsg
+ENDPROC
+
+PROCEDURE VerifMesajFact033
+ * verifica ca mesajul FACT-033 (gcErrMsg, populat de LogErr) numeste articolul si politica -
+ * denumirile vin din tabele, in afara pachetului testat
+ LPARAMETERS tnIdArticol, tnIdPol
+ LOCAL lcDenArt, lcDenPol
+ lcDenArt = ""
+ lcDenPol = ""
+ IF USED('crsver')
+ USE IN crsver
+ ENDIF
+ IF SQLEXEC(gnHandle, "select denumire from nom_articole where id_articol = " + TRANSFORM(tnIdArticol), "crsver") > 0 AND USED('crsver')
+ lcDenArt = ALLTRIM(crsver.denumire)
+ ENDIF
+ IF USED('crsver')
+ USE IN crsver
+ ENDIF
+ IF SQLEXEC(gnHandle, "select nume_lista_preturi from crm_politici_preturi where id_pol = " + TRANSFORM(tnIdPol), "crsver") > 0 AND USED('crsver')
+ lcDenPol = ALLTRIM(crsver.nume_lista_preturi)
+ ENDIF
+ IF USED('crsver')
+ USE IN crsver
+ ENDIF
+ DO Verdict WITH !EMPTY(lcDenArt) AND !EMPTY(lcDenPol) AND lcDenArt $ gcErrMsg AND lcDenPol $ gcErrMsg, ;
+ "mesajul FACT-033 numeste articolul (" + lcDenArt + ") si politica (" + lcDenPol + "): " + gcErrMsg
+ENDPROC
+
+PROCEDURE LeaActTemp
+ LPARAMETERS tnIdAct
+ LOCAL lnRet
+ IF USED('crsact')
+ USE IN crsact
+ ENDIF
+ lnRet = SQLEXEC(gnHandle, "select nvl(scd,'') scd, nvl(ascd,'') ascd, nvl(scc,'') scc, nvl(ascc,'') ascc from act_temp where id_act = " + TRANSFORM(tnIdAct), "crsact")
+ RETURN lnRet
+ENDPROC
+
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk)
+ IF TYPE('gnTransOriginal') = 'N'
+ SQLSETPROP(gnHandle, "Transactions", gnTransOriginal)
+ ENDIF
+ DO AfLog WITH "TOTAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_12b_s4b_proba_b_dupa.prg b/utile/Teste/facturare_unificat/probe_12b_s4b_proba_b_dupa.prg
new file mode 100644
index 0000000..dda259e
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s4b_proba_b_dupa.prg
@@ -0,0 +1,763 @@
+* probe_12b_s4b_proba_b_dupa.prg
+* Plan 12b, S4b partea 3 - Proba B "DUPA": copie a probe_12b_s4b_proba_b_inainte.prg (mecanica
+* nemodificata), aceeasi emitere reala (tip_incasare=1, "Fara incasare", forma veche) - client
+* RAJA (id_part=463), plaja utilizatorului 8. Se ruleaza PE PACHETUL NOU (wip12_07, D10 aplicat),
+* ca sa produca documentul comparat cu cel "inainte" (id_vanzare=1883) prin
+* lib_comparatie_documente.CompAct.
+*
+* Criteriul 1 de "gata" al S3b, PROBA REALA (nu structurala): emite documente REALE in Oracle
+* (MARIUSM_AUTO@ROA_CENTRAL, aprobat explicit de Marius) prin fluxul de emitere efectiv, pe
+* fiecare din cele patru tipuri de incasare (1=Fara incasare, 2=Chitanta, 3=Bon fiscal, 4=POS/Card),
+* o data pe formularul vechi (frm_facturare_articole) si o data pe cel unificat
+* (frm_facturare_articole2), si compara randurile persistate in VANZARI dupa commit.
+*
+* Sursa documentului e cursor_preturi (lista de preturi, client RAJA id_part=463) cu tnTip=22 -
+* singura combinatie confirmata prin proba read-only (probe_emitere_reala.prg) ca intoarce articole
+* in acest mediu; tnTip=5 (FACTURA direct) da Reccount=0. Numerotarea/serie a documentului ramane
+* cea naturala pentru tnTip=22 (AVIZ, nIdTipDoc=6, plaja globala) - neatinsa, nu conteaza pentru
+* criteriul de paritate a INCASARII, care e independent de seria documentului.
+*
+* Mecanica bazata pe COMUN\utile\Teste\editare_factura\creeaza_documente_s8.prg (mediu Oracle real
+* + clase de productie, dovedit ca emite documente reale pentru tnTip=22): dialogul modal de antet
+* e inlocuit cu setare directa poDate (ca acolo), iar "Do Form verificare" (ofacturare.vc2:14404 /
+* :20126) e ocolit cu acelasi stub versionat COMUN\utile\Teste\achizitie_import\stub_verificare\
+* (SET PATH cu el primul).
+*
+* Diferenta fata de creeaza_documente_s8.prg: al doilea modal (frm_alte_date, doar pe calea veche)
+* NU e doar "confirmat" - un driver pe Timer ii seteaza opt_incasat.Value la tipul cerut INAINTE
+* sa-i cheme do_termin(), exact tehnica validata structural in test_s3b_paritate_emitere.prg (setarea
+* de .Value declanseaza opt_incasat.ProgrammaticChange -> actualizeaza_tipincasare(), cod real).
+* Pe calea noua nu exista al doilea modal (opt_incasat e inline pe formular): se seteaza direct pe
+* goFrm inainte de goFrm.do_termin().
+*
+* De ce NU se compara nr_incasare/NR_INCASAT intre vechi si nou (asa cum a facut suita structurala):
+* acolo numerele erau dezalocate dupa fiecare tip, deci acelasi numar fizic se realoca in faza 2.
+* Aici documentele raman scrise (nu se dezaloca nimic dupa un commit reusit), deci vechi si nou aloca
+* NUMERE DIFERITE, consecutive, din aceeasi plaja - egalitatea lor ar fi o eroare, nu o dovada.
+* Paritatea reala verificata e (a) consistenta interna - VANZARI.NR_INCASAT persistat == poDate.nr_incasare
+* capturat chiar inainte de scriere, pe fiecare document in parte, si (b) egalitatea intre vechi/nou a
+* CODULUI de tip (VANZARI.TIP_INCASAT) si a SUMEI (VANZARI.SUMA_INCASAT) - marimi care nu depind de
+* alocarea secventiala si trebuie sa fie identice daca cele doua cai proceseaza acelasi lcListaIncasare.
+*
+* CONSUMA DATE REALE: fiecare pereche (tip, forma) scrie un document nou in VANZARI (client 463),
+* iar tipurile 2/3/4 aloca si un numar real de chitanta/bon fiscal/pos (serii 16/3/26). Niciun
+* rollback, nicio stergere - documentele raman in schema, de inspectat de Marius.
+*
+* Rulare: vfp9.exe -A -T "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_12b_s4b_proba_b_dupa.prg"
+* Log: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\probe_12b_s4b_proba_b_dupa.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET DELETED ON
+SET EXACT ON
+SET CENTURY ON
+SET DATE DMY
+SET DECIMALS TO 4
+SET NULLDISPLAY TO ''
+CLOSE DATABASES
+
+PUBLIC gcLog, gnPass, gnFail
+gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\probe_12b_s4b_proba_b_dupa.log"
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLog)
+gnPass = 0
+gnFail = 0
+
+ON ERROR DO S3bErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+ON SHUTDOWN QUIT
+
+TRY
+ LOCAL lcAppPathLocal, lcSql
+ lcAppPathLocal = "D:\ROA\ROAFACTURARE\"
+
+ *-- stub_verificare PRIMUL (SET PATH plain, nu ADDITIVE): test_init_env_auto_roafacturare.prg
+ *-- face el insusi SET PATH TO ... ADDITIVE mai jos, care ADAUGA dupa (nu inaintea) intrarilor
+ *-- deja existente - asta pastreaza stub_verificare cu prioritate fata de COMUN\FERESTRE, ca
+ *-- "Do Form verificare" (ofacturare.vc2:14404 / :20126) sa rezolve la stub, nu la formularul real
+ SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\achizitie_import\stub_verificare"
+
+ *-- mediul REAL, identic cu cel folosit de test_s3b_paritate_emitere.prg (deja dovedit ca
+ *-- instantiaza fara agatare frm_facturare_articole2 - orice reconstructie manuala a acestui
+ *-- mediu s-a dovedit incompleta si a agatat headless in interiorul Init-ului formularului nou,
+ *-- la constructia coloanei Gestiune din grd_factura (vezi raport)
+ DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+ IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO S3bLog WITH 'EROARE: conectare Oracle esuata'
+ DO S3bFinal
+ ENDIF
+ DO S3bLog WITH 'test_init_env_auto_roafacturare OK, gnHandle=' + TRANSFORM(gnHandle)
+
+ *-- fara asta, un lacat Oracle blocheaza rularea la infinit, invizibil in log
+ SQLSETPROP(gnHandle, "QueryTimeOut", 45)
+
+ *-- clase suplimentare, necesare pentru grd_factura (coloane cu combo pe cursor SQL)
+ SET PATH TO (lcAppPathLocal + "COMUN\utile\gridextras") ADDITIVE
+ SET CLASSLIB TO gridextras.vcx ADDITIVE
+ SET CLASSLIB TO _cb_base.vcx ADDITIVE
+ DO S3bLog WITH 'SET CLASSLIB suplimentar OK'
+
+ *-- mock amessagebox: la nume duplicat castiga fisierul de proceduri deschis cel mai recent
+ SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
+ DO S3bLog WITH 'mock_amessagebox OK'
+
+ *-- CdocGasesteIdVanzare: dovada de scriere pe jonctiunea serie_act + nract
+ SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\lib_comparatie_documente.prg" ADDITIVE
+
+ *-- initializare REALA a optiunilor de program (tehnica din test_s3b_paritate_emitere.prg) -
+ *-- creeaza dinamic globalele gnXxx/glXxx/gcXxx din tabela OPTIUNI; suprascrise imediat dupa
+ *-- cu valorile care bypaseaza dialogurile per-linie in mediul headless
+ IF !actualizeaza_optiuni_program()
+ DO S3bLog WITH 'EROARE: actualizeaza_optiuni_program()'
+ DO S3bFinal
+ ENDIF
+ gnScadereStoc = 0
+ gnModTotFact = 0
+ gnFactSeturi = 0
+ gnListareAvizBonFiscal = 0
+ gnid_part_casa = 0
+ *-- 167: singura sucursala cu plaje pentru chitanta/bon fiscal/pos in acest mediu (16/3/26);
+ *-- verificat READ-ONLY (probe_emitere_reala.prg) ca nu schimba Reccount(cursor_preturi)
+ gnIdSucursala = 167
+ lcSql = [begin pack_contafin.set_id_sucursala(?gnIdSucursala); end;]
+ goExecutor.oExecuta(lcSql)
+ DO S3bLog WITH 'actualizeaza_optiuni_program OK, gnScadereStoc=' + TRANSFORM(gnScadereStoc) + ' gnIdSucursala=' + TRANSFORM(gnIdSucursala)
+
+ PUBLIC gcMockUltimMesaj, gnMockUltimTip
+ gcMockUltimMesaj = ''
+ gnMockUltimTip = 0
+
+ *----- driver: conduce frm_alte_date (singurul modal ramas, doar pe calea veche) -----
+ PUBLIC goDriverAD, glDlgTratatAD, gnTipIncasareCerut, gnNrIncasareCapturat, gcClaseVazute
+ glDlgTratatAD = .F.
+ gnTipIncasareCerut = 1
+ gnNrIncasareCapturat = 0
+ gcClaseVazute = ';'
+ goDriverAD = CREATEOBJECT('driverAlteDateAD')
+ _SCREEN.AddObject('tmrDrvAD', 'Timer')
+ _SCREEN.tmrDrvAD.Interval = 200
+ BINDEVENT(_SCREEN.tmrDrvAD, 'Timer', goDriverAD, 'Executa')
+ _SCREEN.tmrDrvAD.Enabled = .T.
+ *-- _SCREEN ramane invizibil (default -A -T), ca in test_s3b_paritate_emitere.prg - un GETFILE()
+ *-- nativ (dialog "Open") aparut la o SET SCREEN VISIBLE = .T. a agatat rularea (vezi raport)
+ _SCREEN.Caption = 'S3b - emitere reala (paritate incasare vechi/nou)'
+ DO S3bLog WITH 'driver+timer pregatiti'
+
+ *-- pre-proba plajelor 3/16/26 - plasa de siguranta, evita blocaj invizibil daca lipsesc
+ DO S3bLog WITH 'pre-proba plaje: tip3=' + TRANSFORM(RanduriSerii(3)) + ' tip16=' + TRANSFORM(RanduriSerii(16)) + ;
+ ' tip26=' + TRANSFORM(RanduriSerii(26))
+
+ *-- stare INAINTE: ultimul NR_INCASAT emis pe fiecare tip de incasare, in TOATA schema
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== STARE INAINTE (MAX(NR_INCASAT) pe tip_incasat, toata schema) ====='
+ DO LogStareMaxIncasat
+
+ CREATE CURSOR crsRezultate (tip_incasare N(1), forma C(10), id_vanzare N(10), cod N(10), ;
+ serie_act C(10), id_fact N(10), nr_incasare_asteptat N(10), nr_incasat N(10), ;
+ tip_incasat N(10), suma_incasat N(18,2), serie_incasat C(10), total_cu_tva N(18,2))
+
+ LOCAL laNumeTip[4]
+ laNumeTip[1] = 'Fara incasare'
+ laNumeTip[2] = 'Chitanta'
+ laNumeTip[3] = 'Bon fiscal'
+ laNumeTip[4] = 'POS Card'
+
+ *-- FORMA NOUA: BLOCATA in aceasta sesiune (vezi docs\raport_s3b_emitere_reala.md) -
+ *-- frm_facturare_articole2 agata la CREATEOBJECT (Init -> grd_factura.cGestiune.cCboGestiune
+ *-- -> _cb_base.vc2 combosql.Init:589 -> RefreshData(0):826 -> SelectData():832 -> un dialog
+ *-- nativ "Open" real, needeterminat cauzal, indiferent de mediu/tip/vizibilitate _SCREEN).
+ *-- Ramane .F. neconditionat aici; DACA se rezolva blocajul, se schimba in .T. pentru ambele.
+ PUBLIC glIncercaFormaNoua
+ glIncercaFormaNoua = .F.
+
+ LOCAL lnTip, lnIdVz, lnIdVzDupa
+ lnIdVzDupa = 0
+ FOR lnTip = 1 TO 1
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== TIP ' + TRANSFORM(lnTip) + ' (' + laNumeTip[lnTip] + ') - FORMA VECHE (tnTip=22) ====='
+ lnIdVz = CreeazaDocumentIncasare(lnTip, .F.)
+ DO InregistreazaRezultat WITH lnTip, 'vechi', lnIdVz
+ IF lnIdVz > 0
+ DO LogLiniiDocument WITH lnIdVz
+ lnIdVzDupa = lnIdVz
+ ENDIF
+
+ IF glIncercaFormaNoua
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== TIP ' + TRANSFORM(lnTip) + ' (' + laNumeTip[lnTip] + ') - FORMA NOUA (tnTip=3) ====='
+ lnIdVz = CreeazaDocumentIncasare(lnTip, .T.)
+ DO InregistreazaRezultat WITH lnTip, 'nou', lnIdVz
+ ELSE
+ DO S3bLog WITH ' forma noua SARITA (blocata, vezi raport)'
+ ENDIF
+ ENDFOR
+
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== COMPARATIE VECHI / NOU, PE TIP ====='
+ DO ComparaRezultate
+
+ *-- 12b S4b partea 3: CompAct intre documentul "inainte" (1883, SSS/100135, pachetul vechi)
+ *-- si documentul "dupa" tocmai emis (pachetul nou, wip12_07) - aceeasi emitere, acelasi client.
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== CompAct: SSS/100135 (inainte) vs documentul nou (dupa) ====='
+ IF lnIdVzDupa > 0
+ LOCAL lcSerieDupa, lnNractDupa, lnQAct
+ lnQAct = goExecutor.oExecute([select serie_act, numar_act from vanzari where id_vanzare=] + ;
+ TRANSFORM(lnIdVzDupa), 'crsVzDupa')
+ IF lnQAct > 0 AND RECCOUNT('crsVzDupa') = 1
+ lcSerieDupa = ALLTRIM(crsVzDupa.serie_act)
+ lnNractDupa = crsVzDupa.numar_act
+ USE IN crsVzDupa
+ DO S3bLog WITH ' document dupa: serie_act=' + lcSerieDupa + ' numar_act=' + TRANSFORM(lnNractDupa) + ;
+ ' id_vanzare=' + TRANSFORM(lnIdVzDupa)
+ =CompAct('SSS', 100135, lcSerieDupa, lnNractDupa, '12b S4b proba B inainte/dupa')
+ ELSE
+ DO S3bLog WITH ' EROARE: nu s-a putut citi serie_act/numar_act pentru id_vanzare=' + TRANSFORM(lnIdVzDupa)
+ ENDIF
+ ELSE
+ DO S3bLog WITH ' EROARE: documentul dupa nu s-a scris (id_vanzare<=0), CompAct sarit'
+ ENDIF
+
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== STARE DUPA (MAX(NR_INCASAT) pe tip_incasat, toata schema) ====='
+ DO LogStareMaxIncasat
+
+ _SCREEN.tmrDrvAD.Enabled = .F.
+ DO S3bFinal
+
+CATCH TO loExc
+ DO S3bLog WITH 'CATCH TOP-LEVEL ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
+ DO S3bFinal
+ENDTRY
+
+QUIT
+
+*==================================================================================
+PROCEDURE S3bLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13)+CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE S3bErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO S3bLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
+ENDPROC
+
+PROCEDURE S3bFinal
+ DO S3bLog WITH CHR(13)+CHR(10) + 'TOTAL pass=' + TRANSFORM(gnPass) + ' fail=' + TRANSFORM(gnFail)
+ DO S3bLog WITH 'END ' + TTOC(DATETIME())
+ QUIT
+ENDPROC
+
+PROCEDURE Assert
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO S3bLog WITH 'PASS: ' + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO S3bLog WITH 'FAIL: ' + tcMsg
+ ENDIF
+ENDPROC
+
+*-- cate randuri de plaja intoarce verifica_cursor_serii pentru un tip de document, fara sa aloce
+FUNCTION RanduriSerii
+ LPARAMETERS tnIdTipDoc
+ LOCAL lnOk, lnRanduri, lcSql
+ LOCAL ARRAY laErr[1]
+ PRIVATE pnIdTipDoc, pnRezultat
+ pnIdTipDoc = tnIdTipDoc
+ pnRezultat = 0
+ lnRanduri = -1
+ lcSql = "{call " + gcS + ".pack_serii_numere.verifica_cursor_serii(?pnIdTipDoc,?gnIdUtil,?gnIdSucursala,?@pnRezultat)}"
+ lnOk = SQLEXEC(gnHandle, lcSql, "crsprobapl")
+ IF lnOk > 0
+ lnRanduri = RECCOUNT("crsprobapl")
+ USE IN (SELECT("crsprobapl"))
+ ELSE
+ AERROR(laErr)
+ DO S3bLog WITH 'pre-proba plaje tip ' + TRANSFORM(tnIdTipDoc) + ' ESEC: ' + TRANSFORM(laErr[2])
+ ENDIF
+ RETURN lnRanduri
+ENDFUNC
+
+*-- 12b S4b: liniile VANZARI_DETALII (id_pol) + randurile ACT (SCD/SCC) ale documentului, ca
+*-- instantaneu "inainte" pentru CompAct (partea 3) - client/document fixe, notate in stare.
+PROCEDURE LogLiniiDocument
+ LPARAMETERS tnIdVz
+ LOCAL lnQ
+ lnQ = goExecutor.oExecute([select id_articol, id_pol, cont from vanzari_detalii where sters=0 and id_vanzare=] + ;
+ TRANSFORM(tnIdVz) + [ order by id_articol], 'crsLiniiVz')
+ IF lnQ > 0
+ SELECT crsLiniiVz
+ SCAN
+ DO S3bLog WITH ' [proba B linie] id_articol=' + TRANSFORM(id_articol) + ' id_pol=' + TRANSFORM(NVL(id_pol,-1)) + ' cont=' + TRANSFORM(NVL(cont,''))
+ ENDSCAN
+ USE IN crsLiniiVz
+ ENDIF
+ lnQ = goExecutor.oExecute([select scd, scc, ascd, ascc, id_venchelt from act a ] + ;
+ [join vanzari v on v.serie_act=a.serie_act and v.numar_act=a.nract ] + ;
+ [where a.sters=0 and v.id_vanzare=] + TRANSFORM(tnIdVz) + [ order by scd, scc], 'crsActVz')
+ IF lnQ > 0
+ SELECT crsActVz
+ SCAN
+ DO S3bLog WITH ' [proba B ACT] SCD=' + TRANSFORM(NVL(scd,'')) + ' SCC=' + TRANSFORM(NVL(scc,'')) + ;
+ ' ASCD=' + TRANSFORM(NVL(ascd,'')) + ' ASCC=' + TRANSFORM(NVL(ascc,'')) + ' ID_VENCHELT=' + TRANSFORM(NVL(id_venchelt,-1))
+ ENDSCAN
+ USE IN crsActVz
+ ENDIF
+ENDPROC
+
+PROCEDURE LogStareMaxIncasat
+ LOCAL lnQ
+ lnQ = goExecutor.oExecute([select tip_incasat, max(nr_incasat) as maxnr, count(*) as nr ] + ;
+ [from vanzari where tip_incasat is not null group by tip_incasat order by tip_incasat], 'crsMaxInc')
+ IF lnQ > 0
+ SELECT crsMaxInc
+ SCAN
+ DO S3bLog WITH ' tip_incasat=' + TRANSFORM(tip_incasat) + ' max(nr_incasat)=' + TRANSFORM(maxnr) + ' nr_documente=' + TRANSFORM(nr)
+ ENDSCAN
+ USE IN crsMaxInc
+ ELSE
+ DO S3bLog WITH ' EROARE citire stare incasat: ' + goExecutor.oPrelucrareEroare()
+ ENDIF
+ENDPROC
+
+*-- citeste randul VANZARI scris pentru id_vanzare si-l adauga in crsRezultate
+PROCEDURE InregistreazaRezultat
+ LPARAMETERS tnTip, tcForma, tnIdVz
+ DO Assert WITH tnIdVz > 0, '[' + tcForma + ' tip=' + TRANSFORM(tnTip) + '] documentul exista in VANZARI (jonctiune serie_act+nract), e=' + TRANSFORM(tnIdVz)
+ IF tnIdVz <= 0
+ DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': documentul NU s-a scris (id_vanzare=0), fara rand in VANZARI'
+ INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare) VALUES (tnTip, tcForma, 0)
+ RETURN
+ ENDIF
+ LOCAL lnQ
+ lnQ = goExecutor.oExecute([select id_vanzare, cod, serie_act, nvl(id_fact,0) as id_fact, ] + ;
+ [nvl(nr_incasat,0) as nr_incasat, nvl(tip_incasat,0) as tip_incasat, nvl(suma_incasat,0) as suma_incasat, ] + ;
+ [nvl(serie_incasat,'') as serie_incasat, total_cu_tva from vanzari where id_vanzare = ] + TRANSFORM(tnIdVz), 'crsVz1')
+ IF lnQ <= 0 OR RECCOUNT('crsVz1') <> 1
+ DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': EROARE citire VANZARI id_vanzare=' + TRANSFORM(tnIdVz)
+ INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare) VALUES (tnTip, tcForma, tnIdVz)
+ RETURN
+ ENDIF
+ SELECT crsVz1
+ INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare, cod, serie_act, id_fact, ;
+ nr_incasare_asteptat, nr_incasat, tip_incasat, suma_incasat, serie_incasat, total_cu_tva) ;
+ VALUES (tnTip, tcForma, tnIdVz, crsVz1.cod, NVL(crsVz1.serie_act,''), crsVz1.id_fact, ;
+ gnNrIncasareCapturat, crsVz1.nr_incasat, crsVz1.tip_incasat, crsVz1.suma_incasat, NVL(crsVz1.serie_incasat,''), crsVz1.total_cu_tva)
+ DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': id_vanzare=' + TRANSFORM(tnIdVz) + ' cod=' + TRANSFORM(crsVz1.cod) + ;
+ ' serie_act=' + TRANSFORM(crsVz1.serie_act) + ' id_fact=' + TRANSFORM(crsVz1.id_fact) + ;
+ ' nr_incasat=' + TRANSFORM(crsVz1.nr_incasat) + ' (asteptat ' + TRANSFORM(gnNrIncasareCapturat) + ') tip_incasat=' + TRANSFORM(crsVz1.tip_incasat) + ;
+ ' suma_incasat=' + TRANSFORM(crsVz1.suma_incasat) + ' serie_incasat=[' + TRANSFORM(crsVz1.serie_incasat) + ']' + ;
+ ' total_cu_tva=' + TRANSFORM(crsVz1.total_cu_tva)
+ USE IN crsVz1
+
+ DO Assert WITH crsRezultate.nr_incasat = gnNrIncasareCapturat, ;
+ '[' + tcForma + ' tip=' + TRANSFORM(tnTip) + '] VANZARI.NR_INCASAT persistat (' + TRANSFORM(crsRezultate.nr_incasat) + ;
+ ') == poDate.nr_incasare capturat inainte de scriere (' + TRANSFORM(gnNrIncasareCapturat) + ')'
+ENDPROC
+
+PROCEDURE ComparaRezultate
+ LOCAL lnTip, lnRVechi, lnRNou
+ IF !glIncercaFormaNoua
+ DO S3bLog WITH ' forma noua sarita in aceasta rulare - fara comparatie vechi/nou, doar valorile persistate pe forma veche'
+ RETURN
+ ENDIF
+ FOR lnTip = 1 TO 4
+ SELECT crsRezultate
+ LOCATE FOR tip_incasare = lnTip AND forma == 'vechi'
+ IF !FOUND()
+ DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] rand vechi gasit in crsRezultate'
+ LOOP
+ ENDIF
+ lnRVechi = RECNO()
+ LOCATE FOR tip_incasare = lnTip AND forma == 'nou'
+ IF !FOUND()
+ DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] rand nou gasit in crsRezultate'
+ LOOP
+ ENDIF
+ lnRNou = RECNO()
+
+ LOCAL lnIdVechi, lnIdNou, lnTipIncVechi, lnTipIncNou, lnSumaVechi, lnSumaNou, lcSerieVechi, lcSerieNou
+ GO lnRVechi IN crsRezultate
+ lnIdVechi = crsRezultate.id_vanzare
+ lnTipIncVechi = crsRezultate.tip_incasat
+ lnSumaVechi = crsRezultate.suma_incasat
+ lcSerieVechi = crsRezultate.serie_incasat
+ GO lnRNou IN crsRezultate
+ lnIdNou = crsRezultate.id_vanzare
+ lnTipIncNou = crsRezultate.tip_incasat
+ lnSumaNou = crsRezultate.suma_incasat
+ lcSerieNou = crsRezultate.serie_incasat
+
+ IF lnIdVechi <= 0 OR lnIdNou <= 0
+ DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] ambele documente s-au scris (vechi id_vanzare=' + ;
+ TRANSFORM(lnIdVechi) + ' nou id_vanzare=' + TRANSFORM(lnIdNou) + ')'
+ LOOP
+ ENDIF
+
+ DO Assert WITH lnTipIncVechi = lnTipIncNou, '[tip=' + TRANSFORM(lnTip) + '] VANZARI.TIP_INCASAT identic (vechi=' + ;
+ TRANSFORM(lnTipIncVechi) + ' nou=' + TRANSFORM(lnTipIncNou) + ')'
+ DO Assert WITH ABS(lnSumaVechi - lnSumaNou) < 0.005, '[tip=' + TRANSFORM(lnTip) + '] VANZARI.SUMA_INCASAT identica (vechi=' + ;
+ TRANSFORM(lnSumaVechi) + ' nou=' + TRANSFORM(lnSumaNou) + ')'
+ DO Assert WITH ALLTRIM(lcSerieVechi) == ALLTRIM(lcSerieNou), '[tip=' + TRANSFORM(lnTip) + '] VANZARI.SERIE_INCASAT identica (vechi=[' + ;
+ ALLTRIM(lcSerieVechi) + '] nou=[' + ALLTRIM(lcSerieNou) + '])'
+ ENDFOR
+ENDPROC
+
+*==================================================================================
+* CreeazaDocumentIncasare: emite un document REAL prin fluxul de productie (tnTip=22, cursor_preturi,
+* client RAJA id_part=463), aplicand tipul de incasare cerut pe formularul indicat. Intoarce
+* poDate.nid_vanzare (>0 succes) sau 0 (esec, detaliat in log). gnNrIncasareCapturat e umplut cu
+* poDate.nr_incasare chiar inainte de do_termin() - marimea persistata se verifica fata de asta.
+FUNCTION CreeazaDocumentIncasare
+ LPARAMETERS tnTipIncasare, tlFormNou
+
+ PRIVATE poDate, poGeneratorNumere, poDateGestiuneDest
+ LOCAL lnIdSet, lcSqlCursor, lcCursor, lnSucces, lnIdVanzareRezultat, tnTip, tnIdClient, tnIdDelegat
+ LOCAL lcSerieAlocata, lnNractAlocat
+ lnIdVanzareRezultat = 0
+ lcSerieAlocata = ''
+ lnNractAlocat = 0
+ gnNrIncasareCapturat = 0
+ *-- FORMA VECHE: tnTip=22 (AVIZ din lista de preturi) - calea PROVENITA, curata, fara efecte
+ *-- secundare (nu intra pe ramura "comanda" din do_scrie_factura). opt_incasat traieste pe
+ *-- frm_alte_date (clasa separata), deci nu are restrictia Between(poDate.tip,1,4).
+ *-- FORMA NOUA: are nevoie de tnTip Between(1,4) ca opt_incasat sa existe inline pe formular
+ *-- (ofacturare.vc2:21066) - singurele din acel interval cu date reale in cursor_preturi sunt
+ *-- 3/4 (probe_emitere_reala.prg), dar tnTip=3 declanseaza un MESSAGEBOX_FORM real necunoscut
+ *-- mock-ului ("Doriti sa se inchida comanda?") si formularul nou insusi agata la CREATEOBJECT
+ *-- pe coloana Gestiune a grd_factura (vezi raport) - BLOCAT, nerezolvat in aceasta sesiune.
+ *-- 12b S4b proba B: incercari tnTip=1 (client 332) si tnTip=2 (client 463) - Reccount=0 in acest
+ *-- mediu (poDate.id_gestiune_init implicit NULL); revenire la tnTip=22/client 463, singura
+ *-- combinatie confirmata ca intoarce articole headless (probe_emitere_reala.prg) - a dat
+ *-- documentul real id_vanzare=1883, aproape integral pe politica de stoc (41), nu politica reala
+ *-- 34 tintita initial - limitare consemnata in stare, nu blocanta (proba A caz7 acopera regresia
+ *-- pe politica reala 34 direct in PL/SQL)
+ tnTip = IIF(tlFormNou, 3, 22)
+ tnIdClient = 463
+ tnIdDelegat = 256
+
+ update_jtva_coloane([JV], [jtva_coloane_temp])
+ update_saft_taxtable()
+
+ lnIdSet = 25000 + tnTip - 1 + gnScadereStoc * 10
+ poDate = CREATEOBJECT("oDateFactura", lnIdSet, tnTip)
+ poGeneratorNumere = CREATEOBJECT("oGeneratorNumere")
+ poDateGestiuneDest = CREATEOBJECT("oDateGestiune")
+
+ IF !tlFormNou
+ poDate.nIdTipDoc = 6 && AVIZ - plaja globala, dovedit (id_vanzare 1061/1062/1063)
+ ENDIF
+
+ gnIdUtil = 8
+ poGeneratorNumere.ResetNumere()
+ poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(poDate.nIdTipDoc)
+
+ poDate.id_client = tnIdClient
+ poDate.id_delegat = tnIdDelegat
+ poDate.zi_curs = {^2026-08-10}
+
+ IF poDate.rezultat_serii = 3
+ poDate.serie_act = poGeneratorNumere.getSerieCursor(poDate.nIdTipDoc)
+ ENDIF
+ poDate.nract = poGeneratorNumere.aloca_numar(poDate.nIdTipDoc, NULL)
+ poGeneratorNumere.verifica_numar(poDate.nIdTipDoc, poDate.nract)
+ gnIdUtil = -3
+ lcSerieAlocata = ALLTRIM(TRANSFORM(NVL(poDate.serie_act, [])))
+ lnNractAlocat = poDate.nract
+ DO S3bLog WITH ' poDate.nract=' + TRANSFORM(poDate.nract) + ' serie_act=[' + TRANSFORM(NVL(poDate.serie_act,[])) + ']'
+
+ IF poDate.tva_incasare = 0
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_ex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ ELSE
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_neex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ ENDIF
+
+ lcSqlCursor = [{call ] + gcS + [.pack_facturare.cursor_preturi(?poDate.zi_curs,?poDate.tip,?poDate.id_valuta,] + ;
+ [?poDate.id_gestiune_init,?gnLuna,?gnAn,?gnIdUtil,?gnIdSucursala)}]
+
+ lcCursor = [crsarticole]
+ lnSucces = goExecutor.oExecute(lcSqlCursor, lcCursor)
+ IF lnSucces < 0
+ DO S3bLog WITH ' EROARE cursor articole: ' + goExecutor.oPrelucrareEroare()
+ poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc)
+ DO S3bCurataJtva
+ RELEASE poDate, poGeneratorNumere, poDateGestiuneDest
+ RETURN 0
+ ENDIF
+
+ IF RECCOUNT(lcCursor) = 0
+ DO S3bLog WITH ' Nu exista articole (Reccount=0) - abandon document'
+ poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc)
+ DO S3bCurataJtva
+ RELEASE poDate, poGeneratorNumere, poDateGestiuneDest
+ RETURN 0
+ ENDIF
+ DO S3bLog WITH ' crsarticole Reccount=' + TRANSFORM(RECCOUNT(lcCursor))
+
+ *-- Lista de preturi a articolului e in EURO (tip_valuta=1), iar do_scrie_articole
+ *-- trimite pe ramura aceea vpretftva, derivat din pret_val - fortand doar pret,
+ *-- documentul iesea cu VANZARI_DETALII.PRET=0. Se forteaza perechea, coerent cu cursul.
+ SELECT (lcCursor)
+ REPLACE ALL cantitate WITH 1, ;
+ pret_val WITH IIF(tip_valuta = 1, 100, 0), ;
+ pret WITH IIF(tip_valuta = 1, ROUND(100 * IIF(NVL(curs, 0) = 0, 1, curs) / IIF(NVL(multiplicator, 0) = 0, 1, multiplicator), gnPPretV), 100)
+ =TABLEUPDATE(.T., .T., lcCursor)
+ GO TOP
+
+ creeaza_facturacrs([crsfactura])
+
+ IF poDate.in_valuta = 1
+ SELECT DISTINCT Curs, nume_val, id_valuta, multiplicator FROM (lcCursor) WITH (Buffering = .T.) WHERE tip_valuta = 1 ORDER BY nume_val INTO CURSOR crscursuri
+ SELECT crscursuri
+ poDate.Curs = Curs
+ poDate.multiplicator = multiplicator
+ ELSE
+ citeste_cursuri_zi(poDate.zi_curs)
+ IF RECCOUNT('crscursuri') = 0
+ USE IN crscursuri
+ ENDIF
+ ENDIF
+
+ IF TYPE(lcCursor + '.nume_lista_preturi') <> 'U'
+ CREATE CURSOR crspolitici (id_pol N(20), nume_lista_preturi c(100))
+ SELECT crspolitici
+ INSERT INTO crspolitici(id_pol, nume_lista_preturi) VALUES (-9999, '')
+ INSERT INTO crspolitici(id_pol, nume_lista_preturi) ;
+ SELECT DISTINCT id_pol, nume_lista_preturi FROM (lcCursor) ORDER BY nume_lista_preturi
+ ENDIF
+
+ *-- formularul, modeless (apel direct de metode) - vechi sau unificat, dupa tlFormNou
+ PUBLIC goFrmS3b
+ IF tlFormNou
+ goFrmS3b = CREATEOBJECT('frm_facturare_articole2')
+ ELSE
+ goFrmS3b = CREATEOBJECT('frm_facturare_articole')
+ ENDIF
+ DO S3bLog WITH ' CREATEOBJECT OK, VARTYPE=' + VARTYPE(goFrmS3b)
+ goFrmS3b.WindowType = 0
+ DO S3bLog WITH ' WindowType=0 OK'
+ goFrmS3b.Show()
+ DO S3bLog WITH ' Show() OK'
+ DOEVENTS FORCE
+ DO S3bLog WITH ' formular afisat modeless (' + IIF(tlFormNou, 'NOU frm_facturare_articole2', 'VECHI frm_facturare_articole') + ')'
+
+ goFrmS3b.do_adauga_tot()
+ DOEVENTS FORCE
+ DO S3bLog WITH ' do_adauga_tot() -> Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
+
+ goFrmS3b.do_calculeaza_totaluri()
+ DOEVENTS FORCE
+
+ *-- CONT_VENIT asteptat, derivat exact ca in do_scrie_articole (ofacturare.vc2:14279), citit
+ *-- direct din randul crsfactura pe care do_scrie_articole il va scana
+ LOCAL lcExpContVenit, lnExpIdPol, lnExpIdArticol, lcExpCont, loExecutorReal
+ SELECT crsfactura
+ GO TOP
+ lnExpIdPol = crsfactura.id_pol
+ lnExpIdArticol = crsfactura.id_articol
+ lcExpCont = crsfactura.Cont
+ lcExpContVenit = IIF(EMPTY(NVL(lnExpIdPol, 0)), deriva_cont_venit_fara_pol(lnExpIdArticol, lcExpCont), '')
+
+ *-- spion pe goExecutor (tehnica SpyS13, probe_s13_toomanycolumns.prg): captureaza SQL-ul real
+ *-- trimis de do_scrie_articole, fara sa-i schimbe comportamentul (DODEFAULT pe PCOUNT)
+ loExecutorReal = goExecutor
+ goExecutor = CREATEOBJECT('SpyContVenit')
+ goExecutor.nHandle = gnHandle
+
+ LOCAL lnScris
+ IF tlFormNou
+ *-- opt_incasat e inline pe formular - fara al doilea modal
+ goFrmS3b.seteaza_mod_incasare(tnTipIncasare)
+ gnNrIncasareCapturat = poDate.nr_incasare
+ DO S3bLog WITH ' opt_incasat.Value=' + TRANSFORM(tnTipIncasare) + ' -> poDate.nr_incasare=' + TRANSFORM(gnNrIncasareCapturat) + ;
+ ' incasat=' + TRANSFORM(poDate.incasat) + ' incasatCARD=' + TRANSFORM(poDate.incasatCARD)
+ lnScris = goFrmS3b.do_termin()
+ ELSE
+ *-- calea veche: al doilea modal (frm_alte_date) e condus de goDriverAD/tmrDrvAD
+ glDlgTratatAD = .F.
+ gnTipIncasareCerut = tnTipIncasare
+ lnScris = goFrmS3b.do_termin()
+ LOCAL lnWait
+ lnWait = 0
+ DO WHILE !glDlgTratatAD AND lnWait < 10
+ DOEVENTS FORCE
+ lnWait = lnWait + 1
+ ENDDO
+ ENDIF
+ DO S3bLog WITH ' do_termin() -> ' + TRANSFORM(lnScris) + ' poDate.nid_vanzare=' + TRANSFORM(NVL(poDate.nid_vanzare,0))
+
+ *-- restaureaza goExecutor real si verifica CONT_VENIT trimis de do_scrie_articole
+ LOCAL lcActualContVenit, lcEticheta
+ lcEticheta = '[' + IIF(tlFormNou,'nou','vechi') + ' tip=' + TRANSFORM(tnTipIncasare) + ']'
+ DO Assert WITH goExecutor.cLastArtCall # '', ;
+ lcEticheta + ' do_scrie_articole a trimis adauga_articol_factura (spion pe goExecutor)'
+ IF goExecutor.cLastArtCall # ''
+ lcActualContVenit = ExtrageContVenit(goExecutor.cLastArtCall)
+ DO Assert WITH lcActualContVenit == lcExpContVenit, ;
+ lcEticheta + ' CONT_VENIT trimis de do_scrie_articole = [' + lcExpContVenit + '], obtinut [' + lcActualContVenit + ']'
+ ENDIF
+ goExecutor = loExecutorReal
+
+ *-- do_termin() intoarce mereu .T. (_frm_base.vc2:363, DoDefault fara RETURN) si nid_vanzare
+ *-- ramane santinela la esec: singura dovada e randul din VANZARI, pe serie_act + nract.
+ lnIdVanzareRezultat = CdocGasesteIdVanzare(lcSerieAlocata, lnNractAlocat)
+ IF lnIdVanzareRezultat < 0
+ lnIdVanzareRezultat = 0
+ ENDIF
+ DO S3bLog WITH ' verificare in VANZARI pe ' + lcSerieAlocata + ' ' + TRANSFORM(lnNractAlocat) + ;
+ ' -> id_vanzare=' + TRANSFORM(lnIdVanzareRezultat)
+
+ IF TYPE('goFrmS3b') = 'O' AND !ISNULL(goFrmS3b)
+ goFrmS3b.Release()
+ ENDIF
+ goFrmS3b = NULL
+
+ IF USED('crspolitici')
+ USE IN crspolitici
+ ENDIF
+ IF USED('crscursuri')
+ USE IN crscursuri
+ ENDIF
+ IF USED('crsfactura')
+ USE IN crsfactura
+ ENDIF
+ IF USED('crsarticole')
+ USE IN crsarticole
+ ENDIF
+ IF USED('jtva_coloane')
+ USE IN jtva_coloane
+ ENDIF
+ IF USED('jtva_coloane_temp')
+ USE IN jtva_coloane_temp
+ ENDIF
+
+ RELEASE poDate, poGeneratorNumere, poDateGestiuneDest
+ RETURN lnIdVanzareRezultat
+ENDFUNC
+
+PROCEDURE S3bCurataJtva
+ IF USED('jtva_coloane')
+ USE IN jtva_coloane
+ ENDIF
+ IF USED('jtva_coloane_temp')
+ USE IN jtva_coloane_temp
+ ENDIF
+ENDPROC
+
+*-- extrage parametrul 29 (CONT_VENIT) dintr-un apel capturat pack_facturare.adauga_articol_factura(...);
+*-- pozitia 28 e mereu literalul NULL, deci pos29 e tot ce urmeaza dupa ultima virgula dinaintea "); end;"
+FUNCTION ExtrageContVenit
+ LPARAMETERS tcSql
+ LOCAL lnEnd, lcParams, lnComma, lcPos29
+ lnEnd = AT('); end;', tcSql)
+ IF lnEnd = 0
+ RETURN ''
+ ENDIF
+ lcParams = LEFT(tcSql, lnEnd - 1)
+ lnComma = RAT(',', lcParams)
+ IF lnComma = 0
+ RETURN ''
+ ENDIF
+ lcPos29 = SUBSTR(lcParams, lnComma + 1)
+ IF UPPER(lcPos29) == 'NULL'
+ RETURN ''
+ ENDIF
+ RETURN STRTRAN(lcPos29, "'", '')
+ENDFUNC
+
+*==================================================================================
+*-- SpyContVenit: subclasa a lui oexecutor (tehnica SpyS13 din probe_s13_toomanycolumns.prg) -
+*-- logheaza in cLastArtCall statementul adauga_articol_factura, apoi executa normal prin
+*-- DODEFAULT pe PCOUNT (fara sa schimbe comportamentul real)
+DEFINE CLASS SpyContVenit AS oexecutor
+ cLastArtCall = ''
+
+ PROCEDURE oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect)
+ LOCAL lnPc, lcS, lnRet
+ lnPc = PCOUNT()
+ lcS = IIF(VARTYPE(m.tcSql) = 'C', m.tcSql, '')
+ IF 'adauga_articol_factura(' $ lcS
+ THIS.cLastArtCall = lcS
+ ENDIF
+ TRY
+ DO CASE
+ CASE lnPc <= 1
+ lnRet = DODEFAULT(m.tcSql)
+ CASE lnPc = 2
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor)
+ CASE lnPc = 3
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress)
+ CASE lnPc = 4
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress)
+ CASE lnPc = 5
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle)
+ CASE lnPc = 6
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError)
+ CASE lnPc = 7
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError)
+ OTHERWISE
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError, m.tlReconnect)
+ ENDCASE
+ CATCH TO loExSpy
+ lnRet = -1
+ THIS.cEroare = 'SpyContVenit: ' + TRANSFORM(loExSpy.Message)
+ ENDTRY
+ RETURN lnRet
+ ENDPROC
+ENDDEFINE
+
+*==================================================================================
+*-- driverAlteDateAD: cauta FRM_ALTE_DATE prin _SCREEN.Forms si ii seteaza opt_incasat.Value la
+* gnTipIncasareCerut INAINTE de a-i chema .do_termin() - acelasi mecanism ca driverAlteDate8 din
+* creeaza_documente_s8.prg, cu un singur adaos (selectia tipului de incasare).
+DEFINE CLASS driverAlteDateAD AS Custom
+ PROCEDURE Executa
+ LOCAL lnI, loForm, llGasit, loMsgForm
+ llGasit = .F.
+ loMsgForm = NULL
+ FOR lnI = 1 TO _SCREEN.FormCount
+ LOCAL lcClasa
+ lcClasa = UPPER(_SCREEN.Forms(lnI).Class)
+ IF lcClasa == 'FRM_ALTE_DATE'
+ loForm = _SCREEN.Forms(lnI)
+ llGasit = .T.
+ ENDIF
+ IF 'MESSAGEBOX_FORM' $ lcClasa
+ loMsgForm = _SCREEN.Forms(lnI)
+ ENDIF
+ IF !(lcClasa $ gcClaseVazute)
+ gcClaseVazute = gcClaseVazute + lcClasa + ';'
+ DO S3bLog WITH ' [diag timer] forma noua vazuta: ' + lcClasa + ' Caption=[' + TRANSFORM(_SCREEN.Forms(lnI).Caption) + ']'
+ ENDIF
+ ENDFOR
+ *-- confirmare reala neacoperita de mock_amessagebox (forma modala messagebox_form) -
+ *-- apasa automat cmdYes/cmdOk, ca in productie la raspuns implicit "Da"
+ IF !ISNULL(loMsgForm)
+ TRY
+ DO CASE
+ CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdYes', 5)
+ DO S3bLog WITH ' [diag timer] messagebox_form: apas cmgBotones.cmdYes'
+ loMsgForm.cmgBotones.cmdYes.Click()
+ CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdOk', 5)
+ DO S3bLog WITH ' [diag timer] messagebox_form: apas cmgBotones.cmdOk'
+ loMsgForm.cmgBotones.cmdOk.Click()
+ ENDCASE
+ CATCH TO loExcMsg
+ DO S3bLog WITH ' [diag timer] messagebox_form: CATCH ' + TRANSFORM(loExcMsg.ErrorNo) + ' ' + loExcMsg.Message
+ ENDTRY
+ ENDIF
+ IF glDlgTratatAD OR !llGasit
+ RETURN
+ ENDIF
+ LOCAL loAC
+ loAC = loForm.ActiveControl
+ TRY
+ loForm.opt_incasat.Value = gnTipIncasareCerut
+ gnNrIncasareCapturat = poDate.nr_incasare
+ DO S3bLog WITH ' driverAlteDateAD: opt_incasat.Value=' + TRANSFORM(gnTipIncasareCerut) + ;
+ ' -> poDate.nr_incasare=' + TRANSFORM(gnNrIncasareCapturat) + ' incasat=' + TRANSFORM(poDate.incasat) + ;
+ ' incasatCARD=' + TRANSFORM(poDate.incasatCARD)
+ loForm.do_termin()
+ glDlgTratatAD = .T.
+ CATCH TO loExcDrv
+ DO S3bLog WITH ' driverAlteDateAD: CATCH ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ' Message=' + loExcDrv.Message + ;
+ ' Procedure=' + loExcDrv.Procedure + ' LineNo=' + TRANSFORM(loExcDrv.LineNo)
+ glDlgTratatAD = .T.
+ ENDTRY
+ ENDPROC
+ENDDEFINE
diff --git a/utile/Teste/facturare_unificat/probe_12b_s4b_proba_b_inainte.prg b/utile/Teste/facturare_unificat/probe_12b_s4b_proba_b_inainte.prg
new file mode 100644
index 0000000..e34ea4c
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s4b_proba_b_inainte.prg
@@ -0,0 +1,740 @@
+* probe_12b_s4b_proba_b_inainte.prg
+* Plan 12b, S4b partea 2 - Proba B "INAINTE": copie a test_s3b_emitere_reala.prg (mecanica
+* nemodificata, deja dovedita), restransa la o singura emitere reala (tip_incasare=1, "Fara
+* incasare", forma veche) - client RAJA (id_part=463), plaja utilizatorului 8. Se ruleaza PE
+* PACHETUL DE DINAINTE de D10 (S4a), ca sa capteze un instantaneu real al SCD/SCC pe politica
+* reala inainte de schimbare; "dupa" (aceeasi client, mecanism) il face partea 3, cu CompAct.
+*
+* Criteriul 1 de "gata" al S3b, PROBA REALA (nu structurala): emite documente REALE in Oracle
+* (MARIUSM_AUTO@ROA_CENTRAL, aprobat explicit de Marius) prin fluxul de emitere efectiv, pe
+* fiecare din cele patru tipuri de incasare (1=Fara incasare, 2=Chitanta, 3=Bon fiscal, 4=POS/Card),
+* o data pe formularul vechi (frm_facturare_articole) si o data pe cel unificat
+* (frm_facturare_articole2), si compara randurile persistate in VANZARI dupa commit.
+*
+* Sursa documentului e cursor_preturi (lista de preturi, client RAJA id_part=463) cu tnTip=22 -
+* singura combinatie confirmata prin proba read-only (probe_emitere_reala.prg) ca intoarce articole
+* in acest mediu; tnTip=5 (FACTURA direct) da Reccount=0. Numerotarea/serie a documentului ramane
+* cea naturala pentru tnTip=22 (AVIZ, nIdTipDoc=6, plaja globala) - neatinsa, nu conteaza pentru
+* criteriul de paritate a INCASARII, care e independent de seria documentului.
+*
+* Mecanica bazata pe COMUN\utile\Teste\editare_factura\creeaza_documente_s8.prg (mediu Oracle real
+* + clase de productie, dovedit ca emite documente reale pentru tnTip=22): dialogul modal de antet
+* e inlocuit cu setare directa poDate (ca acolo), iar "Do Form verificare" (ofacturare.vc2:14404 /
+* :20126) e ocolit cu acelasi stub versionat COMUN\utile\Teste\achizitie_import\stub_verificare\
+* (SET PATH cu el primul).
+*
+* Diferenta fata de creeaza_documente_s8.prg: al doilea modal (frm_alte_date, doar pe calea veche)
+* NU e doar "confirmat" - un driver pe Timer ii seteaza opt_incasat.Value la tipul cerut INAINTE
+* sa-i cheme do_termin(), exact tehnica validata structural in test_s3b_paritate_emitere.prg (setarea
+* de .Value declanseaza opt_incasat.ProgrammaticChange -> actualizeaza_tipincasare(), cod real).
+* Pe calea noua nu exista al doilea modal (opt_incasat e inline pe formular): se seteaza direct pe
+* goFrm inainte de goFrm.do_termin().
+*
+* De ce NU se compara nr_incasare/NR_INCASAT intre vechi si nou (asa cum a facut suita structurala):
+* acolo numerele erau dezalocate dupa fiecare tip, deci acelasi numar fizic se realoca in faza 2.
+* Aici documentele raman scrise (nu se dezaloca nimic dupa un commit reusit), deci vechi si nou aloca
+* NUMERE DIFERITE, consecutive, din aceeasi plaja - egalitatea lor ar fi o eroare, nu o dovada.
+* Paritatea reala verificata e (a) consistenta interna - VANZARI.NR_INCASAT persistat == poDate.nr_incasare
+* capturat chiar inainte de scriere, pe fiecare document in parte, si (b) egalitatea intre vechi/nou a
+* CODULUI de tip (VANZARI.TIP_INCASAT) si a SUMEI (VANZARI.SUMA_INCASAT) - marimi care nu depind de
+* alocarea secventiala si trebuie sa fie identice daca cele doua cai proceseaza acelasi lcListaIncasare.
+*
+* CONSUMA DATE REALE: fiecare pereche (tip, forma) scrie un document nou in VANZARI (client 463),
+* iar tipurile 2/3/4 aloca si un numar real de chitanta/bon fiscal/pos (serii 16/3/26). Niciun
+* rollback, nicio stergere - documentele raman in schema, de inspectat de Marius.
+*
+* Rulare: vfp9.exe -A -T "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\test_s3b_emitere_reala.prg"
+* Log: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\test_s3b_emitere_reala.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET DELETED ON
+SET EXACT ON
+SET CENTURY ON
+SET DATE DMY
+SET DECIMALS TO 4
+SET NULLDISPLAY TO ''
+CLOSE DATABASES
+
+PUBLIC gcLog, gnPass, gnFail
+gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\probe_12b_s4b_proba_b_inainte.log"
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcLog)
+gnPass = 0
+gnFail = 0
+
+ON ERROR DO S3bErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+ON SHUTDOWN QUIT
+
+TRY
+ LOCAL lcAppPathLocal, lcSql
+ lcAppPathLocal = "D:\ROA\ROAFACTURARE\"
+
+ *-- stub_verificare PRIMUL (SET PATH plain, nu ADDITIVE): test_init_env_auto_roafacturare.prg
+ *-- face el insusi SET PATH TO ... ADDITIVE mai jos, care ADAUGA dupa (nu inaintea) intrarilor
+ *-- deja existente - asta pastreaza stub_verificare cu prioritate fata de COMUN\FERESTRE, ca
+ *-- "Do Form verificare" (ofacturare.vc2:14404 / :20126) sa rezolve la stub, nu la formularul real
+ SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\achizitie_import\stub_verificare"
+
+ *-- mediul REAL, identic cu cel folosit de test_s3b_paritate_emitere.prg (deja dovedit ca
+ *-- instantiaza fara agatare frm_facturare_articole2 - orice reconstructie manuala a acestui
+ *-- mediu s-a dovedit incompleta si a agatat headless in interiorul Init-ului formularului nou,
+ *-- la constructia coloanei Gestiune din grd_factura (vezi raport)
+ DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+ IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO S3bLog WITH 'EROARE: conectare Oracle esuata'
+ DO S3bFinal
+ ENDIF
+ DO S3bLog WITH 'test_init_env_auto_roafacturare OK, gnHandle=' + TRANSFORM(gnHandle)
+
+ *-- fara asta, un lacat Oracle blocheaza rularea la infinit, invizibil in log
+ SQLSETPROP(gnHandle, "QueryTimeOut", 45)
+
+ *-- clase suplimentare, necesare pentru grd_factura (coloane cu combo pe cursor SQL)
+ SET PATH TO (lcAppPathLocal + "COMUN\utile\gridextras") ADDITIVE
+ SET CLASSLIB TO gridextras.vcx ADDITIVE
+ SET CLASSLIB TO _cb_base.vcx ADDITIVE
+ DO S3bLog WITH 'SET CLASSLIB suplimentar OK'
+
+ *-- mock amessagebox: la nume duplicat castiga fisierul de proceduri deschis cel mai recent
+ SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
+ DO S3bLog WITH 'mock_amessagebox OK'
+
+ *-- CdocGasesteIdVanzare: dovada de scriere pe jonctiunea serie_act + nract
+ SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\lib_comparatie_documente.prg" ADDITIVE
+
+ *-- initializare REALA a optiunilor de program (tehnica din test_s3b_paritate_emitere.prg) -
+ *-- creeaza dinamic globalele gnXxx/glXxx/gcXxx din tabela OPTIUNI; suprascrise imediat dupa
+ *-- cu valorile care bypaseaza dialogurile per-linie in mediul headless
+ IF !actualizeaza_optiuni_program()
+ DO S3bLog WITH 'EROARE: actualizeaza_optiuni_program()'
+ DO S3bFinal
+ ENDIF
+ gnScadereStoc = 0
+ gnModTotFact = 0
+ gnFactSeturi = 0
+ gnListareAvizBonFiscal = 0
+ gnid_part_casa = 0
+ *-- 167: singura sucursala cu plaje pentru chitanta/bon fiscal/pos in acest mediu (16/3/26);
+ *-- verificat READ-ONLY (probe_emitere_reala.prg) ca nu schimba Reccount(cursor_preturi)
+ gnIdSucursala = 167
+ lcSql = [begin pack_contafin.set_id_sucursala(?gnIdSucursala); end;]
+ goExecutor.oExecuta(lcSql)
+ DO S3bLog WITH 'actualizeaza_optiuni_program OK, gnScadereStoc=' + TRANSFORM(gnScadereStoc) + ' gnIdSucursala=' + TRANSFORM(gnIdSucursala)
+
+ PUBLIC gcMockUltimMesaj, gnMockUltimTip
+ gcMockUltimMesaj = ''
+ gnMockUltimTip = 0
+
+ *----- driver: conduce frm_alte_date (singurul modal ramas, doar pe calea veche) -----
+ PUBLIC goDriverAD, glDlgTratatAD, gnTipIncasareCerut, gnNrIncasareCapturat, gcClaseVazute
+ glDlgTratatAD = .F.
+ gnTipIncasareCerut = 1
+ gnNrIncasareCapturat = 0
+ gcClaseVazute = ';'
+ goDriverAD = CREATEOBJECT('driverAlteDateAD')
+ _SCREEN.AddObject('tmrDrvAD', 'Timer')
+ _SCREEN.tmrDrvAD.Interval = 200
+ BINDEVENT(_SCREEN.tmrDrvAD, 'Timer', goDriverAD, 'Executa')
+ _SCREEN.tmrDrvAD.Enabled = .T.
+ *-- _SCREEN ramane invizibil (default -A -T), ca in test_s3b_paritate_emitere.prg - un GETFILE()
+ *-- nativ (dialog "Open") aparut la o SET SCREEN VISIBLE = .T. a agatat rularea (vezi raport)
+ _SCREEN.Caption = 'S3b - emitere reala (paritate incasare vechi/nou)'
+ DO S3bLog WITH 'driver+timer pregatiti'
+
+ *-- pre-proba plajelor 3/16/26 - plasa de siguranta, evita blocaj invizibil daca lipsesc
+ DO S3bLog WITH 'pre-proba plaje: tip3=' + TRANSFORM(RanduriSerii(3)) + ' tip16=' + TRANSFORM(RanduriSerii(16)) + ;
+ ' tip26=' + TRANSFORM(RanduriSerii(26))
+
+ *-- stare INAINTE: ultimul NR_INCASAT emis pe fiecare tip de incasare, in TOATA schema
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== STARE INAINTE (MAX(NR_INCASAT) pe tip_incasat, toata schema) ====='
+ DO LogStareMaxIncasat
+
+ CREATE CURSOR crsRezultate (tip_incasare N(1), forma C(10), id_vanzare N(10), cod N(10), ;
+ serie_act C(10), id_fact N(10), nr_incasare_asteptat N(10), nr_incasat N(10), ;
+ tip_incasat N(10), suma_incasat N(18,2), serie_incasat C(10), total_cu_tva N(18,2))
+
+ LOCAL laNumeTip[4]
+ laNumeTip[1] = 'Fara incasare'
+ laNumeTip[2] = 'Chitanta'
+ laNumeTip[3] = 'Bon fiscal'
+ laNumeTip[4] = 'POS Card'
+
+ *-- FORMA NOUA: BLOCATA in aceasta sesiune (vezi docs\raport_s3b_emitere_reala.md) -
+ *-- frm_facturare_articole2 agata la CREATEOBJECT (Init -> grd_factura.cGestiune.cCboGestiune
+ *-- -> _cb_base.vc2 combosql.Init:589 -> RefreshData(0):826 -> SelectData():832 -> un dialog
+ *-- nativ "Open" real, needeterminat cauzal, indiferent de mediu/tip/vizibilitate _SCREEN).
+ *-- Ramane .F. neconditionat aici; DACA se rezolva blocajul, se schimba in .T. pentru ambele.
+ PUBLIC glIncercaFormaNoua
+ glIncercaFormaNoua = .F.
+
+ LOCAL lnTip, lnIdVz
+ FOR lnTip = 1 TO 1
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== TIP ' + TRANSFORM(lnTip) + ' (' + laNumeTip[lnTip] + ') - FORMA VECHE (tnTip=22) ====='
+ lnIdVz = CreeazaDocumentIncasare(lnTip, .F.)
+ DO InregistreazaRezultat WITH lnTip, 'vechi', lnIdVz
+ IF lnIdVz > 0
+ DO LogLiniiDocument WITH lnIdVz
+ ENDIF
+
+ IF glIncercaFormaNoua
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== TIP ' + TRANSFORM(lnTip) + ' (' + laNumeTip[lnTip] + ') - FORMA NOUA (tnTip=3) ====='
+ lnIdVz = CreeazaDocumentIncasare(lnTip, .T.)
+ DO InregistreazaRezultat WITH lnTip, 'nou', lnIdVz
+ ELSE
+ DO S3bLog WITH ' forma noua SARITA (blocata, vezi raport)'
+ ENDIF
+ ENDFOR
+
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== COMPARATIE VECHI / NOU, PE TIP ====='
+ DO ComparaRezultate
+
+ DO S3bLog WITH CHR(13)+CHR(10) + '===== STARE DUPA (MAX(NR_INCASAT) pe tip_incasat, toata schema) ====='
+ DO LogStareMaxIncasat
+
+ _SCREEN.tmrDrvAD.Enabled = .F.
+ DO S3bFinal
+
+CATCH TO loExc
+ DO S3bLog WITH 'CATCH TOP-LEVEL ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
+ DO S3bFinal
+ENDTRY
+
+QUIT
+
+*==================================================================================
+PROCEDURE S3bLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13)+CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE S3bErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO S3bLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
+ENDPROC
+
+PROCEDURE S3bFinal
+ DO S3bLog WITH CHR(13)+CHR(10) + 'TOTAL pass=' + TRANSFORM(gnPass) + ' fail=' + TRANSFORM(gnFail)
+ DO S3bLog WITH 'END ' + TTOC(DATETIME())
+ QUIT
+ENDPROC
+
+PROCEDURE Assert
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO S3bLog WITH 'PASS: ' + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO S3bLog WITH 'FAIL: ' + tcMsg
+ ENDIF
+ENDPROC
+
+*-- cate randuri de plaja intoarce verifica_cursor_serii pentru un tip de document, fara sa aloce
+FUNCTION RanduriSerii
+ LPARAMETERS tnIdTipDoc
+ LOCAL lnOk, lnRanduri, lcSql
+ LOCAL ARRAY laErr[1]
+ PRIVATE pnIdTipDoc, pnRezultat
+ pnIdTipDoc = tnIdTipDoc
+ pnRezultat = 0
+ lnRanduri = -1
+ lcSql = "{call " + gcS + ".pack_serii_numere.verifica_cursor_serii(?pnIdTipDoc,?gnIdUtil,?gnIdSucursala,?@pnRezultat)}"
+ lnOk = SQLEXEC(gnHandle, lcSql, "crsprobapl")
+ IF lnOk > 0
+ lnRanduri = RECCOUNT("crsprobapl")
+ USE IN (SELECT("crsprobapl"))
+ ELSE
+ AERROR(laErr)
+ DO S3bLog WITH 'pre-proba plaje tip ' + TRANSFORM(tnIdTipDoc) + ' ESEC: ' + TRANSFORM(laErr[2])
+ ENDIF
+ RETURN lnRanduri
+ENDFUNC
+
+*-- 12b S4b: liniile VANZARI_DETALII (id_pol) + randurile ACT (SCD/SCC) ale documentului, ca
+*-- instantaneu "inainte" pentru CompAct (partea 3) - client/document fixe, notate in stare.
+PROCEDURE LogLiniiDocument
+ LPARAMETERS tnIdVz
+ LOCAL lnQ
+ lnQ = goExecutor.oExecute([select id_articol, id_pol, cont from vanzari_detalii where sters=0 and id_vanzare=] + ;
+ TRANSFORM(tnIdVz) + [ order by id_articol], 'crsLiniiVz')
+ IF lnQ > 0
+ SELECT crsLiniiVz
+ SCAN
+ DO S3bLog WITH ' [proba B linie] id_articol=' + TRANSFORM(id_articol) + ' id_pol=' + TRANSFORM(NVL(id_pol,-1)) + ' cont=' + TRANSFORM(NVL(cont,''))
+ ENDSCAN
+ USE IN crsLiniiVz
+ ENDIF
+ lnQ = goExecutor.oExecute([select scd, scc, ascd, ascc, id_venchelt from act a ] + ;
+ [join vanzari v on v.serie_act=a.serie_act and v.numar_act=a.nract ] + ;
+ [where a.sters=0 and v.id_vanzare=] + TRANSFORM(tnIdVz) + [ order by scd, scc], 'crsActVz')
+ IF lnQ > 0
+ SELECT crsActVz
+ SCAN
+ DO S3bLog WITH ' [proba B ACT] SCD=' + TRANSFORM(NVL(scd,'')) + ' SCC=' + TRANSFORM(NVL(scc,'')) + ;
+ ' ASCD=' + TRANSFORM(NVL(ascd,'')) + ' ASCC=' + TRANSFORM(NVL(ascc,'')) + ' ID_VENCHELT=' + TRANSFORM(NVL(id_venchelt,-1))
+ ENDSCAN
+ USE IN crsActVz
+ ENDIF
+ENDPROC
+
+PROCEDURE LogStareMaxIncasat
+ LOCAL lnQ
+ lnQ = goExecutor.oExecute([select tip_incasat, max(nr_incasat) as maxnr, count(*) as nr ] + ;
+ [from vanzari where tip_incasat is not null group by tip_incasat order by tip_incasat], 'crsMaxInc')
+ IF lnQ > 0
+ SELECT crsMaxInc
+ SCAN
+ DO S3bLog WITH ' tip_incasat=' + TRANSFORM(tip_incasat) + ' max(nr_incasat)=' + TRANSFORM(maxnr) + ' nr_documente=' + TRANSFORM(nr)
+ ENDSCAN
+ USE IN crsMaxInc
+ ELSE
+ DO S3bLog WITH ' EROARE citire stare incasat: ' + goExecutor.oPrelucrareEroare()
+ ENDIF
+ENDPROC
+
+*-- citeste randul VANZARI scris pentru id_vanzare si-l adauga in crsRezultate
+PROCEDURE InregistreazaRezultat
+ LPARAMETERS tnTip, tcForma, tnIdVz
+ DO Assert WITH tnIdVz > 0, '[' + tcForma + ' tip=' + TRANSFORM(tnTip) + '] documentul exista in VANZARI (jonctiune serie_act+nract), e=' + TRANSFORM(tnIdVz)
+ IF tnIdVz <= 0
+ DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': documentul NU s-a scris (id_vanzare=0), fara rand in VANZARI'
+ INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare) VALUES (tnTip, tcForma, 0)
+ RETURN
+ ENDIF
+ LOCAL lnQ
+ lnQ = goExecutor.oExecute([select id_vanzare, cod, serie_act, nvl(id_fact,0) as id_fact, ] + ;
+ [nvl(nr_incasat,0) as nr_incasat, nvl(tip_incasat,0) as tip_incasat, nvl(suma_incasat,0) as suma_incasat, ] + ;
+ [nvl(serie_incasat,'') as serie_incasat, total_cu_tva from vanzari where id_vanzare = ] + TRANSFORM(tnIdVz), 'crsVz1')
+ IF lnQ <= 0 OR RECCOUNT('crsVz1') <> 1
+ DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': EROARE citire VANZARI id_vanzare=' + TRANSFORM(tnIdVz)
+ INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare) VALUES (tnTip, tcForma, tnIdVz)
+ RETURN
+ ENDIF
+ SELECT crsVz1
+ INSERT INTO crsRezultate (tip_incasare, forma, id_vanzare, cod, serie_act, id_fact, ;
+ nr_incasare_asteptat, nr_incasat, tip_incasat, suma_incasat, serie_incasat, total_cu_tva) ;
+ VALUES (tnTip, tcForma, tnIdVz, crsVz1.cod, NVL(crsVz1.serie_act,''), crsVz1.id_fact, ;
+ gnNrIncasareCapturat, crsVz1.nr_incasat, crsVz1.tip_incasat, crsVz1.suma_incasat, NVL(crsVz1.serie_incasat,''), crsVz1.total_cu_tva)
+ DO S3bLog WITH ' ' + tcForma + ' tip=' + TRANSFORM(tnTip) + ': id_vanzare=' + TRANSFORM(tnIdVz) + ' cod=' + TRANSFORM(crsVz1.cod) + ;
+ ' serie_act=' + TRANSFORM(crsVz1.serie_act) + ' id_fact=' + TRANSFORM(crsVz1.id_fact) + ;
+ ' nr_incasat=' + TRANSFORM(crsVz1.nr_incasat) + ' (asteptat ' + TRANSFORM(gnNrIncasareCapturat) + ') tip_incasat=' + TRANSFORM(crsVz1.tip_incasat) + ;
+ ' suma_incasat=' + TRANSFORM(crsVz1.suma_incasat) + ' serie_incasat=[' + TRANSFORM(crsVz1.serie_incasat) + ']' + ;
+ ' total_cu_tva=' + TRANSFORM(crsVz1.total_cu_tva)
+ USE IN crsVz1
+
+ DO Assert WITH crsRezultate.nr_incasat = gnNrIncasareCapturat, ;
+ '[' + tcForma + ' tip=' + TRANSFORM(tnTip) + '] VANZARI.NR_INCASAT persistat (' + TRANSFORM(crsRezultate.nr_incasat) + ;
+ ') == poDate.nr_incasare capturat inainte de scriere (' + TRANSFORM(gnNrIncasareCapturat) + ')'
+ENDPROC
+
+PROCEDURE ComparaRezultate
+ LOCAL lnTip, lnRVechi, lnRNou
+ IF !glIncercaFormaNoua
+ DO S3bLog WITH ' forma noua sarita in aceasta rulare - fara comparatie vechi/nou, doar valorile persistate pe forma veche'
+ RETURN
+ ENDIF
+ FOR lnTip = 1 TO 4
+ SELECT crsRezultate
+ LOCATE FOR tip_incasare = lnTip AND forma == 'vechi'
+ IF !FOUND()
+ DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] rand vechi gasit in crsRezultate'
+ LOOP
+ ENDIF
+ lnRVechi = RECNO()
+ LOCATE FOR tip_incasare = lnTip AND forma == 'nou'
+ IF !FOUND()
+ DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] rand nou gasit in crsRezultate'
+ LOOP
+ ENDIF
+ lnRNou = RECNO()
+
+ LOCAL lnIdVechi, lnIdNou, lnTipIncVechi, lnTipIncNou, lnSumaVechi, lnSumaNou, lcSerieVechi, lcSerieNou
+ GO lnRVechi IN crsRezultate
+ lnIdVechi = crsRezultate.id_vanzare
+ lnTipIncVechi = crsRezultate.tip_incasat
+ lnSumaVechi = crsRezultate.suma_incasat
+ lcSerieVechi = crsRezultate.serie_incasat
+ GO lnRNou IN crsRezultate
+ lnIdNou = crsRezultate.id_vanzare
+ lnTipIncNou = crsRezultate.tip_incasat
+ lnSumaNou = crsRezultate.suma_incasat
+ lcSerieNou = crsRezultate.serie_incasat
+
+ IF lnIdVechi <= 0 OR lnIdNou <= 0
+ DO Assert WITH .F., '[tip=' + TRANSFORM(lnTip) + '] ambele documente s-au scris (vechi id_vanzare=' + ;
+ TRANSFORM(lnIdVechi) + ' nou id_vanzare=' + TRANSFORM(lnIdNou) + ')'
+ LOOP
+ ENDIF
+
+ DO Assert WITH lnTipIncVechi = lnTipIncNou, '[tip=' + TRANSFORM(lnTip) + '] VANZARI.TIP_INCASAT identic (vechi=' + ;
+ TRANSFORM(lnTipIncVechi) + ' nou=' + TRANSFORM(lnTipIncNou) + ')'
+ DO Assert WITH ABS(lnSumaVechi - lnSumaNou) < 0.005, '[tip=' + TRANSFORM(lnTip) + '] VANZARI.SUMA_INCASAT identica (vechi=' + ;
+ TRANSFORM(lnSumaVechi) + ' nou=' + TRANSFORM(lnSumaNou) + ')'
+ DO Assert WITH ALLTRIM(lcSerieVechi) == ALLTRIM(lcSerieNou), '[tip=' + TRANSFORM(lnTip) + '] VANZARI.SERIE_INCASAT identica (vechi=[' + ;
+ ALLTRIM(lcSerieVechi) + '] nou=[' + ALLTRIM(lcSerieNou) + '])'
+ ENDFOR
+ENDPROC
+
+*==================================================================================
+* CreeazaDocumentIncasare: emite un document REAL prin fluxul de productie (tnTip=22, cursor_preturi,
+* client RAJA id_part=463), aplicand tipul de incasare cerut pe formularul indicat. Intoarce
+* poDate.nid_vanzare (>0 succes) sau 0 (esec, detaliat in log). gnNrIncasareCapturat e umplut cu
+* poDate.nr_incasare chiar inainte de do_termin() - marimea persistata se verifica fata de asta.
+FUNCTION CreeazaDocumentIncasare
+ LPARAMETERS tnTipIncasare, tlFormNou
+
+ PRIVATE poDate, poGeneratorNumere, poDateGestiuneDest
+ LOCAL lnIdSet, lcSqlCursor, lcCursor, lnSucces, lnIdVanzareRezultat, tnTip, tnIdClient, tnIdDelegat
+ LOCAL lcSerieAlocata, lnNractAlocat
+ lnIdVanzareRezultat = 0
+ lcSerieAlocata = ''
+ lnNractAlocat = 0
+ gnNrIncasareCapturat = 0
+ *-- FORMA VECHE: tnTip=22 (AVIZ din lista de preturi) - calea PROVENITA, curata, fara efecte
+ *-- secundare (nu intra pe ramura "comanda" din do_scrie_factura). opt_incasat traieste pe
+ *-- frm_alte_date (clasa separata), deci nu are restrictia Between(poDate.tip,1,4).
+ *-- FORMA NOUA: are nevoie de tnTip Between(1,4) ca opt_incasat sa existe inline pe formular
+ *-- (ofacturare.vc2:21066) - singurele din acel interval cu date reale in cursor_preturi sunt
+ *-- 3/4 (probe_emitere_reala.prg), dar tnTip=3 declanseaza un MESSAGEBOX_FORM real necunoscut
+ *-- mock-ului ("Doriti sa se inchida comanda?") si formularul nou insusi agata la CREATEOBJECT
+ *-- pe coloana Gestiune a grd_factura (vezi raport) - BLOCAT, nerezolvat in aceasta sesiune.
+ *-- 12b S4b proba B: incercari tnTip=1 (client 332) si tnTip=2 (client 463) - Reccount=0 in acest
+ *-- mediu (poDate.id_gestiune_init implicit NULL); revenire la tnTip=22/client 463, singura
+ *-- combinatie confirmata ca intoarce articole headless (probe_emitere_reala.prg) - a dat
+ *-- documentul real id_vanzare=1883, aproape integral pe politica de stoc (41), nu politica reala
+ *-- 34 tintita initial - limitare consemnata in stare, nu blocanta (proba A caz7 acopera regresia
+ *-- pe politica reala 34 direct in PL/SQL)
+ tnTip = IIF(tlFormNou, 3, 22)
+ tnIdClient = 463
+ tnIdDelegat = 256
+
+ update_jtva_coloane([JV], [jtva_coloane_temp])
+ update_saft_taxtable()
+
+ lnIdSet = 25000 + tnTip - 1 + gnScadereStoc * 10
+ poDate = CREATEOBJECT("oDateFactura", lnIdSet, tnTip)
+ poGeneratorNumere = CREATEOBJECT("oGeneratorNumere")
+ poDateGestiuneDest = CREATEOBJECT("oDateGestiune")
+
+ IF !tlFormNou
+ poDate.nIdTipDoc = 6 && AVIZ - plaja globala, dovedit (id_vanzare 1061/1062/1063)
+ ENDIF
+
+ gnIdUtil = 8
+ poGeneratorNumere.ResetNumere()
+ poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(poDate.nIdTipDoc)
+
+ poDate.id_client = tnIdClient
+ poDate.id_delegat = tnIdDelegat
+ poDate.zi_curs = {^2026-08-10}
+
+ IF poDate.rezultat_serii = 3
+ poDate.serie_act = poGeneratorNumere.getSerieCursor(poDate.nIdTipDoc)
+ ENDIF
+ poDate.nract = poGeneratorNumere.aloca_numar(poDate.nIdTipDoc, NULL)
+ poGeneratorNumere.verifica_numar(poDate.nIdTipDoc, poDate.nract)
+ gnIdUtil = -3
+ lcSerieAlocata = ALLTRIM(TRANSFORM(NVL(poDate.serie_act, [])))
+ lnNractAlocat = poDate.nract
+ DO S3bLog WITH ' poDate.nract=' + TRANSFORM(poDate.nract) + ' serie_act=[' + TRANSFORM(NVL(poDate.serie_act,[])) + ']'
+
+ IF poDate.tva_incasare = 0
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_ex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ ELSE
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_neex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ ENDIF
+
+ lcSqlCursor = [{call ] + gcS + [.pack_facturare.cursor_preturi(?poDate.zi_curs,?poDate.tip,?poDate.id_valuta,] + ;
+ [?poDate.id_gestiune_init,?gnLuna,?gnAn,?gnIdUtil,?gnIdSucursala)}]
+
+ lcCursor = [crsarticole]
+ lnSucces = goExecutor.oExecute(lcSqlCursor, lcCursor)
+ IF lnSucces < 0
+ DO S3bLog WITH ' EROARE cursor articole: ' + goExecutor.oPrelucrareEroare()
+ poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc)
+ DO S3bCurataJtva
+ RELEASE poDate, poGeneratorNumere, poDateGestiuneDest
+ RETURN 0
+ ENDIF
+
+ IF RECCOUNT(lcCursor) = 0
+ DO S3bLog WITH ' Nu exista articole (Reccount=0) - abandon document'
+ poGeneratorNumere.dezaloca_numar(poDate.nIdTipDoc)
+ DO S3bCurataJtva
+ RELEASE poDate, poGeneratorNumere, poDateGestiuneDest
+ RETURN 0
+ ENDIF
+ DO S3bLog WITH ' crsarticole Reccount=' + TRANSFORM(RECCOUNT(lcCursor))
+
+ *-- Lista de preturi a articolului e in EURO (tip_valuta=1), iar do_scrie_articole
+ *-- trimite pe ramura aceea vpretftva, derivat din pret_val - fortand doar pret,
+ *-- documentul iesea cu VANZARI_DETALII.PRET=0. Se forteaza perechea, coerent cu cursul.
+ SELECT (lcCursor)
+ REPLACE ALL cantitate WITH 1, ;
+ pret_val WITH IIF(tip_valuta = 1, 100, 0), ;
+ pret WITH IIF(tip_valuta = 1, ROUND(100 * IIF(NVL(curs, 0) = 0, 1, curs) / IIF(NVL(multiplicator, 0) = 0, 1, multiplicator), gnPPretV), 100)
+ =TABLEUPDATE(.T., .T., lcCursor)
+ GO TOP
+
+ creeaza_facturacrs([crsfactura])
+
+ IF poDate.in_valuta = 1
+ SELECT DISTINCT Curs, nume_val, id_valuta, multiplicator FROM (lcCursor) WITH (Buffering = .T.) WHERE tip_valuta = 1 ORDER BY nume_val INTO CURSOR crscursuri
+ SELECT crscursuri
+ poDate.Curs = Curs
+ poDate.multiplicator = multiplicator
+ ELSE
+ citeste_cursuri_zi(poDate.zi_curs)
+ IF RECCOUNT('crscursuri') = 0
+ USE IN crscursuri
+ ENDIF
+ ENDIF
+
+ IF TYPE(lcCursor + '.nume_lista_preturi') <> 'U'
+ CREATE CURSOR crspolitici (id_pol N(20), nume_lista_preturi c(100))
+ SELECT crspolitici
+ INSERT INTO crspolitici(id_pol, nume_lista_preturi) VALUES (-9999, '')
+ INSERT INTO crspolitici(id_pol, nume_lista_preturi) ;
+ SELECT DISTINCT id_pol, nume_lista_preturi FROM (lcCursor) ORDER BY nume_lista_preturi
+ ENDIF
+
+ *-- formularul, modeless (apel direct de metode) - vechi sau unificat, dupa tlFormNou
+ PUBLIC goFrmS3b
+ IF tlFormNou
+ goFrmS3b = CREATEOBJECT('frm_facturare_articole2')
+ ELSE
+ goFrmS3b = CREATEOBJECT('frm_facturare_articole')
+ ENDIF
+ DO S3bLog WITH ' CREATEOBJECT OK, VARTYPE=' + VARTYPE(goFrmS3b)
+ goFrmS3b.WindowType = 0
+ DO S3bLog WITH ' WindowType=0 OK'
+ goFrmS3b.Show()
+ DO S3bLog WITH ' Show() OK'
+ DOEVENTS FORCE
+ DO S3bLog WITH ' formular afisat modeless (' + IIF(tlFormNou, 'NOU frm_facturare_articole2', 'VECHI frm_facturare_articole') + ')'
+
+ goFrmS3b.do_adauga_tot()
+ DOEVENTS FORCE
+ DO S3bLog WITH ' do_adauga_tot() -> Reccount(crsfactura)=' + TRANSFORM(RECCOUNT('crsfactura'))
+
+ goFrmS3b.do_calculeaza_totaluri()
+ DOEVENTS FORCE
+
+ *-- CONT_VENIT asteptat, derivat exact ca in do_scrie_articole (ofacturare.vc2:14279), citit
+ *-- direct din randul crsfactura pe care do_scrie_articole il va scana
+ LOCAL lcExpContVenit, lnExpIdPol, lnExpIdArticol, lcExpCont, loExecutorReal
+ SELECT crsfactura
+ GO TOP
+ lnExpIdPol = crsfactura.id_pol
+ lnExpIdArticol = crsfactura.id_articol
+ lcExpCont = crsfactura.Cont
+ lcExpContVenit = IIF(EMPTY(NVL(lnExpIdPol, 0)), deriva_cont_venit_fara_pol(lnExpIdArticol, lcExpCont), '')
+
+ *-- spion pe goExecutor (tehnica SpyS13, probe_s13_toomanycolumns.prg): captureaza SQL-ul real
+ *-- trimis de do_scrie_articole, fara sa-i schimbe comportamentul (DODEFAULT pe PCOUNT)
+ loExecutorReal = goExecutor
+ goExecutor = CREATEOBJECT('SpyContVenit')
+ goExecutor.nHandle = gnHandle
+
+ LOCAL lnScris
+ IF tlFormNou
+ *-- opt_incasat e inline pe formular - fara al doilea modal
+ goFrmS3b.seteaza_mod_incasare(tnTipIncasare)
+ gnNrIncasareCapturat = poDate.nr_incasare
+ DO S3bLog WITH ' opt_incasat.Value=' + TRANSFORM(tnTipIncasare) + ' -> poDate.nr_incasare=' + TRANSFORM(gnNrIncasareCapturat) + ;
+ ' incasat=' + TRANSFORM(poDate.incasat) + ' incasatCARD=' + TRANSFORM(poDate.incasatCARD)
+ lnScris = goFrmS3b.do_termin()
+ ELSE
+ *-- calea veche: al doilea modal (frm_alte_date) e condus de goDriverAD/tmrDrvAD
+ glDlgTratatAD = .F.
+ gnTipIncasareCerut = tnTipIncasare
+ lnScris = goFrmS3b.do_termin()
+ LOCAL lnWait
+ lnWait = 0
+ DO WHILE !glDlgTratatAD AND lnWait < 10
+ DOEVENTS FORCE
+ lnWait = lnWait + 1
+ ENDDO
+ ENDIF
+ DO S3bLog WITH ' do_termin() -> ' + TRANSFORM(lnScris) + ' poDate.nid_vanzare=' + TRANSFORM(NVL(poDate.nid_vanzare,0))
+
+ *-- restaureaza goExecutor real si verifica CONT_VENIT trimis de do_scrie_articole
+ LOCAL lcActualContVenit, lcEticheta
+ lcEticheta = '[' + IIF(tlFormNou,'nou','vechi') + ' tip=' + TRANSFORM(tnTipIncasare) + ']'
+ DO Assert WITH goExecutor.cLastArtCall # '', ;
+ lcEticheta + ' do_scrie_articole a trimis adauga_articol_factura (spion pe goExecutor)'
+ IF goExecutor.cLastArtCall # ''
+ lcActualContVenit = ExtrageContVenit(goExecutor.cLastArtCall)
+ DO Assert WITH lcActualContVenit == lcExpContVenit, ;
+ lcEticheta + ' CONT_VENIT trimis de do_scrie_articole = [' + lcExpContVenit + '], obtinut [' + lcActualContVenit + ']'
+ ENDIF
+ goExecutor = loExecutorReal
+
+ *-- do_termin() intoarce mereu .T. (_frm_base.vc2:363, DoDefault fara RETURN) si nid_vanzare
+ *-- ramane santinela la esec: singura dovada e randul din VANZARI, pe serie_act + nract.
+ lnIdVanzareRezultat = CdocGasesteIdVanzare(lcSerieAlocata, lnNractAlocat)
+ IF lnIdVanzareRezultat < 0
+ lnIdVanzareRezultat = 0
+ ENDIF
+ DO S3bLog WITH ' verificare in VANZARI pe ' + lcSerieAlocata + ' ' + TRANSFORM(lnNractAlocat) + ;
+ ' -> id_vanzare=' + TRANSFORM(lnIdVanzareRezultat)
+
+ IF TYPE('goFrmS3b') = 'O' AND !ISNULL(goFrmS3b)
+ goFrmS3b.Release()
+ ENDIF
+ goFrmS3b = NULL
+
+ IF USED('crspolitici')
+ USE IN crspolitici
+ ENDIF
+ IF USED('crscursuri')
+ USE IN crscursuri
+ ENDIF
+ IF USED('crsfactura')
+ USE IN crsfactura
+ ENDIF
+ IF USED('crsarticole')
+ USE IN crsarticole
+ ENDIF
+ IF USED('jtva_coloane')
+ USE IN jtva_coloane
+ ENDIF
+ IF USED('jtva_coloane_temp')
+ USE IN jtva_coloane_temp
+ ENDIF
+
+ RELEASE poDate, poGeneratorNumere, poDateGestiuneDest
+ RETURN lnIdVanzareRezultat
+ENDFUNC
+
+PROCEDURE S3bCurataJtva
+ IF USED('jtva_coloane')
+ USE IN jtva_coloane
+ ENDIF
+ IF USED('jtva_coloane_temp')
+ USE IN jtva_coloane_temp
+ ENDIF
+ENDPROC
+
+*-- extrage parametrul 29 (CONT_VENIT) dintr-un apel capturat pack_facturare.adauga_articol_factura(...);
+*-- pozitia 28 e mereu literalul NULL, deci pos29 e tot ce urmeaza dupa ultima virgula dinaintea "); end;"
+FUNCTION ExtrageContVenit
+ LPARAMETERS tcSql
+ LOCAL lnEnd, lcParams, lnComma, lcPos29
+ lnEnd = AT('); end;', tcSql)
+ IF lnEnd = 0
+ RETURN ''
+ ENDIF
+ lcParams = LEFT(tcSql, lnEnd - 1)
+ lnComma = RAT(',', lcParams)
+ IF lnComma = 0
+ RETURN ''
+ ENDIF
+ lcPos29 = SUBSTR(lcParams, lnComma + 1)
+ IF UPPER(lcPos29) == 'NULL'
+ RETURN ''
+ ENDIF
+ RETURN STRTRAN(lcPos29, "'", '')
+ENDFUNC
+
+*==================================================================================
+*-- SpyContVenit: subclasa a lui oexecutor (tehnica SpyS13 din probe_s13_toomanycolumns.prg) -
+*-- logheaza in cLastArtCall statementul adauga_articol_factura, apoi executa normal prin
+*-- DODEFAULT pe PCOUNT (fara sa schimbe comportamentul real)
+DEFINE CLASS SpyContVenit AS oexecutor
+ cLastArtCall = ''
+
+ PROCEDURE oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect)
+ LOCAL lnPc, lcS, lnRet
+ lnPc = PCOUNT()
+ lcS = IIF(VARTYPE(m.tcSql) = 'C', m.tcSql, '')
+ IF 'adauga_articol_factura(' $ lcS
+ THIS.cLastArtCall = lcS
+ ENDIF
+ TRY
+ DO CASE
+ CASE lnPc <= 1
+ lnRet = DODEFAULT(m.tcSql)
+ CASE lnPc = 2
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor)
+ CASE lnPc = 3
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress)
+ CASE lnPc = 4
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress)
+ CASE lnPc = 5
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle)
+ CASE lnPc = 6
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError)
+ CASE lnPc = 7
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError)
+ OTHERWISE
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError, m.tlReconnect)
+ ENDCASE
+ CATCH TO loExSpy
+ lnRet = -1
+ THIS.cEroare = 'SpyContVenit: ' + TRANSFORM(loExSpy.Message)
+ ENDTRY
+ RETURN lnRet
+ ENDPROC
+ENDDEFINE
+
+*==================================================================================
+*-- driverAlteDateAD: cauta FRM_ALTE_DATE prin _SCREEN.Forms si ii seteaza opt_incasat.Value la
+* gnTipIncasareCerut INAINTE de a-i chema .do_termin() - acelasi mecanism ca driverAlteDate8 din
+* creeaza_documente_s8.prg, cu un singur adaos (selectia tipului de incasare).
+DEFINE CLASS driverAlteDateAD AS Custom
+ PROCEDURE Executa
+ LOCAL lnI, loForm, llGasit, loMsgForm
+ llGasit = .F.
+ loMsgForm = NULL
+ FOR lnI = 1 TO _SCREEN.FormCount
+ LOCAL lcClasa
+ lcClasa = UPPER(_SCREEN.Forms(lnI).Class)
+ IF lcClasa == 'FRM_ALTE_DATE'
+ loForm = _SCREEN.Forms(lnI)
+ llGasit = .T.
+ ENDIF
+ IF 'MESSAGEBOX_FORM' $ lcClasa
+ loMsgForm = _SCREEN.Forms(lnI)
+ ENDIF
+ IF !(lcClasa $ gcClaseVazute)
+ gcClaseVazute = gcClaseVazute + lcClasa + ';'
+ DO S3bLog WITH ' [diag timer] forma noua vazuta: ' + lcClasa + ' Caption=[' + TRANSFORM(_SCREEN.Forms(lnI).Caption) + ']'
+ ENDIF
+ ENDFOR
+ *-- confirmare reala neacoperita de mock_amessagebox (forma modala messagebox_form) -
+ *-- apasa automat cmdYes/cmdOk, ca in productie la raspuns implicit "Da"
+ IF !ISNULL(loMsgForm)
+ TRY
+ DO CASE
+ CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdYes', 5)
+ DO S3bLog WITH ' [diag timer] messagebox_form: apas cmgBotones.cmdYes'
+ loMsgForm.cmgBotones.cmdYes.Click()
+ CASE PEMSTATUS(loMsgForm.cmgBotones, 'cmdOk', 5)
+ DO S3bLog WITH ' [diag timer] messagebox_form: apas cmgBotones.cmdOk'
+ loMsgForm.cmgBotones.cmdOk.Click()
+ ENDCASE
+ CATCH TO loExcMsg
+ DO S3bLog WITH ' [diag timer] messagebox_form: CATCH ' + TRANSFORM(loExcMsg.ErrorNo) + ' ' + loExcMsg.Message
+ ENDTRY
+ ENDIF
+ IF glDlgTratatAD OR !llGasit
+ RETURN
+ ENDIF
+ LOCAL loAC
+ loAC = loForm.ActiveControl
+ TRY
+ loForm.opt_incasat.Value = gnTipIncasareCerut
+ gnNrIncasareCapturat = poDate.nr_incasare
+ DO S3bLog WITH ' driverAlteDateAD: opt_incasat.Value=' + TRANSFORM(gnTipIncasareCerut) + ;
+ ' -> poDate.nr_incasare=' + TRANSFORM(gnNrIncasareCapturat) + ' incasat=' + TRANSFORM(poDate.incasat) + ;
+ ' incasatCARD=' + TRANSFORM(poDate.incasatCARD)
+ loForm.do_termin()
+ glDlgTratatAD = .T.
+ CATCH TO loExcDrv
+ DO S3bLog WITH ' driverAlteDateAD: CATCH ErrorNo=' + TRANSFORM(loExcDrv.ErrorNo) + ' Message=' + loExcDrv.Message + ;
+ ' Procedure=' + loExcDrv.Procedure + ' LineNo=' + TRANSFORM(loExcDrv.LineNo)
+ glDlgTratatAD = .T.
+ ENDTRY
+ ENDPROC
+ENDDEFINE
diff --git a/utile/Teste/facturare_unificat/probe_12b_s6b_clasa_pret_nomenclator.prg b/utile/Teste/facturare_unificat/probe_12b_s6b_clasa_pret_nomenclator.prg
new file mode 100644
index 0000000..2c172f4
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s6b_clasa_pret_nomenclator.prg
@@ -0,0 +1,406 @@
+* probe_12b_s6b_clasa_pret_nomenclator.prg
+* Plan #12b, S6b - proba headless pe clasa cus_pret_nomenclator (COMUN\programe\ofacturare_comun.prg:2319),
+* definita direct in .prg (Set Procedure To ofacturare_comun.prg, deja Additive in mediul de test),
+* nu in .vcx - CREATEOBJECT direct, fara SET CLASSLIB.
+*
+* Articol de proba: 2528841557 (ARIPA FATA AUDI A4), are deja rand pe politica 41 (tiparul S5/S5b).
+* Conturi 461/7583 (tiparul S5b caz2 si S4b caz1/caz6): validate in PLCONT, fara nota preexistenta.
+*
+* Cazuri (numerotate ca in docs\stare_plan_12b.md / plan_12b, sectiunea S6b):
+* (1) asigura_politica -> 41; incarca -> salveaza (12.34/1.21, conturi goale) -> instanta noua
+* incarca -> aceleasi valori; citire si prin cursor_preturi (tiparul S5).
+* (2) doar cont debit fara credit -> valideaza .F., spion: zero apeluri RPC.
+* (3) esec fortat pe al doilea RPC (salveaza_pret_nomenclator) dupa ce primul (gaseste_sau_creeaza_
+* nota_vanzare, real, 461/7583) a creat nota -> salveaza .F.; SAVEPOINT/ROLLBACK TO local (nu
+* tot lantul), apoi SELECT confirma ca nici nota noua, nici randul nu au ramas modificate.
+* (4) rand cu ID_NOTA existent (pus direct prin SQL, in tranzactie), instanta noua fara incarca,
+* salveaza -> ID_NOTA neschimbat (pnScrieNota=0 cand lIncarcat=.F.).
+* (5) conturi 461/7583 salvate prin clasa (real, fara spion) -> pack_facturare.contabilizeaza_articol
+* pe un rand de factura pentru acelasi articol/politica -> ACT_TEMP.SCD=461/SCC=7583 (tiparul S4b-A).
+* (6) recalculeaza_pret: 100 fara TVA la proc_tvav=1.21 -> 121 si invers: 121 -> 100, rotunjire la
+* zecimalele reale (gnPc=2, verificat egal cu pack_sesiune.nzecimale_pretv - baseline_12b.sql:114).
+*
+* Spion pe goExecutor (subclasa, DODEFAULT pe PCOUNT) - tiparul din probe_12b_s7a_optiuni_readonly.prg /
+* editare_factura\probe_s13_toomanycolumns.prg: nu opreste executia decat pentru cazul (3), unde
+* filtreaza explicit SQL-ul care contine 'salveaza_pret_nomenclator' si intoarce -1 fara sa-l trimita.
+*
+* Rulare: powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume probe_12b_s6b_clasa_pret_nomenclator
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\s6b_clasa.log (cerut de sarcina, nu out\)
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail, gnTransOriginal, gcErrMsg, gnIdArtProba, gnAn, gnLuna
+gcErrMsg = ""
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s6b_clasa.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+gnIdArtProba = 2528841557
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+gnIdUtil = 8
+* gnPc lipseste din test_init_env_auto_roafacturare - il seteaza aplicatia real la nivelul sesiunii,
+* tiparul din alte probe ale suitei (gnPc = 2, ex. test_s4c_discount_grid.prg)
+PUBLIC gnPc
+gnPc = 2
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle) + " gnPc=" + TRANSFORM(gnPc)
+
+IF TYPE('cus_pret_nomenclator') <> 'C' AND !("CUS_PRET_NOMENCLATOR" $ UPPER(SET('PROCEDURE')))
+ * verificare informativa - CREATEOBJECT esueaza oricum mai jos daca clasa nu e vizibila
+ DO AfLog WITH "info: SET(PROCEDURE) nu confirma explicit ofacturare_comun.prg (verificare slaba, se bazeaza pe CREATEOBJECT)"
+ENDIF
+
+gnTransOriginal = SQLGETPROP(gnHandle, "Transactions")
+SQLSETPROP(gnHandle, "Transactions", 2)
+DO AfLog WITH "Transactions manual, original=" + TRANSFORM(gnTransOriginal)
+
+*----------------------------------------------------------------------------------------
+* precondition: articolul de proba e chiar pe politica 41, si pack_facturare are politica de
+* stoc + antetul de document initializate (cerut de contabilizeaza_articol la cazul 5, tiparul
+* precondition din probe_12b_s4b_matrice.prg)
+gcCaz = "[precondition] "
+LOCAL lnOk, lcSql
+lnOk = SQLEXEC(gnHandle, "select count(*) cnt from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(gnIdArtProba), "crspre")
+DO Verdict WITH lnOk > 0 AND USED('crspre') AND crspre.cnt = 1, "articolul " + TRANSFORM(gnIdArtProba) + " e pe politica 41 (cnt=" + TRANSFORM(IIF(USED('crspre'),crspre.cnt,-1)) + ")"
+IF USED('crspre')
+ USE IN crspre
+ENDIF
+
+gnAn = YEAR(DATETIME())
+gnLuna = MONTH(DATETIME())
+lcSql = [begin pack_facturare.initializeaza_facturare(8); ] + ;
+ [if nvl(pack_facturare.nid_politica_stoc,0) <> 41 then raise_application_error(-20900,'nid_politica_stoc='||to_char(pack_facturare.nid_politica_stoc)); end if; ] + ;
+ [pack_facturare.nnumar_act := 999998; pack_facturare.cserie_act := 'TST'; ] + ;
+ [pack_facturare.ddata_ireg := sysdate; pack_facturare.ddata_act := sysdate; pack_facturare.ddata_scadenta := sysdate; ] + ;
+ [pack_facturare.nid_moneda_nationala := 3; pack_facturare.nperechec := 0; pack_facturare.nid_fdoc := 0; ] + ;
+ [pack_facturare.nid_factc := 0; pack_facturare.nid_part := 0; pack_facturare.nid_partc := 0; pack_facturare.nid_set := 26000; ] + ;
+ [pack_facturare.nid_sectie_stoc := nvl(pack_facturare.nid_sectie_stoc,1); pack_facturare.ntip := 1; end;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "initializeaza_facturare(8) + antet document proba + precondition nid_politica_stoc=41"
+IF lnOk <= 0
+ DO AfLog WITH "BLOCAT: precondition esuata, opresc"
+ DO Final
+ENDIF
+
+*==========================================================================================
+* CAZ (1): asigura_politica -> incarca -> salveaza (conturi goale) -> instanta noua incarca
+*==========================================================================================
+gcCaz = "[1-incarca-salveaza-reincarca] "
+LOCAL loP1, loP1b
+loP1 = CREATEOBJECT('cus_pret_nomenclator')
+LOCAL lnPol1
+lnPol1 = loP1.asigura_politica()
+DO Verdict WITH lnPol1 = 41, "asigura_politica() = 41 (obtinut " + TRANSFORM(lnPol1) + ")"
+
+DO Verdict WITH loP1.incarca(gnIdArtProba), "incarca(" + TRANSFORM(gnIdArtProba) + ") = .T."
+DO AfLog WITH " inainte de salveaza: pretftva=" + TRANSFORM(loP1.nPretFtva) + " pretctva=" + TRANSFORM(loP1.nPretCtva) + " proc_tvav=" + TRANSFORM(loP1.nProcTvav) + " id_nota=" + TRANSFORM(NVL(loP1.nIdNota,-999))
+
+loP1.nPretFtva = 12.34
+loP1.nProcTvav = 1.21
+loP1.nPretCtva = loP1.recalculeaza_pret(loP1.nPretFtva, .T.)
+loP1.cScd = []
+loP1.cScc = []
+DO Verdict WITH loP1.salveaza(gnIdArtProba), "salveaza() = .T. (pretftva=12.34 pretctva=" + TRANSFORM(loP1.nPretCtva) + " proc_tvav=1.21, conturi goale)"
+
+loP1b = CREATEOBJECT('cus_pret_nomenclator')
+DO Verdict WITH loP1b.incarca(gnIdArtProba), "instanta noua: incarca(" + TRANSFORM(gnIdArtProba) + ") = .T."
+DO Verdict WITH loP1b.nPretFtva == 12.34, "reincarcat pretftva=12.34 (obtinut " + TRANSFORM(loP1b.nPretFtva) + ")"
+DO Verdict WITH loP1b.nPretCtva == loP1.nPretCtva, "reincarcat pretctva=" + TRANSFORM(loP1.nPretCtva) + " (obtinut " + TRANSFORM(loP1b.nPretCtva) + ")"
+DO Verdict WITH loP1b.nProcTvav == 1.21, "reincarcat proc_tvav=1.21 (obtinut " + TRANSFORM(loP1b.nProcTvav) + ")"
+DO Verdict WITH ISNULL(loP1b.nIdNota), "reincarcat id_nota=NULL (conturi goale la salvare, incarcat=.T. -> scrie_nota=1)"
+
+* citire si prin cursor_preturi (tiparul S5): articol vizibil prin STOC temporar (gestiune 1, cants=10)
+gcCaz = "[1b-cursor_preturi] "
+LOCAL lnIdStoc
+lnOk = SQLEXEC(gnHandle, "select nvl(max(id_stoc),0)+1 idn from stoc", "crsids")
+lnIdStoc = IIF(lnOk > 0 AND USED('crsids'), crsids.idn, 0)
+IF USED('crsids')
+ USE IN crsids
+ENDIF
+lcSql = "insert into stoc (id_stoc, an, luna, id_articol, pret, pretv, tva, tvav, cants, cant, cante, cont, pretd, id_gestiune, proc_tvav, id_sucursala) values (" + ;
+ TRANSFORM(lnIdStoc) + "," + TRANSFORM(gnAn) + "," + TRANSFORM(gnLuna) + "," + TRANSFORM(gnIdArtProba) + ",0,0,0,0,10,0,0,'371',0,1,1.21,167)"
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "INSERT STOC temporar pentru vizibilitate in cursor_preturi (id_stoc=" + TRANSFORM(lnIdStoc) + ")"
+
+PRIVATE pnIdArtCursor, pnGasitCursor, pnPretCursor, pnProcCursor
+pnIdArtCursor = gnIdArtProba
+pnGasitCursor = 0
+pnPretCursor = 0
+pnProcCursor = 0
+* ?@ ca tinta de asignare directa (nu doar ca parametru de apel) e confirmat in COMUN\clase\ocomenzi.vc2:1916
+* ([begin ?@pcMesajVerificareCom:=pack_comenzi.verifica_acces_comanda(...); end;]) - dar doar ca instructiune
+* de top-level, o singura data; asignarile de mai jos se fac dupa LOOP, in variabile PL/SQL simple pe
+* parcursul buclei, ca sa nu riscam un bind ?@ neconfirmat imbricat in IF/LOOP (View Parameter modal)
+lcSql = [declare v_cursor pack_facturare.cursor_facturare; v_id_c number; v_id_articol number; v_lot varchar2(50); v_serie varchar2(50); ] + ;
+ [v_id_pol number; v_id_valuta number; v_nume_lista varchar2(200); v_discount number; v_discount_val number; ] + ;
+ [v_codmat varchar2(50); v_codbare varchar2(50); v_denumire varchar2(200); v_um varchar2(50); v_gestionabil number; ] + ;
+ [v_cantitate number; v_proc_tvav number; v_preturi_cu_tva number; v_curs number; v_multiplicator number; ] + ;
+ [v_pret number; v_pret_val number; v_tip_valuta number; v_nume_val varchar2(50); v_modificabil number; ] + ;
+ [v_gasit number := 0; v_pret_out number := 0; v_proc_out number := 0; ] + ;
+ [begin pack_facturare.cursor_preturi(trunc(sysdate),1,3,null,] + TRANSFORM(gnLuna) + [,] + TRANSFORM(gnAn) + [,8,167,v_cursor); ] + ;
+ [loop fetch v_cursor into v_id_c, v_id_articol, v_lot, v_serie, v_id_pol, v_id_valuta, v_nume_lista, v_discount, v_discount_val, ] + ;
+ [v_codmat, v_codbare, v_denumire, v_um, v_gestionabil, v_cantitate, v_proc_tvav, v_preturi_cu_tva, v_curs, v_multiplicator, ] + ;
+ [v_pret, v_pret_val, v_tip_valuta, v_nume_val, v_modificabil; ] + ;
+ [exit when v_cursor%notfound; if v_id_articol = ] + TRANSFORM(gnIdArtProba) + [ then v_gasit := 1; v_pret_out := v_pret; v_proc_out := v_proc_tvav; exit; end if; end loop; ] + ;
+ [close v_cursor; ?@pnGasitCursor := v_gasit; ?@pnPretCursor := v_pret_out; ?@pnProcCursor := v_proc_out; end;]
+lnOk = goExecutor.oExecute(lcSql)
+DO Verdict WITH lnOk >= 0, "bloc cursor_preturi executat fara eroare"
+DO AfLog WITH " cursor_preturi: gasit=" + TRANSFORM(pnGasitCursor) + " pret=" + TRANSFORM(pnPretCursor) + " proc_tvav=" + TRANSFORM(pnProcCursor)
+DO Verdict WITH pnGasitCursor = 1, "articolul apare in cursor_preturi (STOC temporar vizibil)"
+DO Verdict WITH ROUND(pnPretCursor,2) == 12.34, "cursor_preturi.pret = 12.34 (obtinut " + TRANSFORM(pnPretCursor) + ")"
+DO Verdict WITH ROUND(pnProcCursor,2) == 1.21, "cursor_preturi.proc_tvav = 1.21 (obtinut " + TRANSFORM(pnProcCursor) + ")"
+
+lnOk = SQLEXEC(gnHandle, "delete from stoc where id_stoc = " + TRANSFORM(lnIdStoc))
+DO Verdict WITH lnOk >= 0, "curatare STOC temporar"
+
+*==========================================================================================
+* CAZ (2): doar cont debit fara credit -> valideaza .F., zero apeluri RPC
+*==========================================================================================
+gcCaz = "[2-doar-debit-zero-rpc] "
+LOCAL loP2, loRealTmp, loSpy2
+loP2 = CREATEOBJECT('cus_pret_nomenclator')
+loP2.nPretFtva = 10
+loP2.nPretCtva = 12.1
+loP2.nProcTvav = 1.21
+loP2.cScd = '461'
+loP2.cScc = []
+DO Verdict WITH !loP2.valideaza(), "valideaza() = .F. (doar debit, fara credit)"
+
+loRealTmp = goExecutor
+loSpy2 = CREATEOBJECT('SpyS6b')
+goExecutor = loSpy2
+LOCAL llRezSalv2
+llRezSalv2 = loP2.salveaza(gnIdArtProba)
+goExecutor = loRealTmp
+DO Verdict WITH !llRezSalv2, "salveaza() = .F. (refuz pe validare)"
+DO Verdict WITH loSpy2.nApeluri = 0, "zero apeluri RPC prin executor (" + TRANSFORM(loSpy2.nApeluri) + " obtinut)"
+
+*==========================================================================================
+* CAZ (3): esec fortat pe al doilea RPC (salveaza_pret_nomenclator), dupa ce primul (nota
+* 461/7583) chiar s-a executat - SAVEPOINT local, ROLLBACK TO, apoi SELECT de confirmare
+*==========================================================================================
+gcCaz = "[3-esec-al-doilea-rpc] "
+lnOk = SQLEXEC(gnHandle, "SAVEPOINT SP_CAZ3")
+DO Verdict WITH lnOk > 0, "SAVEPOINT SP_CAZ3"
+
+LOCAL lnMaxNotaInainte, lnIdNotaRandInainte
+lnOk = SQLEXEC(gnHandle, "select nvl(max(id_nota),0) mx from crm_note_vanzari", "crsmx1")
+lnMaxNotaInainte = IIF(lnOk > 0 AND USED('crsmx1'), crsmx1.mx, -1)
+IF USED('crsmx1')
+ USE IN crsmx1
+ENDIF
+lnOk = SQLEXEC(gnHandle, "select id_nota from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(gnIdArtProba), "crsid1")
+lnIdNotaRandInainte = IIF(lnOk > 0 AND USED('crsid1'), NVL(crsid1.id_nota,-999), -999)
+IF USED('crsid1')
+ USE IN crsid1
+ENDIF
+DO AfLog WITH " inainte: max(id_nota)=" + TRANSFORM(lnMaxNotaInainte) + " id_nota rand=" + TRANSFORM(lnIdNotaRandInainte)
+
+LOCAL loP3, loSpy3
+loP3 = CREATEOBJECT('cus_pret_nomenclator')
+DO Verdict WITH loP3.incarca(gnIdArtProba), "incarca() pentru caz3"
+loP3.nPretFtva = 20
+loP3.nProcTvav = 1.21
+loP3.nPretCtva = loP3.recalculeaza_pret(loP3.nPretFtva, .T.)
+loP3.cScd = '461'
+loP3.cScc = '7583'
+
+loRealTmp = goExecutor
+loSpy3 = CREATEOBJECT('SpyS6b')
+loSpy3.lForteazaEsecSalveaza = .T.
+goExecutor = loSpy3
+LOCAL llRezSalv3
+llRezSalv3 = loP3.salveaza(gnIdArtProba)
+goExecutor = loRealTmp
+DO Verdict WITH !llRezSalv3, "salveaza() = .F. (RPC2 fortat sa esueze)"
+DO Verdict WITH loSpy3.nApeluri = 2, "2 apeluri RPC (nota + salveaza_pret_nomenclator interceptat) - " + TRANSFORM(loSpy3.nApeluri)
+
+lnOk = SQLEXEC(gnHandle, "ROLLBACK TO SP_CAZ3")
+DO Verdict WITH lnOk > 0, "ROLLBACK TO SP_CAZ3"
+
+LOCAL lnMaxNotaDupa, lnIdNotaRandDupa
+lnOk = SQLEXEC(gnHandle, "select nvl(max(id_nota),0) mx from crm_note_vanzari", "crsmx2")
+lnMaxNotaDupa = IIF(lnOk > 0 AND USED('crsmx2'), crsmx2.mx, -1)
+IF USED('crsmx2')
+ USE IN crsmx2
+ENDIF
+lnOk = SQLEXEC(gnHandle, "select id_nota from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(gnIdArtProba), "crsid2")
+lnIdNotaRandDupa = IIF(lnOk > 0 AND USED('crsid2'), NVL(crsid2.id_nota,-999), -999)
+IF USED('crsid2')
+ USE IN crsid2
+ENDIF
+DO AfLog WITH " dupa ROLLBACK: max(id_nota)=" + TRANSFORM(lnMaxNotaDupa) + " id_nota rand=" + TRANSFORM(lnIdNotaRandDupa)
+DO Verdict WITH lnMaxNotaDupa = lnMaxNotaInainte, "dupa ROLLBACK nicio nota noua (max(id_nota) neschimbat)"
+DO Verdict WITH lnIdNotaRandDupa = lnIdNotaRandInainte, "dupa ROLLBACK randul politicii nu a fost modificat (id_nota=" + TRANSFORM(lnIdNotaRandDupa) + ")"
+
+*==========================================================================================
+* CAZ (4): rand cu ID_NOTA existent (SQL direct), instanta noua fara incarca -> ID_NOTA neschimbat
+*==========================================================================================
+gcCaz = "[4-fara-incarca-idnota-neschimbat] "
+LOCAL lnNotaFixata
+lnNotaFixata = 6
+lnOk = SQLEXEC(gnHandle, "update crm_politici_pret_art set id_nota = " + TRANSFORM(lnNotaFixata) + " where id_pol = 41 and id_articol = " + TRANSFORM(gnIdArtProba))
+DO Verdict WITH lnOk > 0, "UPDATE id_nota=" + TRANSFORM(lnNotaFixata) + " direct pe rand (precondition caz 4)"
+
+LOCAL loP4
+loP4 = CREATEOBJECT('cus_pret_nomenclator')
+DO Verdict WITH !loP4.lIncarcat, "instanta noua: lIncarcat=.F. (fara incarca)"
+loP4.nPretFtva = 30
+loP4.nProcTvav = 1.21
+loP4.nPretCtva = loP4.recalculeaza_pret(loP4.nPretFtva, .T.)
+DO Verdict WITH loP4.salveaza(gnIdArtProba), "salveaza() fara incarca = .T."
+
+lnOk = SQLEXEC(gnHandle, "select id_nota from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(gnIdArtProba), "crsid4")
+DO Verdict WITH lnOk > 0 AND USED('crsid4') AND NVL(crsid4.id_nota,-999) = lnNotaFixata, "id_nota neschimbat dupa salveaza() fara incarca (" + TRANSFORM(IIF(USED('crsid4'),NVL(crsid4.id_nota,-999),-999)) + ", asteptat " + TRANSFORM(lnNotaFixata) + ")"
+IF USED('crsid4')
+ USE IN crsid4
+ENDIF
+
+*==========================================================================================
+* CAZ (5): conturi 461/7583 salvate prin clasa (real) -> contabilizeaza_articol -> ACT_TEMP
+*==========================================================================================
+gcCaz = "[5-conturi-461-7583-contabilizare] "
+LOCAL loP5
+loP5 = CREATEOBJECT('cus_pret_nomenclator')
+DO Verdict WITH loP5.incarca(gnIdArtProba), "incarca() pentru caz5"
+loP5.nPretFtva = 40
+loP5.nProcTvav = 1.21
+loP5.nPretCtva = loP5.recalculeaza_pret(loP5.nPretFtva, .T.)
+loP5.cScd = '461'
+loP5.cScc = '7583'
+DO Verdict WITH loP5.salveaza(gnIdArtProba), "salveaza() real cu conturi 461/7583 = .T."
+DO Verdict WITH !ISNULL(loP5.nIdNota) AND loP5.nIdNota > 0, "id_nota atribuit dupa salveaza (" + TRANSFORM(NVL(loP5.nIdNota,-1)) + ")"
+
+lcSql = [DECLARE v_row vanzari_detalii_temp%ROWTYPE; v_res NUMBER; ] + ;
+ [BEGIN pack_facturare.ntip := 1; pack_facturare.nid_act := -906000; ] + ;
+ [v_row.id_pol := 41; v_row.id_articol := ] + TRANSFORM(gnIdArtProba) + [; v_row.cont_venit := NULL; ] + ;
+ [v_row.cantitate := 1; v_row.pret := 40; v_row.discount_unitar := 0; v_row.pret_cu_tva := 0; ] + ;
+ [v_row.id_valuta := 3; v_row.curs := 1; v_row.multiplicator := 1; v_row.id_gestiune := -1000; ] + ;
+ [v_row.in_stoc := 0; v_row.explicatia := 'PROBA S6B CAZ5'; v_row.proc_tvav := 1.21; ] + ;
+ [v_res := pack_facturare.contabilizeaza_articol(v_row); END;]
+lnOk = SQLEXEC(gnHandle, lcSql)
+DO Verdict WITH lnOk > 0, "contabilizeaza_articol fara eroare"
+IF lnOk > 0
+ * ACT_TEMP.ID_ACT = nid_act + 1, nu nid_act (tiparul confirmat pe toate cele 11 cazuri din
+ * probe_12b_s4b_matrice.prg, ex. nid_act=-901000 -> LeaActTemp WITH -900999)
+ lnOk = SQLEXEC(gnHandle, "select nvl(scd,'') scd, nvl(scc,'') scc from act_temp where id_act = -905999", "crsact5")
+ IF lnOk > 0 AND USED('crsact5') AND RECCOUNT('crsact5') = 1
+ DO AfLog WITH " ACT_TEMP: SCD=" + ALLTRIM(crsact5.scd) + " SCC=" + ALLTRIM(crsact5.scc)
+ DO Verdict WITH ALLTRIM(crsact5.scd) == "461" AND ALLTRIM(crsact5.scc) == "7583", "ACT_TEMP.SCD/SCC = 461/7583 (nota scrisa prin clasa)"
+ ELSE
+ DO Verdict WITH .F., "nicio linie in ACT_TEMP (neasteptat)"
+ ENDIF
+ENDIF
+IF USED('crsact5')
+ USE IN crsact5
+ENDIF
+
+*==========================================================================================
+* CAZ (6): recalculeaza_pret, rotunjire pe gnPc (verificat egal cu pack_sesiune.nzecimale_pretv)
+*==========================================================================================
+gcCaz = "[6-recalculeaza_pret] "
+* pack_sesiune.nzecimale_pretv e variabila de pachet PL/SQL, neselectabila direct din SQL
+* (ORA-06553 PLS-221, confirmat in docs\baseline_12b.md:6-9) - SQLEXEC-ul de mai jos esua tacut
+* (lnOk<=0), de-aia asertul vechi trecea gnPc fata de fallback-ul -1, nu fata de o valoare reala.
+* recalculeaza_pret (ofacturare_comun.prg:2485/2487) foloseste Round(tnPret*nProcTvav, gnPc) -
+* gnPc e sursa reala de rotunjire, nu pachetul Oracle; verificat prin cod (vfp_symbols -Grep).
+DO Verdict WITH gnPc = 2, "gnPc = 2 (precizie sume lei, sursa reala din recalculeaza_pret - ofacturare_comun.prg:2485)"
+
+LOCAL loP6
+loP6 = CREATEOBJECT('cus_pret_nomenclator')
+loP6.nProcTvav = 1.21
+DO Verdict WITH loP6.recalculeaza_pret(100, .T.) == 121, "recalculeaza_pret(100,.T.) = 121 (obtinut " + TRANSFORM(loP6.recalculeaza_pret(100,.T.)) + ")"
+DO Verdict WITH loP6.recalculeaza_pret(121, .F.) == 100, "recalculeaza_pret(121,.F.) = 100 (obtinut " + TRANSFORM(loP6.recalculeaza_pret(121,.F.)) + ")"
+
+DO Final
+
+*==================================================================================================
+* Spion pe goExecutor - subclasa DODEFAULT pe PCOUNT (nu opreste executia), tiparul din
+* probe_12b_s7a_optiuni_readonly.prg. lForteazaEsecSalveaza=.T. intoarce -1 fara sa mai trimita
+* SQL-ul cand acesta contine 'salveaza_pret_nomenclator' (cazul 3) - restul trece prin DODEFAULT.
+*==================================================================================================
+DEFINE CLASS SpyS6b AS oexecutor
+ nApeluri = 0
+ cToateSql = ''
+ lForteazaEsecSalveaza = .F.
+
+ PROCEDURE oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect)
+ LOCAL lnRet, lnPc, lcS
+ THIS.nApeluri = THIS.nApeluri + 1
+ lcS = IIF(VARTYPE(m.tcSql) = 'C', m.tcSql, '')
+ THIS.cToateSql = THIS.cToateSql + lcS + CHR(13) + CHR(10)
+ STRTOFILE(' SpyS6b #' + TRANSFORM(THIS.nApeluri) + ' SQL=[' + lcS + ']' + CHR(13) + CHR(10), gcLog, 1)
+
+ IF THIS.lForteazaEsecSalveaza AND 'SALVEAZA_PRET_NOMENCLATOR' $ UPPER(lcS)
+ STRTOFILE(' SpyS6b: ESEC FORTAT (nu trimit SQL-ul de mai sus)' + CHR(13) + CHR(10), gcLog, 1)
+ RETURN -1
+ ENDIF
+
+ lnPc = PCOUNT()
+ DO CASE
+ CASE lnPc <= 1
+ lnRet = DODEFAULT(m.tcSql)
+ CASE lnPc = 2
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor)
+ CASE lnPc = 3
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress)
+ CASE lnPc = 4
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress)
+ CASE lnPc = 5
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle)
+ CASE lnPc = 6
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError)
+ CASE lnPc = 7
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError)
+ OTHERWISE
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError, m.tlReconnect)
+ ENDCASE
+ RETURN lnRet
+ ENDPROC
+ENDDEFINE
+
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk)
+ IF TYPE('gnTransOriginal') = 'N'
+ SQLSETPROP(gnHandle, "Transactions", gnTransOriginal)
+ ENDIF
+ DO AfLog WITH "TOTAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_12b_s6c_fisa_pagina_vanzare.prg b/utile/Teste/facturare_unificat/probe_12b_s6c_fisa_pagina_vanzare.prg
new file mode 100644
index 0000000..837ea03
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s6c_fisa_pagina_vanzare.prg
@@ -0,0 +1,785 @@
+* probe_12b_s6c_fisa_pagina_vanzare.prg
+* Plan #12b, S6c - proba headless pe frm_catalog_articole_nou (COMUN\clase\onom_articole.vc2:662),
+* Page3 "Vanzare" (docs\plan_12b_nomenclator_politica_stoc.md, sectiunea S6c).
+*
+* Partea 1 (fara scriere in Oracle, fara salvare), doua cazuri, in DOUA procese vfp9 separate -
+* Init() executa neconditionat (indiferent de gcNumeProgram) generatorul de coduri automate
+* (creeaza_cursor_serii); a doua instantiere a formularului in ACELASI proces se autobloca (nu
+* apuca sa arunce nicio eroare prinsa de TRY, nici dupa ROLLBACK intre cele doua CREATEOBJECT -
+* incercat si infirmat), deci fiecare caz porneste propriul vfp9, cu propriul gnHandle:
+* (0a) implicit, fara parametru - CREATEOBJECT sub gcNumeProgram=ROAFACTURARE - trece (errno=0);
+* PageCount=3; Thisform.oPretNom instantiat (Vartype='O'); valorile incarcate in oPretNom
+* comparate cu un SELECT direct, independent de goExecutor, pe crm_politici_pret_art;
+* TabIndex pe cele 7 controale din Page3; recalculeaza_pret (ftva<->ctva) apelat prin
+* Thisform.oPretNom, cu proc_tvav real incarcat.
+* (0b) cu parametrul ROACONT - acelasi CREATEOBJECT sub gcNumeProgram=ROACONT - trece (errno=0);
+* PageCount=2; Thisform.oPretNom NU e instantiat (Vartype<>'O').
+*
+* Partea 2 (scrie in Oracle, tot in tranzactie/ROLLBACK), patru cazuri, fiecare in procesul lui
+* propriu (acelasi motiv ca la partea 1 - o singura instantiere a formularului per proces).
+* Salvarea headless NU trece prin inainte_de_do_termin() (onom_articole.vc2:1777) - confirmat cu
+* un script de diagnostic: This.ActiveControl.BaseClass (linia 1782, primul rand al metodei)
+* arunca ERROR 1924 "ACTIVECONTROL is not an object" pe un formular niciodata Show(), deci fara
+* focus real de fereastra (masina partajata - nu se face Show()). In loc, proba apeleaza direct,
+* in aceeasi ordine ca in productie, metodele reale de salvare pe care inainte_de_do_termin le
+* orchestreaza (onom_articole.vc2:1799-1840): Thisform.do_deschide_tranzactie(),
+* Thisform.cus_odata_catalog_articole.salvare(Thisform.orec, Thisform.NID) (cu lSilent=.T., ca sa
+* sara peste dialogul modal de confirmare - _cus_odata_base.vc2:126-130), apoi
+* Thisform.oPretNom.salveaza(idArticol) (COMUN\programe\ofacturare_comun.prg:2487).
+* Diferenta fata de fluxul real: pe cazurile de succes (CAZ1/CAZ2) proba NU cheama
+* Thisform.do_inchide_tranzactie(1) - acela face un SQLCOMMIT() real, ireversibil, pe schema de
+* test; verificarea se face prin SELECT in aceeasi tranzactie manuala, apoi un ROLLBACK direct
+* (nu wrapper-ul de productie). Pe CAZ3 (esec fortat), do_inchide_tranzactie(2) chiar se cheama -
+* acela face SQLROLLBACK(), sigur de rulat real, exact cum cere sarcina.
+* (CAZ1) articol NOU (INSERT), pret/TVA/conturi (461/7583) setate pe Page3 (Thisform.oPretNom) ->
+* dupa salvare, randul din crm_politici_pret_art exista in Oracle (in tranzactie) cu
+* valorile puse de proba, id_nota alocat; apoi ROLLBACK direct, zero date ramase.
+* (CAZ2) articolul de proba (2528841557, UPDATE) cu pret/TVA/conturi noi pe Page3 -> randul din
+* crm_politici_pret_art actualizat in Oracle (in tranzactie); apoi ROLLBACK direct.
+* (CAZ3) articol NOU (INSERT) - articolul se salveaza real, apoi salvarea randului de pret e
+* fortata sa esueze cu un spion pe goExecutor (subclasa oexecutor, filtreaza SQL-ul care
+* contine 'salveaza_pret_nomenclator', fara modificare de productie - tiparul SpyS6b din
+* probe_12b_s6b_clasa_pret_nomenclator.prg) -> Thisform.do_inchide_tranzactie(2) (ROLLBACK
+* real) -> articolul nou nu mai exista.
+* (CAZ4) regresie garda NULL (onom_articole.vc2:88, S6c-4) - articol NOU (INSERT) cu
+* id_tara_origine fortat NULL -> cus_odata_catalog_articole.salvare() trebuie sa construiasca
+* un SQL real (nu This.csql NULL) si sa scrie efectiv in Oracle; verificat direct dupa
+* codmat (id_tara_origine ramas NULL), apoi ROLLBACK direct. Inainte de reparatie, csql
+* devenea NULL si salvare() intorcea .T. fara nicio scriere (defect de productie #1).
+* (CAZ5) regresie S6c-5 (_cus_odata_base.vc2:150-181) - subclasa LOCALA proba
+* (cus_odata_vid_s6c5 AS cus_odata_catalog_articole, make_sql suprascris gol, fara nicio
+* modificare de productie) forteaza This.csql gol -> salvare() trebuie sa intoarca .F.
+* (inainte de reparatie intorcea .T. fara sa trimita niciun SQL - defect de productie #2).
+* Nu scrie in Oracle (verificat prin spion pe goExecutor, 0 apeluri).
+* Manual, ramane datorie deschisa (nu se automatizeaza): aspectul paginii si fluxul real
+* "articol nou -> factura"; fisa deschisa din NIR si din importul e-Factura.
+*
+* Articol de proba: 2528841557, pe politica 41 (tiparul S5/S5b/S6b).
+*
+* Rulare (0a): powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume probe_12b_s6c_fisa_pagina_vanzare
+* Rulare (0b): "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A -T probe_12b_s6c_fisa_pagina_vanzare.prg ROACONT
+* Rulare (CAZ1/CAZ2/CAZ3/CAZ4/CAZ5): "...\vfp9.exe" -A -T probe_12b_s6c_fisa_pagina_vanzare.prg CAZ1 (idem CAZ2, CAZ3, CAZ4, CAZ5)
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\s6c_fisa.log (cerut de sarcina, nu out\; fiecare
+* proces face APPEND peste rularile anterioare)
+
+PARAMETERS tcModo
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+LOCAL lcCazSel
+lcCazSel = UPPER(ALLTRIM(IIF(VARTYPE(tcModo) = "C", tcModo, "")))
+LOCAL llCazB
+llCazB = (lcCazSel == "ROACONT")
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s6c_fisa.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+DO CASE
+CASE llCazB
+ STRTOFILE("--- caz (0b), proces separat, START " + TTOC(DATETIME()) + " ---" + CHR(13) + CHR(10), gcLog, 1)
+CASE INLIST(lcCazSel, "CAZ1", "CAZ2", "CAZ3", "CAZ4", "CAZ5")
+ STRTOFILE("--- partea 2, caz (" + lcCazSel + "), proces separat, START " + TTOC(DATETIME()) + " ---" + CHR(13) + CHR(10), gcLog, 1)
+OTHERWISE
+ STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+ENDCASE
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+gnIdUtil = 8
+PUBLIC gnPc
+gnPc = 2
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle) + " gnPc=" + TRANSFORM(gnPc)
+
+* incarcare explicita din calea COMPLETA (tiparul S7a) - ofacturare.vcx inainte de onom_articole.vcx,
+* la fel ca la instalarea reala (roafacturare.prg incarca tot COMUN\CLASE la pornire)
+SET PATH TO (gcAppPath + "COMUN\CLASE") ADDITIVE
+SET CLASSLIB TO (gcAppPath + "COMUN\CLASE\ofacturare.vcx") ADDITIVE
+SET CLASSLIB TO (gcAppPath + "COMUN\CLASE\onom_articole.vcx") ADDITIVE
+DO AfLog WITH "SET CLASSLIB ofacturare + onom_articole OK (cale completa)"
+
+* precondition-urile pe care le face onomenclatoare.prg (nom_articole_modifica/nou) inainte sa
+* deschida fisa - fara ele Init() pica pe alias lipsa (crs_grupe_art / vnom_um_iso), independent
+* de continutul paginii Vanzare
+update_um()
+update_um_iso()
+update_grupe_art()
+update_subgrupe_art()
+DO AfLog WITH "preconditii onomenclatoare (update_um/update_um_iso/update_grupe_art/update_subgrupe_art) OK"
+
+LOCAL lnIdArtProba, lnOk, loRec
+lnIdArtProba = 2528841557
+gcCaz = "[precondition] "
+lnOk = SQLEXEC(gnHandle, "select count(*) cnt from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(lnIdArtProba), "crspre")
+DO Verdict WITH lnOk > 0 AND USED('crspre') AND crspre.cnt = 1, "articolul " + TRANSFORM(lnIdArtProba) + " e pe politica 41 (mod UPDATE)"
+IF USED('crspre')
+ USE IN crspre
+ENDIF
+
+lnOk = goExecutor.oExecuta('select * from vnom_articole where id_articol = ' + TRANSFORM(lnIdArtProba), 'vnom_articole_nou')
+DO Verdict WITH lnOk # .F. AND USED('vnom_articole_nou') AND RECCOUNT('vnom_articole_nou') = 1, "SELECT vnom_articole pentru articolul de proba"
+SELECT vnom_articole_nou
+SCATTER NAME loRec MEMO
+loRec.conditii_pastrare = NVL(loRec.conditii_pastrare,'')
+USE IN vnom_articole_nou
+
+PUBLIC gcNumeProgram
+
+DO CASE
+CASE !llCazB AND !INLIST(lcCazSel, "CAZ1", "CAZ2", "CAZ3", "CAZ4", "CAZ5")
+ *==========================================================================================
+ * CAZ (0a): CREATEOBJECT sub gcNumeProgram = ROAFACTURARE - trece, plus verificarile din plan
+ * care nu scriu in Oracle: PageCount, instantierea oPretNom, valorile incarcate, TabIndex,
+ * recalculeaza_pret
+ *==========================================================================================
+ * SELECT direct pe crm_politici_pret_art, PRIN SQLEXEC (fara goExecutor, deci independent de
+ * incarca()) - referinta pentru compararea valorilor incarcate in Thisform.oPretNom
+ LOCAL lnPretFtvaDirect, lnPretCtvaDirect, lnProcTvavDirect, lnIdVenchDirect, lnIdNotaDirect, llVenchNullDirect, llNotaNullDirect, llProcNullDirect
+ gcCaz = "[precondition] "
+ lnOk = SQLEXEC(gnHandle, "select pretftva, pretctva, proc_tvav, id_venchelt, id_nota from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(lnIdArtProba), "crsdirect")
+ DO Verdict WITH lnOk > 0 AND USED('crsdirect') AND RECCOUNT('crsdirect') = 1, "SELECT direct (SQLEXEC) pe crm_politici_pret_art, referinta pentru caz (0a)"
+ lnPretFtvaDirect = NVL(crsdirect.pretftva,0)
+ lnPretCtvaDirect = NVL(crsdirect.pretctva,0)
+ llProcNullDirect = ISNULL(crsdirect.proc_tvav)
+ lnProcTvavDirect = NVL(crsdirect.proc_tvav,-1)
+ llVenchNullDirect = ISNULL(crsdirect.id_venchelt)
+ lnIdVenchDirect = NVL(crsdirect.id_venchelt,-1)
+ llNotaNullDirect = ISNULL(crsdirect.id_nota)
+ lnIdNotaDirect = NVL(crsdirect.id_nota,-1)
+ IF USED('crsdirect')
+ USE IN crsdirect
+ ENDIF
+ DO AfLog WITH " referinta directa: pretftva=" + TRANSFORM(lnPretFtvaDirect) + " pretctva=" + TRANSFORM(lnPretCtvaDirect) + " proc_tvav=" + IIF(llProcNullDirect,"NULL",TRANSFORM(lnProcTvavDirect)) + " id_venchelt=" + IIF(llVenchNullDirect,"NULL",TRANSFORM(lnIdVenchDirect)) + " id_nota=" + IIF(llNotaNullDirect,"NULL",TRANSFORM(lnIdNotaDirect))
+
+ gcCaz = "[0a-createobject-ROAFACTURARE] "
+ gcNumeProgram = 'ROAFACTURARE'
+ PRIVATE poRec, pnIdAMS
+ poRec = loRec
+ pnIdAMS = lnIdArtProba
+
+ LOCAL loForm1, llCrapat1, lcErrMsg1, lnErrNo1
+ llCrapat1 = .F.
+ lcErrMsg1 = ''
+ lnErrNo1 = 0
+ TRY
+ loForm1 = CREATEOBJECT('frm_catalog_articole_nou', loRec, lnIdArtProba, 'UPDATE')
+ CATCH TO loExc1
+ llCrapat1 = .T.
+ lnErrNo1 = loExc1.ErrorNo
+ lcErrMsg1 = loExc1.Message
+ ENDTRY
+ DO AfLog WITH " rezultat: llCrapat=" + TRANSFORM(llCrapat1) + " errno=" + TRANSFORM(lnErrNo1) + " mesaj=[" + lcErrMsg1 + "]"
+ DO Verdict WITH !llCrapat1 AND lnErrNo1 = 0, "CREATEOBJECT trece sub gcNumeProgram=ROAFACTURARE (errno=0)"
+
+ IF !llCrapat1
+ DO Verdict WITH loForm1._pageframe1.PageCount = 3, "PageCount = 3 (Page3 Vanzare vizibila, obtinut " + TRANSFORM(loForm1._pageframe1.PageCount) + ")"
+ DO Verdict WITH VARTYPE(loForm1.oPretNom) = "O", "Thisform.oPretNom instantiat (Vartype=" + VARTYPE(loForm1.oPretNom) + ")"
+
+ IF VARTYPE(loForm1.oPretNom) = "O"
+ gcCaz = "[0a-valori-opretnom] "
+ DO Verdict WITH loForm1.oPretNom.nPretFtva == lnPretFtvaDirect, "oPretNom.nPretFtva = " + TRANSFORM(lnPretFtvaDirect) + " (obtinut " + TRANSFORM(loForm1.oPretNom.nPretFtva) + ")"
+ DO Verdict WITH loForm1.oPretNom.nPretCtva == lnPretCtvaDirect, "oPretNom.nPretCtva = " + TRANSFORM(lnPretCtvaDirect) + " (obtinut " + TRANSFORM(loForm1.oPretNom.nPretCtva) + ")"
+ DO Verdict WITH IIF(llProcNullDirect, ISNULL(loForm1.oPretNom.nProcTvav), loForm1.oPretNom.nProcTvav == lnProcTvavDirect), "oPretNom.nProcTvav = " + IIF(llProcNullDirect,"NULL",TRANSFORM(lnProcTvavDirect)) + " (obtinut " + IIF(ISNULL(loForm1.oPretNom.nProcTvav),"NULL",TRANSFORM(loForm1.oPretNom.nProcTvav)) + ")"
+ DO Verdict WITH IIF(llVenchNullDirect, ISNULL(loForm1.oPretNom.nIdVenchelt), loForm1.oPretNom.nIdVenchelt == lnIdVenchDirect), "oPretNom.nIdVenchelt = " + IIF(llVenchNullDirect,"NULL",TRANSFORM(lnIdVenchDirect)) + " (obtinut " + IIF(ISNULL(loForm1.oPretNom.nIdVenchelt),"NULL",TRANSFORM(loForm1.oPretNom.nIdVenchelt)) + ")"
+ DO Verdict WITH IIF(llNotaNullDirect, ISNULL(loForm1.oPretNom.nIdNota), loForm1.oPretNom.nIdNota == lnIdNotaDirect), "oPretNom.nIdNota = " + IIF(llNotaNullDirect,"NULL",TRANSFORM(lnIdNotaDirect)) + " (obtinut " + IIF(ISNULL(loForm1.oPretNom.nIdNota),"NULL",TRANSFORM(loForm1.oPretNom.nIdNota)) + ")"
+
+ gcCaz = "[0a-tabindex-page3] "
+ DO Verdict WITH loForm1._pageframe1.Page3.Clb_tx_pret_ftva.TabIndex = 1, "TabIndex Clb_tx_pret_ftva = 1"
+ DO Verdict WITH loForm1._pageframe1.Page3.Clb_tx_pret_ctva.TabIndex = 2, "TabIndex Clb_tx_pret_ctva = 2"
+ DO Verdict WITH loForm1._pageframe1.Page3.Cb_tx_proc_tvav.TabIndex = 3, "TabIndex Cb_tx_proc_tvav = 3"
+ DO Verdict WITH loForm1._pageframe1.Page3.Cb_tx_venit.TabIndex = 4, "TabIndex Cb_tx_venit = 4"
+ DO Verdict WITH loForm1._pageframe1.Page3.Clb_tx_scd.TabIndex = 5, "TabIndex Clb_tx_scd = 5"
+ DO Verdict WITH loForm1._pageframe1.Page3.Clb_tx_scc.TabIndex = 6, "TabIndex Clb_tx_scc = 6"
+ DO Verdict WITH loForm1._pageframe1.Page3.Clb_tx_cont_dedus.TabIndex = 7, "TabIndex Clb_tx_cont_dedus = 7"
+
+ gcCaz = "[0a-recalculeaza-pret] "
+ LOCAL lnFtvaTest, lnCtvaCalc, lnFtvaInapoi, lnCoefEfectiv
+ lnFtvaTest = 100
+ lnCoefEfectiv = IIF(ISNULL(loForm1.oPretNom.nProcTvav), (GetProcTvaStandard()+100)/100, loForm1.oPretNom.nProcTvav)
+ lnCtvaCalc = loForm1.oPretNom.recalculeaza_pret(lnFtvaTest, .T.)
+ lnFtvaInapoi = loForm1.oPretNom.recalculeaza_pret(lnCtvaCalc, .F.)
+ DO AfLog WITH " recalculeaza_pret: proc_tvav efectiv=" + TRANSFORM(lnCoefEfectiv) + " 100->" + TRANSFORM(lnCtvaCalc) + "->" + TRANSFORM(lnFtvaInapoi)
+ DO Verdict WITH lnCtvaCalc == ROUND(lnFtvaTest * lnCoefEfectiv, gnPc), "recalculeaza_pret(100,.T.) = 100 * proc_tvav efectiv rotunjit (obtinut " + TRANSFORM(lnCtvaCalc) + ")"
+ DO Verdict WITH lnFtvaInapoi == lnFtvaTest, "recalculeaza_pret(recalculeaza_pret(100,.T.),.F.) = 100 (reciproc, obtinut " + TRANSFORM(lnFtvaInapoi) + ")"
+ ENDIF
+
+ RELEASE loForm1
+ ENDIF
+
+ DO AfLog WITH " caz (0b) ruleaza intr-un proces vfp9 separat (vezi antetul fisierului) - reentranta"
+ DO AfLog WITH " CREATEOBJECT('frm_catalog_articole_nou') in acelasi proces se autoblocheaza."
+CASE llCazB
+ *==========================================================================================
+ * CAZ (0b): CREATEOBJECT sub gcNumeProgram = ROACONT (proces separat de (0a)) - trece
+ * (errno=0), Page3 invizibila (PageCount=2) si oPretNom NEinstantiat, dovada ca defectul
+ * original (ERROR 1736) nu revine si ca ramura gcNumeProgram din Init izoleaza corect
+ * celelalte produse
+ *==========================================================================================
+ gcCaz = "[0b-createobject-ROACONT] "
+ gcNumeProgram = 'ROACONT'
+ PRIVATE poRec, pnIdAMS
+ poRec = loRec
+ pnIdAMS = lnIdArtProba
+
+ LOCAL loForm2, llCrapat2, lcErrMsg2, lnErrNo2
+ llCrapat2 = .F.
+ lcErrMsg2 = ''
+ lnErrNo2 = 0
+ TRY
+ loForm2 = CREATEOBJECT('frm_catalog_articole_nou', loRec, lnIdArtProba, 'UPDATE')
+ CATCH TO loExc2
+ llCrapat2 = .T.
+ lnErrNo2 = loExc2.ErrorNo
+ lcErrMsg2 = loExc2.Message
+ ENDTRY
+ DO AfLog WITH " rezultat: llCrapat=" + TRANSFORM(llCrapat2) + " errno=" + TRANSFORM(lnErrNo2) + " mesaj=[" + lcErrMsg2 + "]"
+ DO Verdict WITH !llCrapat2 AND lnErrNo2 = 0, "CREATEOBJECT trece sub gcNumeProgram=ROACONT (errno=0)"
+
+ IF !llCrapat2
+ DO Verdict WITH loForm2._pageframe1.PageCount = 2, "PageCount = 2 (Page3 Vanzare invizibila, obtinut " + TRANSFORM(loForm2._pageframe1.PageCount) + ")"
+ DO Verdict WITH VARTYPE(loForm2.oPretNom) <> "O", "Thisform.oPretNom NEinstantiat sub ROACONT (Vartype=" + VARTYPE(loForm2.oPretNom) + ")"
+ RELEASE loForm2
+ ENDIF
+
+ DO AfLog WITH ""
+ DO AfLog WITH " Partea 2 (INSERT/UPDATE la salvare, cu scriere in Oracle) - cazurile CAZ1/CAZ2/CAZ3"
+ DO AfLog WITH " ale acestui fisier, fiecare in procesul lui propriu (vezi antetul fisierului)."
+
+*=================================================================================================
+* CAZ (1): articol NOU (INSERT) - pret/TVA/conturi setate pe Page3 (Thisform.oPretNom), salvat prin
+* metodele reale de salvare (nu inainte_de_do_termin, vezi antetul); dupa salvare, verificat direct
+* din Oracle, in aceeasi tranzactie manuala, apoi ROLLBACK direct (nu do_inchide_tranzactie(1) -
+* ala ar comite real)
+*=================================================================================================
+CASE lcCazSel == "CAZ1"
+ gcCaz = "[1-articol-nou-page3-vanzare] "
+ gcNumeProgram = 'ROAFACTURARE'
+
+ LOCAL lcCodMat1
+ lcCodMat1 = "PS6C2B1" + SYS(2015)
+ loRec.codmat = lcCodMat1
+ loRec.codmatf = lcCodMat1
+ loRec.denumire = "PROBA S6C2B ARTICOL NOU CAZ1"
+ loRec.codbare = ""
+ * articolul de proba (2528841557) are id_tara_origine NULL - make_sql (onom_articole.vc2:88,
+ * ramura INSERT) NU garzeste NULL-ul (spre deosebire de ramura UPDATE, linia 100), deci
+ * This.csql devine NULL (propagare NULL in concatenare) si salvare() raporteaza .T. fara sa
+ * trimita vreun SQL - defect de productie, NEREPARAT; proba isi alege un id_tara_origine
+ * valid (dintr-un articol real) ca sa poata testa ce i s-a cerut (pret/TVA/ID_NOTA pe Page3)
+ LOCAL lnOkTara1, lnTaraOrigine1
+ lnTaraOrigine1 = 0
+ lnOkTara1 = SQLEXEC(gnHandle, "select id_tara_origine from vnom_articole where id_tara_origine is not null and rownum = 1", "crstara1")
+ IF lnOkTara1 > 0 AND USED('crstara1') AND RECCOUNT('crstara1') = 1
+ lnTaraOrigine1 = crstara1.id_tara_origine
+ ENDIF
+ IF USED('crstara1')
+ USE IN crstara1
+ ENDIF
+ IF lnTaraOrigine1 > 0
+ loRec.id_tara_origine = lnTaraOrigine1
+ ENDIF
+
+ PRIVATE poRec, pnIdAMS
+ poRec = loRec
+ pnIdAMS = 0
+
+ LOCAL loForm1, llCrapat1, lcErrMsg1, lnErrNo1
+ llCrapat1 = .F.
+ lcErrMsg1 = ''
+ lnErrNo1 = 0
+ TRY
+ loForm1 = CREATEOBJECT('frm_catalog_articole_nou', loRec, 0, 'INSERT')
+ CATCH TO loExc1
+ llCrapat1 = .T.
+ lnErrNo1 = loExc1.ErrorNo
+ lcErrMsg1 = loExc1.Message
+ ENDTRY
+ DO AfLog WITH " rezultat CREATEOBJECT: llCrapat=" + TRANSFORM(llCrapat1) + " errno=" + TRANSFORM(lnErrNo1) + " mesaj=[" + lcErrMsg1 + "]"
+ DO Verdict WITH !llCrapat1 AND VARTYPE(loForm1) = "O", "CREATEOBJECT('frm_catalog_articole_nou',...,'INSERT') trece (errno=0)"
+
+ IF !llCrapat1
+ DO Verdict WITH VARTYPE(loForm1.oPretNom) = "O", "oPretNom instantiat pe formularul de INSERT"
+
+ IF VARTYPE(loForm1.oPretNom) = "O"
+ LOCAL lnPretFtvaNou, lnProcTvavNou, lnPretCtvaNou
+ lnPretFtvaNou = 55.55
+ lnProcTvavNou = 1.19
+ lnPretCtvaNou = loForm1.oPretNom.recalculeaza_pret(lnPretFtvaNou, .T.)
+ loForm1.oPretNom.nPretFtva = lnPretFtvaNou
+ loForm1.oPretNom.nProcTvav = lnProcTvavNou
+ loForm1.oPretNom.nPretCtva = lnPretCtvaNou
+ loForm1.oPretNom.cScd = '461'
+ loForm1.oPretNom.cScc = '7583'
+
+ loForm1.cus_odata_catalog_articole.lSilent = .T.
+ DO Verdict WITH loForm1.do_deschide_tranzactie(), "do_deschide_tranzactie() = .T."
+
+ DO AfLog WITH " diagnostic: lSilent=" + TRANSFORM(loForm1.cus_odata_catalog_articole.lSilent) + " cactiune=[" + loForm1.cus_odata_catalog_articole.cactiune + "] validare()=" + TRANSFORM(loForm1.cus_odata_catalog_articole.validare()) + " TYPE(orec)=" + TYPE('loForm1.orec') + " TYPE(NID)=" + TYPE('loForm1.NID')
+
+ * spion NEUTRU (nu forteaza esec) doar ca sa vada proba exact ce SQL a trimis (sau nu)
+ * cus_odata_catalog_articole.salvare() prin goExecutor - diagnostic, nu modifica fluxul
+ LOCAL loRealExec1, loSpy1
+ loRealExec1 = goExecutor
+ loSpy1 = CREATEOBJECT('SpyS6c2b')
+ goExecutor = loSpy1
+
+ LOCAL llSalvatArticol1
+ llSalvatArticol1 = loForm1.cus_odata_catalog_articole.salvare(loForm1.orec, loForm1.NID)
+ goExecutor = loRealExec1
+ DO AfLog WITH " diagnostic: dupa salvare() lsalvareconfirmata=" + TRANSFORM(loForm1.cus_odata_catalog_articole.lsalvareconfirmata) + " VARTYPE(csql)=" + VARTYPE(loForm1.cus_odata_catalog_articole.csql) + " csql=[" + TRANSFORM(loForm1.cus_odata_catalog_articole.csql) + "]"
+ DO AfLog WITH " diagnostic: SpyS6c2b apeluri=" + TRANSFORM(loSpy1.nApeluri)
+ DO Verdict WITH llSalvatArticol1, "cus_odata_catalog_articole.salvare() INSERT = .T. (codmat=" + lcCodMat1 + ")"
+
+ * pnIdAMS (OUT bind ?@pnIdAMS din make_sql) a ramas 0 dupa un INSERT confirmat reusit -
+ * id-ul real se ia din Oracle, dupa codmat (unic, generat mai sus), nu din pnIdAMS
+ DO AfLog WITH " info: pnIdAMS dupa INSERT=" + TRANSFORM(NVL(pnIdAMS,-1)) + " (neconcludent, vezi cautarea dupa codmat mai jos)"
+ LOCAL lnIdArtNou1, lnOkIdNou1
+ lnIdArtNou1 = 0
+ lnOkIdNou1 = SQLEXEC(gnHandle, "select id_articol from vnom_articole where codmat = '" + lcCodMat1 + "'", "crsidnou1")
+ IF lnOkIdNou1 > 0 AND USED('crsidnou1') AND RECCOUNT('crsidnou1') = 1
+ lnIdArtNou1 = crsidnou1.id_articol
+ ENDIF
+ IF USED('crsidnou1')
+ USE IN crsidnou1
+ ENDIF
+ DO AfLog WITH " id articol nou (cautat dupa codmat)=" + TRANSFORM(lnIdArtNou1)
+ DO Verdict WITH lnIdArtNou1 > 0, "articolul nou gasit dupa codmat, id_articol > 0 (obtinut " + TRANSFORM(lnIdArtNou1) + ")"
+
+ LOCAL llSalvatPret1
+ llSalvatPret1 = .F.
+ IF lnIdArtNou1 > 0
+ llSalvatPret1 = loForm1.oPretNom.salveaza(lnIdArtNou1)
+ ENDIF
+ DO Verdict WITH llSalvatPret1, "oPretNom.salveaza() = .T. (articol nou)"
+
+ LOCAL lnOkAnyPol1
+ lnOkAnyPol1 = SQLEXEC(gnHandle, "select id_pol, pretftva, pretctva, proc_tvav, id_nota from crm_politici_pret_art where id_articol = " + TRANSFORM(lnIdArtNou1), "crsanypol1")
+ DO AfLog WITH " diagnostic: randuri crm_politici_pret_art (orice id_pol) pentru articolul nou=" + TRANSFORM(IIF(lnOkAnyPol1>0 AND USED('crsanypol1'),RECCOUNT('crsanypol1'),-1)) + " nIdPolitica(oPretNom)=" + TRANSFORM(loForm1.oPretNom.nIdPolitica)
+ IF USED('crsanypol1')
+ SELECT crsanypol1
+ SCAN
+ DO AfLog WITH " id_pol=" + TRANSFORM(crsanypol1.id_pol) + " pretftva=" + TRANSFORM(crsanypol1.pretftva) + " id_nota=" + TRANSFORM(NVL(crsanypol1.id_nota,-1))
+ ENDSCAN
+ USE IN crsanypol1
+ ENDIF
+
+ LOCAL lnOkSel1
+ lnOkSel1 = SQLEXEC(gnHandle, "select pretftva, pretctva, proc_tvav, id_nota from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(lnIdArtNou1), "crscaz1")
+ DO Verdict WITH lnOkSel1 > 0 AND USED('crscaz1') AND RECCOUNT('crscaz1') = 1, "randul politicii de pret exista in Oracle pentru articolul nou (in tranzactie)"
+ IF USED('crscaz1') AND RECCOUNT('crscaz1') = 1
+ DO Verdict WITH ROUND(crscaz1.pretftva,2) == lnPretFtvaNou, "Oracle pretftva=" + TRANSFORM(lnPretFtvaNou) + " (obtinut " + TRANSFORM(crscaz1.pretftva) + ")"
+ DO Verdict WITH ROUND(crscaz1.pretctva,2) == lnPretCtvaNou, "Oracle pretctva=" + TRANSFORM(lnPretCtvaNou) + " (obtinut " + TRANSFORM(crscaz1.pretctva) + ")"
+ DO Verdict WITH ROUND(crscaz1.proc_tvav,2) == lnProcTvavNou, "Oracle proc_tvav=" + TRANSFORM(lnProcTvavNou) + " (obtinut " + TRANSFORM(crscaz1.proc_tvav) + ")"
+ DO Verdict WITH !ISNULL(crscaz1.id_nota) AND crscaz1.id_nota > 0, "Oracle id_nota atribuit (" + TRANSFORM(NVL(crscaz1.id_nota,-1)) + ")"
+ ENDIF
+ IF USED('crscaz1')
+ USE IN crscaz1
+ ENDIF
+
+ LOCAL lnOkArt1
+ lnOkArt1 = SQLEXEC(gnHandle, "select count(*) cnt from vnom_articole where id_articol = " + TRANSFORM(lnIdArtNou1), "crsart1")
+ DO Verdict WITH lnOkArt1 > 0 AND USED('crsart1') AND crsart1.cnt = 1, "articolul nou exista in vnom_articole (in tranzactie)"
+ IF USED('crsart1')
+ USE IN crsart1
+ ENDIF
+
+ * fara Thisform.do_inchide_tranzactie(1) - ar face SQLCOMMIT() real; ROLLBACK direct
+ * dupa verificare, ca sa nu ramana date (cerinta explicita a sarcinii)
+ LOCAL lnOkRb1
+ lnOkRb1 = SQLEXEC(gnHandle, "ROLLBACK")
+ DO Verdict WITH lnOkRb1 > 0, "ROLLBACK direct dupa verificare (nu do_inchide_tranzactie(1))"
+ SQLSETPROP(gnHandle, "Transactions", 1)
+ ENDIF
+
+ RELEASE loForm1
+ ENDIF
+
+*=================================================================================================
+* CAZ (2): articolul de proba (existent, UPDATE) - pret/TVA/conturi noi pe Page3 -> randul din
+* crm_politici_pret_art actualizat in Oracle (in tranzactie), apoi ROLLBACK direct
+*=================================================================================================
+CASE lcCazSel == "CAZ2"
+ gcCaz = "[2-articol-existent-page3-modificat] "
+ gcNumeProgram = 'ROAFACTURARE'
+
+ PRIVATE poRec, pnIdAMS
+ poRec = loRec
+ pnIdAMS = lnIdArtProba
+
+ LOCAL loForm2, llCrapat2, lcErrMsg2, lnErrNo2
+ llCrapat2 = .F.
+ lcErrMsg2 = ''
+ lnErrNo2 = 0
+ TRY
+ loForm2 = CREATEOBJECT('frm_catalog_articole_nou', loRec, lnIdArtProba, 'UPDATE')
+ CATCH TO loExc2b
+ llCrapat2 = .T.
+ lnErrNo2 = loExc2b.ErrorNo
+ lcErrMsg2 = loExc2b.Message
+ ENDTRY
+ DO AfLog WITH " rezultat CREATEOBJECT: llCrapat=" + TRANSFORM(llCrapat2) + " errno=" + TRANSFORM(lnErrNo2) + " mesaj=[" + lcErrMsg2 + "]"
+ DO Verdict WITH !llCrapat2 AND VARTYPE(loForm2) = "O", "CREATEOBJECT('frm_catalog_articole_nou',...,'UPDATE') trece (errno=0)"
+
+ IF !llCrapat2
+ DO Verdict WITH VARTYPE(loForm2.oPretNom) = "O", "oPretNom instantiat pe formularul de UPDATE"
+
+ IF VARTYPE(loForm2.oPretNom) = "O"
+ LOCAL lnPretFtvaMod, lnProcTvavMod, lnPretCtvaMod
+ lnPretFtvaMod = 77.70
+ lnProcTvavMod = 1.09
+ lnPretCtvaMod = loForm2.oPretNom.recalculeaza_pret(lnPretFtvaMod, .T.)
+ loForm2.oPretNom.nPretFtva = lnPretFtvaMod
+ loForm2.oPretNom.nProcTvav = lnProcTvavMod
+ loForm2.oPretNom.nPretCtva = lnPretCtvaMod
+ loForm2.oPretNom.cScd = '461'
+ loForm2.oPretNom.cScc = '7583'
+
+ loForm2.cus_odata_catalog_articole.lSilent = .T.
+ DO Verdict WITH loForm2.do_deschide_tranzactie(), "do_deschide_tranzactie() = .T."
+
+ LOCAL llSalvatArticol2
+ llSalvatArticol2 = loForm2.cus_odata_catalog_articole.salvare(loForm2.orec, loForm2.NID)
+ DO Verdict WITH llSalvatArticol2, "cus_odata_catalog_articole.salvare() UPDATE = .T."
+
+ DO AfLog WITH " diagnostic: inainte de salveaza() nIdPolitica=" + TRANSFORM(loForm2.oPretNom.nIdPolitica) + " nPretFtva=" + TRANSFORM(loForm2.oPretNom.nPretFtva) + " nProcTvav=" + TRANSFORM(loForm2.oPretNom.nProcTvav) + " lIncarcat=" + TRANSFORM(loForm2.oPretNom.lIncarcat)
+ LOCAL loRealExec2, loSpy2
+ loRealExec2 = goExecutor
+ loSpy2 = CREATEOBJECT('SpyS6c2b')
+ goExecutor = loSpy2
+ LOCAL llSalvatPret2
+ llSalvatPret2 = loForm2.oPretNom.salveaza(lnIdArtProba)
+ goExecutor = loRealExec2
+ DO AfLog WITH " diagnostic: dupa salveaza() nPretFtva=" + TRANSFORM(loForm2.oPretNom.nPretFtva) + " nIdNota=" + TRANSFORM(NVL(loForm2.oPretNom.nIdNota,-1))
+ DO Verdict WITH llSalvatPret2, "oPretNom.salveaza() = .T. (articol existent " + TRANSFORM(lnIdArtProba) + ")"
+
+ LOCAL lnOkSel2
+ lnOkSel2 = SQLEXEC(gnHandle, "select pretftva, pretctva, proc_tvav, id_nota from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(lnIdArtProba), "crscaz2")
+ DO Verdict WITH lnOkSel2 > 0 AND USED('crscaz2') AND RECCOUNT('crscaz2') = 1, "randul politicii de pret exista in Oracle pentru articolul modificat (in tranzactie)"
+ IF USED('crscaz2') AND RECCOUNT('crscaz2') = 1
+ DO Verdict WITH ROUND(crscaz2.pretftva,2) == lnPretFtvaMod, "Oracle pretftva=" + TRANSFORM(lnPretFtvaMod) + " (obtinut " + TRANSFORM(crscaz2.pretftva) + ")"
+ DO Verdict WITH ROUND(crscaz2.pretctva,2) == lnPretCtvaMod, "Oracle pretctva=" + TRANSFORM(lnPretCtvaMod) + " (obtinut " + TRANSFORM(crscaz2.pretctva) + ")"
+ DO Verdict WITH ROUND(crscaz2.proc_tvav,2) == lnProcTvavMod, "Oracle proc_tvav=" + TRANSFORM(lnProcTvavMod) + " (obtinut " + TRANSFORM(crscaz2.proc_tvav) + ")"
+ DO Verdict WITH !ISNULL(crscaz2.id_nota) AND crscaz2.id_nota > 0, "Oracle id_nota atribuit (" + TRANSFORM(NVL(crscaz2.id_nota,-1)) + ")"
+ ENDIF
+ IF USED('crscaz2')
+ USE IN crscaz2
+ ENDIF
+
+ LOCAL lnOkRb2
+ lnOkRb2 = SQLEXEC(gnHandle, "ROLLBACK")
+ DO Verdict WITH lnOkRb2 > 0, "ROLLBACK direct dupa verificare (articolul existent ramane cu valorile originale)"
+ SQLSETPROP(gnHandle, "Transactions", 1)
+ ENDIF
+
+ RELEASE loForm2
+ ENDIF
+
+*=================================================================================================
+* CAZ (3): articol NOU (INSERT) - articolul se salveaza real, apoi salvarea randului de pret e
+* fortata sa esueze cu un spion pe goExecutor (subclasa oexecutor, tiparul SpyS6b din
+* probe_12b_s6b_clasa_pret_nomenclator.prg, fara nicio modificare de productie) -> flux real:
+* Thisform.do_inchide_tranzactie(2) - ROLLBACK real - articolul nou nu mai exista
+*=================================================================================================
+CASE lcCazSel == "CAZ3"
+ gcCaz = "[3-esec-salvare-pret-articol-nou] "
+ gcNumeProgram = 'ROAFACTURARE'
+
+ LOCAL lcCodMat3
+ lcCodMat3 = "PS6C2B3" + SYS(2015)
+ loRec.codmat = lcCodMat3
+ loRec.codmatf = lcCodMat3
+ loRec.denumire = "PROBA S6C2B ARTICOL NOU CAZ3 ESEC"
+ loRec.codbare = ""
+ * vezi nota din CAZ1 - id_tara_origine NULL blocheaza INSERT-ul (defect de productie, NEREPARAT)
+ LOCAL lnOkTara3, lnTaraOrigine3
+ lnTaraOrigine3 = 0
+ lnOkTara3 = SQLEXEC(gnHandle, "select id_tara_origine from vnom_articole where id_tara_origine is not null and rownum = 1", "crstara3")
+ IF lnOkTara3 > 0 AND USED('crstara3') AND RECCOUNT('crstara3') = 1
+ lnTaraOrigine3 = crstara3.id_tara_origine
+ ENDIF
+ IF USED('crstara3')
+ USE IN crstara3
+ ENDIF
+ IF lnTaraOrigine3 > 0
+ loRec.id_tara_origine = lnTaraOrigine3
+ ENDIF
+
+ PRIVATE poRec, pnIdAMS
+ poRec = loRec
+ pnIdAMS = 0
+
+ LOCAL loForm3, llCrapat3, lcErrMsg3, lnErrNo3
+ llCrapat3 = .F.
+ lcErrMsg3 = ''
+ lnErrNo3 = 0
+ TRY
+ loForm3 = CREATEOBJECT('frm_catalog_articole_nou', loRec, 0, 'INSERT')
+ CATCH TO loExc3
+ llCrapat3 = .T.
+ lnErrNo3 = loExc3.ErrorNo
+ lcErrMsg3 = loExc3.Message
+ ENDTRY
+ DO AfLog WITH " rezultat CREATEOBJECT: llCrapat=" + TRANSFORM(llCrapat3) + " errno=" + TRANSFORM(lnErrNo3) + " mesaj=[" + lcErrMsg3 + "]"
+ DO Verdict WITH !llCrapat3 AND VARTYPE(loForm3) = "O", "CREATEOBJECT('frm_catalog_articole_nou',...,'INSERT') trece (errno=0, caz3)"
+
+ IF !llCrapat3 AND VARTYPE(loForm3.oPretNom) = "O"
+ loForm3.oPretNom.nPretFtva = 33.33
+ loForm3.oPretNom.nProcTvav = 1.19
+ loForm3.oPretNom.nPretCtva = loForm3.oPretNom.recalculeaza_pret(33.33, .T.)
+ * conturi goale - fortarea esecului tinteste doar salveaza_pret_nomenclator, nu nota
+ loForm3.oPretNom.cScd = ''
+ loForm3.oPretNom.cScc = ''
+
+ loForm3.cus_odata_catalog_articole.lSilent = .T.
+ DO Verdict WITH loForm3.do_deschide_tranzactie(), "do_deschide_tranzactie() = .T. (caz3)"
+
+ LOCAL llSalvatArticol3
+ llSalvatArticol3 = loForm3.cus_odata_catalog_articole.salvare(loForm3.orec, loForm3.NID)
+ DO Verdict WITH llSalvatArticol3, "cus_odata_catalog_articole.salvare() INSERT = .T. (articolul e creat inainte de esecul pe pret)"
+
+ * id-ul se cauta dupa codmat (unic), nu din pnIdAMS - vezi nota din CAZ1
+ LOCAL lnIdArtNou3, lnOkIdNou3
+ lnIdArtNou3 = 0
+ lnOkIdNou3 = SQLEXEC(gnHandle, "select id_articol from vnom_articole where codmat = '" + lcCodMat3 + "'", "crsidnou3")
+ IF lnOkIdNou3 > 0 AND USED('crsidnou3') AND RECCOUNT('crsidnou3') = 1
+ lnIdArtNou3 = crsidnou3.id_articol
+ ENDIF
+ IF USED('crsidnou3')
+ USE IN crsidnou3
+ ENDIF
+ DO AfLog WITH " id articol nou caz3 (cautat dupa codmat)=" + TRANSFORM(lnIdArtNou3)
+ DO Verdict WITH lnIdArtNou3 > 0, "articolul nou gasit dupa codmat, id_articol > 0 (caz3, obtinut " + TRANSFORM(lnIdArtNou3) + ")"
+
+ LOCAL loRealExec3, loSpy3
+ loRealExec3 = goExecutor
+ loSpy3 = CREATEOBJECT('SpyS6c2b')
+ loSpy3.lForteazaEsecSalveaza = .T.
+ goExecutor = loSpy3
+
+ LOCAL llSalvatPret3
+ llSalvatPret3 = .F.
+ IF lnIdArtNou3 > 0
+ llSalvatPret3 = loForm3.oPretNom.salveaza(lnIdArtNou3)
+ ENDIF
+ goExecutor = loRealExec3
+ DO Verdict WITH !llSalvatPret3, "oPretNom.salveaza() = .F. (salveaza_pret_nomenclator interceptat/fortat sa esueze)"
+
+ * flux real: llReturn=.F. -> Thisform.do_inchide_tranzactie(2) - SQLROLLBACK() real, sigur
+ LOCAL llInchis3
+ llInchis3 = loForm3.do_inchide_tranzactie(IIF(llSalvatPret3, 1, 2))
+ DO Verdict WITH llInchis3, "do_inchide_tranzactie(2) = .T. (ROLLBACK real, tnTip=2)"
+
+ IF lnIdArtNou3 > 0
+ LOCAL lnOkArt3
+ lnOkArt3 = SQLEXEC(gnHandle, "select count(*) cnt from vnom_articole where id_articol = " + TRANSFORM(lnIdArtNou3), "crsart3")
+ DO Verdict WITH lnOkArt3 > 0 AND USED('crsart3') AND crsart3.cnt = 0, "articolul nou NU exista dupa do_inchide_tranzactie(2) (cnt=" + TRANSFORM(IIF(USED('crsart3'),crsart3.cnt,-1)) + ")"
+ IF USED('crsart3')
+ USE IN crsart3
+ ENDIF
+ ENDIF
+
+ RELEASE loForm3
+ ENDIF
+
+*=================================================================================================
+* CAZ (4): regresie garda NULL (S6c-4, onom_articole.vc2:88) - articol NOU (INSERT) cu
+* id_tara_origine fortat NULL -> cus_odata_catalog_articole.salvare() trebuie sa construiasca SQL
+* real (nu This.csql NULL) si sa scrie efectiv in Oracle - verificat direct dupa codmat, apoi
+* ROLLBACK direct
+*=================================================================================================
+CASE lcCazSel == "CAZ4"
+ gcCaz = "[4-articol-nou-tara-origine-null] "
+ gcNumeProgram = 'ROAFACTURARE'
+
+ LOCAL lcCodMat4
+ lcCodMat4 = "PS6C4" + SYS(2015)
+ loRec.codmat = lcCodMat4
+ loRec.codmatf = lcCodMat4
+ loRec.denumire = "PROBA S6C4 ARTICOL NOU TARA ORIGINE NULL"
+ loRec.codbare = ""
+ loRec.id_tara_origine = .NULL.
+
+ PRIVATE poRec, pnIdAMS
+ poRec = loRec
+ pnIdAMS = 0
+
+ LOCAL loForm4, llCrapat4, lcErrMsg4, lnErrNo4
+ llCrapat4 = .F.
+ lcErrMsg4 = ''
+ lnErrNo4 = 0
+ TRY
+ loForm4 = CREATEOBJECT('frm_catalog_articole_nou', loRec, 0, 'INSERT')
+ CATCH TO loExc4
+ llCrapat4 = .T.
+ lnErrNo4 = loExc4.ErrorNo
+ lcErrMsg4 = loExc4.Message
+ ENDTRY
+ DO AfLog WITH " rezultat CREATEOBJECT: llCrapat=" + TRANSFORM(llCrapat4) + " errno=" + TRANSFORM(lnErrNo4) + " mesaj=[" + lcErrMsg4 + "]"
+ DO Verdict WITH !llCrapat4 AND VARTYPE(loForm4) = "O", "CREATEOBJECT('frm_catalog_articole_nou',...,'INSERT') trece (errno=0, caz4)"
+
+ IF !llCrapat4
+ loForm4.cus_odata_catalog_articole.lSilent = .T.
+ DO Verdict WITH loForm4.do_deschide_tranzactie(), "do_deschide_tranzactie() = .T. (caz4)"
+
+ LOCAL llSalvatArticol4
+ llSalvatArticol4 = loForm4.cus_odata_catalog_articole.salvare(loForm4.orec, loForm4.NID)
+ DO AfLog WITH " diagnostic: VARTYPE(csql)=" + VARTYPE(loForm4.cus_odata_catalog_articole.csql) + " csql=[" + TRANSFORM(loForm4.cus_odata_catalog_articole.csql) + "]"
+ DO Verdict WITH llSalvatArticol4, "cus_odata_catalog_articole.salvare() INSERT = .T. (id_tara_origine NULL, codmat=" + lcCodMat4 + ")"
+ DO Verdict WITH VARTYPE(loForm4.cus_odata_catalog_articole.csql) = "C" AND !EMPTY(loForm4.cus_odata_catalog_articole.csql), "This.csql construit (nu NULL) cu id_tara_origine NULL"
+
+ LOCAL lnIdArtNou4, lnOkIdNou4
+ lnIdArtNou4 = 0
+ lnOkIdNou4 = SQLEXEC(gnHandle, "select id_articol, id_tara_origine from vnom_articole where codmat = '" + lcCodMat4 + "'", "crsidnou4")
+ DO Verdict WITH lnOkIdNou4 > 0 AND USED('crsidnou4') AND RECCOUNT('crsidnou4') = 1, "articolul nou exista in Oracle dupa codmat (in tranzactie, caz4)"
+ IF USED('crsidnou4') AND RECCOUNT('crsidnou4') = 1
+ lnIdArtNou4 = crsidnou4.id_articol
+ DO Verdict WITH ISNULL(crsidnou4.id_tara_origine), "id_tara_origine ramas NULL in Oracle (caz4)"
+ ENDIF
+ IF USED('crsidnou4')
+ USE IN crsidnou4
+ ENDIF
+ DO AfLog WITH " id articol nou caz4 (cautat dupa codmat)=" + TRANSFORM(lnIdArtNou4)
+ DO Verdict WITH lnIdArtNou4 > 0, "articolul nou gasit dupa codmat, id_articol > 0 (caz4, obtinut " + TRANSFORM(lnIdArtNou4) + ")"
+
+ LOCAL lnOkRb4
+ lnOkRb4 = SQLEXEC(gnHandle, "ROLLBACK")
+ DO Verdict WITH lnOkRb4 > 0, "ROLLBACK direct dupa verificare (caz4, nu do_inchide_tranzactie(1))"
+ SQLSETPROP(gnHandle, "Transactions", 1)
+
+ RELEASE loForm4
+ ENDIF
+
+*=================================================================================================
+* CAZ (5): regresie S6c-5 (_cus_odata_base.vc2:150-181) - subclasa LOCALA proba
+* (cus_odata_vid_s6c5, definita mai jos in acest fisier, fara nicio modificare de productie)
+* suprascrie make_sql lasand This.csql gol -> llConditie devine .F. in salvare() -> trebuie sa
+* intoarca .F. (inainte de reparatie intorcea .T. fara sa trimita niciun SQL). Nu instantiaza
+* formularul, nu atinge Oracle - doar apeleaza direct salvare() pe obiectul de proba, cu spion pe
+* goExecutor ca sa confirme 0 apeluri.
+*=================================================================================================
+CASE lcCazSel == "CAZ5"
+ gcCaz = "[5-sql-gol-salvare-fals] "
+ gcNumeProgram = 'ROAFACTURARE'
+
+ LOCAL loObj5, llRet5, loRealExec5, loSpy5
+ loObj5 = CREATEOBJECT('cus_odata_vid_s6c5')
+ loObj5.lSilent = .T.
+ loObj5.cactiune = 'INSERT'
+
+ loRealExec5 = goExecutor
+ loSpy5 = CREATEOBJECT('SpyS6c2b')
+ goExecutor = loSpy5
+
+ llRet5 = loObj5.salvare(loRec, 0)
+ goExecutor = loRealExec5
+
+ DO AfLog WITH " diagnostic: VARTYPE(csql)=" + VARTYPE(loObj5.csql) + " csql=[" + TRANSFORM(loObj5.csql) + "] SpyS6c2b apeluri=" + TRANSFORM(loSpy5.nApeluri)
+ DO Verdict WITH !llRet5, "salvare() = .F. cand make_sql lasa csql gol (S6c-5, regresie)"
+ DO Verdict WITH EMPTY(loObj5.csql), "csql a ramas gol (make_sql suprascris nu construieste SQL)"
+ DO Verdict WITH loSpy5.nApeluri = 0, "goExecutor.oExecute NU a fost apelat (nimic trimis la Oracle)"
+
+ RELEASE loObj5
+ENDCASE
+
+DO Final
+
+*==================================================================================================
+* Spion pe goExecutor - subclasa DODEFAULT pe PCOUNT (nu opreste executia), tiparul SpyS6b din
+* probe_12b_s6b_clasa_pret_nomenclator.prg. lForteazaEsecSalveaza=.T. intoarce -1 fara sa mai
+* trimita SQL-ul cand acesta contine 'salveaza_pret_nomenclator' (caz CAZ3) - restul trece prin
+* DODEFAULT.
+*==================================================================================================
+DEFINE CLASS SpyS6c2b AS oexecutor
+ nApeluri = 0
+ cToateSql = ''
+ lForteazaEsecSalveaza = .F.
+
+ PROCEDURE oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect)
+ LOCAL lnRet, lnPc, lcS
+ THIS.nApeluri = THIS.nApeluri + 1
+ lcS = IIF(VARTYPE(m.tcSql) = 'C', m.tcSql, '')
+ THIS.cToateSql = THIS.cToateSql + lcS + CHR(13) + CHR(10)
+ STRTOFILE(' SpyS6c2b #' + TRANSFORM(THIS.nApeluri) + ' SQL=[' + lcS + ']' + CHR(13) + CHR(10), gcLog, 1)
+
+ IF THIS.lForteazaEsecSalveaza AND 'SALVEAZA_PRET_NOMENCLATOR' $ UPPER(lcS)
+ STRTOFILE(' SpyS6c2b: ESEC FORTAT (nu trimit SQL-ul de mai sus)' + CHR(13) + CHR(10), gcLog, 1)
+ RETURN -1
+ ENDIF
+
+ lnPc = PCOUNT()
+ DO CASE
+ CASE lnPc <= 1
+ lnRet = DODEFAULT(m.tcSql)
+ CASE lnPc = 2
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor)
+ CASE lnPc = 3
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress)
+ CASE lnPc = 4
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress)
+ CASE lnPc = 5
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle)
+ CASE lnPc = 6
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError)
+ CASE lnPc = 7
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError)
+ OTHERWISE
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError, m.tlReconnect)
+ ENDCASE
+ RETURN lnRet
+ ENDPROC
+ENDDEFINE
+
+*==================================================================================================
+* Subclasa LOCALA de proba (CAZ5, S6c-5) - fara nicio modificare de productie. make_sql suprascris
+* gol, This.csql ramane la valoarea implicita din clasa de baza (sir gol), ca sa forteze ramura
+* llConditie = .F. in _cus_odata_base.vc2 salvare().
+*==================================================================================================
+DEFINE CLASS cus_odata_vid_s6c5 AS cus_odata_catalog_articole
+ PROCEDURE make_sql
+ LPARAMETERS toRec, tnId
+ ENDPROC
+ENDDEFINE
+
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ IF TYPE('gnHandle') = 'N' AND gnHandle > 0
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk) + " (plasa de siguranta - fiecare caz isi face deja propriul ROLLBACK/verificare inainte de asta)"
+ ENDIF
+ DO AfLog WITH "PARTIAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_12b_s7a_optiuni_readonly.prg b/utile/Teste/facturare_unificat/probe_12b_s7a_optiuni_readonly.prg
new file mode 100644
index 0000000..c746862
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s7a_optiuni_readonly.prg
@@ -0,0 +1,187 @@
+* probe_12b_s7a_optiuni_readonly.prg
+* Plan #12b, S7a - proba headless pe frm_optiuni_facturare (COMUN\clase\ofacturare.vc2:24650):
+* .ct_clb_pol_pret_stoc.Enabled = Empty(Thisform.nidpolpretstoc) in Init.
+*
+* nidpolpretstoc vine din pack_facturare.citeste_setari_pol_pret(1, gnIdUtil, ...) (apelata din
+* actualizeaza_politica_pret, ofacturare.vc2:24573). Sursa PL/SQL (ALL_SOURCE, verificata inainte
+* de proba, nu presupusa) pentru V_TIP=1 NU filtreaza dupa V_ID_UTIL - citeste direct
+* OPTIUNI.VARVALUE (VARNAME='ID_POL_PRET_STOC') si verifica doar ca politica exista si nu e STERS
+* in CRM_POLITICI_PRETURI. Filtrul pe utilizator (CRM_VPOLPRETCURUTIL) exista doar pe ramurile
+* V_TIP IN (23,30,41) si V_TIP IN (48,49) - S3 a scos exact acest filtru de pe ramura V_TIP=1
+* ("Locul #3 (citire din OPTIUNI + CRM_POLITICI_PRETURI, fara view-ul pe utilizator)"). Cum S3 e
+* deja aplicat REAL pe schema (stare_plan_12b.md), id_util=4 (fara drept azi la politica 41 prin
+* CRM_VPOLPRETCURUTIL, baseline_12b.md sectiunea 11) primeste ACUM acelasi id_pol=41 ca id_util=8
+* pe aceasta ramura - nota "fara drept inainte de S3" din plan descrie starea DINAINTE de aplicarea
+* reala a S3, nu starea curenta a schemei.
+*
+* Spion pe goExecutor (subclasa, DODEFAULT pe PCOUNT) - tiparul din
+* editare_factura\probe_s13_toomanycolumns.prg: nu opreste executia, doar logheaza fiecare SQL.
+*
+* Rulare: powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume probe_12b_s7a_optiuni_readonly
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\s7a_optiuni_readonly.log (cerut de sarcina, nu out\)
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s7a_optiuni_readonly.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle)
+
+* incarcare explicita a clasei din calea COMPLETA (nu relativa via SET PATH), ca sa fim siguri
+* care ofacturare.vcx s-a incarcat de fapt
+RELEASE CLASSLIB ofacturare
+SET CLASSLIB TO (gcAppPath + "COMUN\CLASE\ofacturare.vcx") ADDITIVE
+DO AfLog WITH "SET CLASSLIB la " + gcAppPath + "COMUN\CLASE\ofacturare.vcx"
+
+gnTransOriginal = SQLGETPROP(gnHandle, "Transactions")
+SQLSETPROP(gnHandle, "Transactions", 2)
+DO AfLog WITH "Transactions manual, original=" + TRANSFORM(gnTransOriginal)
+
+LOCAL loForm1, loForm2, loForm3, loForm4, loReal, loSpy
+
+*----------------------------------------------------------------------------------------
+gcCaz = "[1: optiune setata, id_util=8] "
+gnIdUtil = 8
+loForm1 = CREATEOBJECT('frm_optiuni_facturare', 1)
+DO Verdict WITH LOWER(JUSTFNAME(loForm1.ClassLibrary)) == 'ofacturare.vcx', ;
+ "ClassLibrary incarcat = ofacturare.vcx (cale completa) - " + TRANSFORM(loForm1.ClassLibrary)
+DO Verdict WITH loForm1.pgfrm_optiuni.Page1.Ct_clb_pol_pret_stoc.Enabled = .F., ;
+ "Enabled=.F. dupa Init (nidpolpretstoc=" + TRANSFORM(loForm1.nidpolpretstoc) + ")"
+loForm1.Refresh()
+DO Verdict WITH loForm1.pgfrm_optiuni.Page1.Ct_clb_pol_pret_stoc.Enabled = .F., "Enabled=.F. dupa Refresh()"
+
+*----------------------------------------------------------------------------------------
+gcCaz = "[2: optiune setata, id_util=4 fara drept CRM_VPOLPRETCURUTIL] "
+gnIdUtil = 4
+loForm2 = CREATEOBJECT('frm_optiuni_facturare', 1)
+DO Verdict WITH loForm2.pgfrm_optiuni.Page1.Ct_clb_pol_pret_stoc.Enabled = .F., ;
+ "Enabled=.F. dupa Init (nidpolpretstoc=" + TRANSFORM(loForm2.nidpolpretstoc) + ") - fara filtru pe utilizator pe ramura V_TIP=1, cf. sursei citite"
+loForm2.Refresh()
+DO Verdict WITH loForm2.pgfrm_optiuni.Page1.Ct_clb_pol_pret_stoc.Enabled = .F., "Enabled=.F. dupa Refresh()"
+
+*----------------------------------------------------------------------------------------
+gcCaz = "[3: optiune GOALA] "
+gnIdUtil = 8
+LOCAL lnOk
+lnOk = SQLEXEC(gnHandle, "UPDATE OPTIUNI SET VARVALUE = NULL WHERE PROGRAM = 'ROAFACTURARE' AND VARNAME = 'ID_POL_PRET_STOC'")
+DO Verdict WITH lnOk > 0, "UPDATE OPTIUNI ID_POL_PRET_STOC=NULL (in tranzactie, ROLLBACK la final) - lnOk=" + TRANSFORM(lnOk)
+loForm3 = CREATEOBJECT('frm_optiuni_facturare', 1)
+DO Verdict WITH loForm3.pgfrm_optiuni.Page1.Ct_clb_pol_pret_stoc.Enabled = .T., ;
+ "Enabled=.T. cu optiunea goala (nidpolpretstoc=" + TRANSFORM(NVL(loForm3.nidpolpretstoc, -999)) + ")"
+
+*----------------------------------------------------------------------------------------
+* revin la optiunea reala (41) pentru cazul 4 - salvare fara schimbare trebuie sa compare fata
+* de valoarea reala din OPTIUNI, nu fata de NULL-ul de mai sus
+lnOk = SQLEXEC(gnHandle, "UPDATE OPTIUNI SET VARVALUE = '41' WHERE PROGRAM = 'ROAFACTURARE' AND VARNAME = 'ID_POL_PRET_STOC'")
+DO Verdict WITH lnOk > 0, "restaurare OPTIUNI ID_POL_PRET_STOC=41 (tot in tranzactie) - lnOk=" + TRANSFORM(lnOk)
+
+gcCaz = "[4: salvare fara schimbare de camp, spion oexecutor] "
+loForm4 = CREATEOBJECT('frm_optiuni_facturare', 1)
+loReal = goExecutor
+loSpy = CREATEOBJECT('SpyS7a')
+loSpy.nHandle = gnHandle
+goExecutor = loSpy
+loForm4.inainte_de_do_termin()
+goExecutor = loReal
+DO Verdict WITH !('modificare_politica_stoc' $ UPPER(loSpy.cToateSql)) AND !('MODIFICARE_POLITICA_STOC' $ loSpy.cToateSql), ;
+ "niciun SQL trimis prin executor nu contine modificare_politica_stoc (" + TRANSFORM(loSpy.nApeluri) + " apel(uri))"
+
+*----------------------------------------------------------------------------------------
+gcCaz = "[mutatie de control, instanta separata] "
+LOCAL loFormCtrl
+gnIdUtil = 8
+loFormCtrl = CREATEOBJECT('frm_optiuni_facturare', 1)
+loFormCtrl.pgfrm_optiuni.Page1.Ct_clb_pol_pret_stoc.Enabled = .T.
+DO Verdict WITH loFormCtrl.pgfrm_optiuni.Page1.Ct_clb_pol_pret_stoc.Enabled = .T., ;
+ "dupa fortare manuala Enabled=.T. pe o instanta separata - un assert naiv 'Enabled=.F.' de la cazul 1 ar fi picat aici, deci asertul e sensibil la linia din Init"
+
+DO Final
+
+*==================================================================================================
+* Spion pe goExecutor - subclasa DODEFAULT pe PCOUNT (nu opreste executia), tiparul din
+* editare_factura\probe_s13_toomanycolumns.prg. Acumuleaza toate SQL-urile intr-un singur sir,
+* pentru un singur test de substring la final.
+*==================================================================================================
+DEFINE CLASS SpyS7a AS oexecutor
+ nApeluri = 0
+ cToateSql = ''
+
+ PROCEDURE oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect)
+ LOCAL lnRet, lnPc, lcS
+ THIS.nApeluri = THIS.nApeluri + 1
+ lcS = IIF(VARTYPE(m.tcSql) = 'C', m.tcSql, '')
+ THIS.cToateSql = THIS.cToateSql + lcS + CHR(13) + CHR(10)
+ STRTOFILE(' SpyS7a #' + TRANSFORM(THIS.nApeluri) + ' SQL=[' + lcS + ']' + CHR(13) + CHR(10), gcLog, 1)
+
+ lnPc = PCOUNT()
+ DO CASE
+ CASE lnPc <= 1
+ lnRet = DODEFAULT(m.tcSql)
+ CASE lnPc = 2
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor)
+ CASE lnPc = 3
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress)
+ CASE lnPc = 4
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress)
+ CASE lnPc = 5
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle)
+ CASE lnPc = 6
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError)
+ CASE lnPc = 7
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError)
+ OTHERWISE
+ lnRet = DODEFAULT(m.tcSql, m.tcCursor, m.tlProgress, m.tcTitluProgress, m.tnHandle, m.tlShowError, m.tlQuitOnError, m.tlReconnect)
+ ENDCASE
+ RETURN lnRet
+ ENDPROC
+ENDDEFINE
+
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk)
+ IF TYPE('gnTransOriginal') = 'N'
+ SQLSETPROP(gnHandle, "Transactions", gnTransOriginal)
+ ENDIF
+ DO AfLog WITH "TOTAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_12b_s7b_politica_nota.prg b/utile/Teste/facturare_unificat/probe_12b_s7b_politica_nota.prg
new file mode 100644
index 0000000..3450b68
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s7b_politica_nota.prg
@@ -0,0 +1,181 @@
+* probe_12b_s7b_politica_nota.prg
+* Plan #12b, S7b - proba headless pe clasa cus_pret_nomenclator (COMUN\programe\ofacturare_comun.prg:2323),
+* metodele adaugate in S7b: incarca_nota_politica / salveaza_nota_politica (nota implicita a politicii
+* de stoc, folosita in optiunile facturarii, ofacturare.vc2). Clasa e definita direct in .prg
+* (Set Procedure To ofacturare_comun.prg, deja Additive in mediul de test) - CREATEOBJECT direct.
+*
+* Cazuri:
+* (1) asigura_politica() apelata de doua ori, ca din ROACONTRACTE (acelasi pachet PL/SQL,
+* D14 = pack_preturi.asigura_politica_stoc) dupa ce optiunea e golita -> o singura politica
+* noua (numarate randurile CRM_POLITICI_PRETURI inainte/dupa fiecare apel, nu doar id-ul).
+* (2) salveaza_nota_politica(id_pol_nou, '461', '7583') -> ID_NOTA citit DIRECT din
+* CRM_POLITICI_PRETURI (nu din proprietatile instantei), plus SCD/SCC ale notei citite prin
+* JOIN CRM_NOTE_VANZARI/NOTE_CONTABILE, comparate cu valorile asteptate 461/7583.
+* (3) incarca_nota_politica(acelasi id_pol) pe o instanta noua -> cScd/cScc = 461/7583, identic
+* cu ce s-a scris la (2).
+* Politica noua de la (1) e folosita si la (2)/(3), ca sa nu atinga politica 41 de productie -
+* dispare oricum la ROLLBACK.
+*
+* Spion pe goExecutor: nu e nevoie - toate verificarile citesc direct din Oracle (SQLEXEC), nu
+* numara apeluri RPC.
+*
+* Rulare: powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume probe_12b_s7b_politica_nota
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\s7b_proba.log (cerut de sarcina, nu out\)
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail, gnTransOriginal
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s7b_proba.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+gnIdUtil = 8
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle)
+
+gnTransOriginal = SQLGETPROP(gnHandle, "Transactions")
+SQLSETPROP(gnHandle, "Transactions", 2)
+DO AfLog WITH "Transactions manual, original=" + TRANSFORM(gnTransOriginal)
+
+LOCAL lnOk, lnCntInit, lnCntDupa1, lnCntDupa2, lcOptInit, loA, loB, lnPolA, lnPolB
+
+*==========================================================================================
+* CAZ (1): asigura_politica_stoc apelata de doua ori (ca din ROACONTRACTE) -> o singura politica
+*==========================================================================================
+gcCaz = "[1-asigura_politica_stoc-x2] "
+
+* precondition: sesiunea reala initializeaza pack_facturare.nid_moneda_nationala inaintea D14
+* (initializeaza_facturare) - tiparul confirmat in docs\proba_s6a_asigura_politica_stoc.sql
+lnOk = SQLEXEC(gnHandle, "begin pack_facturare.nid_moneda_nationala := pack_def.GetIdMonedaNationala(); end;")
+DO Verdict WITH lnOk > 0, "precondition pack_facturare.nid_moneda_nationala initializat"
+
+lnOk = SQLEXEC(gnHandle, "select count(*) cnt from crm_politici_preturi", "crscnt0")
+lnCntInit = IIF(lnOk > 0 AND USED('crscnt0'), crscnt0.cnt, -1)
+IF USED('crscnt0')
+ USE IN crscnt0
+ENDIF
+
+lnOk = SQLEXEC(gnHandle, "select varvalue from optiuni where program='ROAFACTURARE' and varname='ID_POL_PRET_STOC'", "crsopt0")
+lcOptInit = IIF(lnOk > 0 AND USED('crsopt0') AND !ISNULL(crsopt0.varvalue), ALLTRIM(crsopt0.varvalue), "")
+IF USED('crsopt0')
+ USE IN crsopt0
+ENDIF
+DO AfLog WITH " OPTIUNE initiala ID_POL_PRET_STOC=[" + lcOptInit + "], politici initial=" + TRANSFORM(lnCntInit)
+
+lnOk = SQLEXEC(gnHandle, "UPDATE OPTIUNI SET VARVALUE = NULL WHERE PROGRAM = 'ROAFACTURARE' AND VARNAME = 'ID_POL_PRET_STOC'")
+DO Verdict WITH lnOk > 0, "UPDATE OPTIUNI ID_POL_PRET_STOC=NULL (tranzactie, ROLLBACK la final) - lnOk=" + TRANSFORM(lnOk)
+
+loA = CREATEOBJECT('cus_pret_nomenclator')
+lnPolA = loA.asigura_politica()
+DO Verdict WITH lnPolA > 0, "primul apel asigura_politica() > 0 (obtinut " + TRANSFORM(lnPolA) + ")"
+
+lnOk = SQLEXEC(gnHandle, "select count(*) cnt from crm_politici_preturi", "crscnt1")
+lnCntDupa1 = IIF(lnOk > 0 AND USED('crscnt1'), crscnt1.cnt, -1)
+IF USED('crscnt1')
+ USE IN crscnt1
+ENDIF
+DO Verdict WITH lnCntDupa1 = lnCntInit + 1, "dupa primul apel: politici " + TRANSFORM(lnCntInit) + " -> " + TRANSFORM(lnCntDupa1) + " (+1 asteptat)"
+
+loB = CREATEOBJECT('cus_pret_nomenclator')
+lnPolB = loB.asigura_politica()
+
+lnOk = SQLEXEC(gnHandle, "select count(*) cnt from crm_politici_preturi", "crscnt2")
+lnCntDupa2 = IIF(lnOk > 0 AND USED('crscnt2'), crscnt2.cnt, -1)
+IF USED('crscnt2')
+ USE IN crscnt2
+ENDIF
+
+DO Verdict WITH lnPolB = lnPolA, "al doilea apel (ca din ROACONTRACTE) intoarce acelasi id=" + TRANSFORM(lnPolA) + " (obtinut " + TRANSFORM(lnPolB) + ")"
+DO Verdict WITH lnCntDupa2 = lnCntDupa1, "al doilea apel NU creeaza politica noua (politici " + TRANSFORM(lnCntDupa1) + " -> " + TRANSFORM(lnCntDupa2) + ")"
+
+IF !EMPTY(lcOptInit)
+ lnOk = SQLEXEC(gnHandle, "UPDATE OPTIUNI SET VARVALUE = '" + lcOptInit + "' WHERE PROGRAM = 'ROAFACTURARE' AND VARNAME = 'ID_POL_PRET_STOC'")
+ DO Verdict WITH lnOk > 0, "restaurare OPTIUNI ID_POL_PRET_STOC=" + lcOptInit + " (tot in tranzactie) - lnOk=" + TRANSFORM(lnOk)
+ENDIF
+
+*==========================================================================================
+* CAZ (2): salveaza_nota_politica scrie ID_NOTA in CRM_POLITICI_PRETURI (citit din Oracle)
+*==========================================================================================
+gcCaz = "[2-salveaza_nota_politica] "
+LOCAL loC, llRes2, lnIdNotaCitit
+
+loC = CREATEOBJECT('cus_pret_nomenclator')
+llRes2 = loC.salveaza_nota_politica(lnPolA, '461', '7583')
+DO Verdict WITH llRes2, "salveaza_nota_politica(" + TRANSFORM(lnPolA) + ",461,7583) = .T."
+
+lnOk = SQLEXEC(gnHandle, "select id_nota from crm_politici_preturi where id_pol = " + TRANSFORM(lnPolA), "crsverif2")
+lnIdNotaCitit = IIF(lnOk > 0 AND USED('crsverif2') AND RECCOUNT('crsverif2') = 1, NVL(crsverif2.id_nota,-999), -999)
+IF USED('crsverif2')
+ USE IN crsverif2
+ENDIF
+DO Verdict WITH lnIdNotaCitit > 0, "ID_NOTA citit direct din CRM_POLITICI_PRETURI (nu din instanta) > 0 - obtinut " + TRANSFORM(lnIdNotaCitit)
+
+lnOk = SQLEXEC(gnHandle, "select n.scd, n.scc from crm_note_vanzari v, note_contabile n where v.id_nota = " + TRANSFORM(lnIdNotaCitit) + " and n.id_set = v.id_set", "crsnota2")
+DO Verdict WITH lnOk > 0 AND USED('crsnota2') AND RECCOUNT('crsnota2') = 1 AND ALLTRIM(crsnota2.scd) == "461" AND ALLTRIM(crsnota2.scc) == "7583", ;
+ "nota din Oracle are scd/scc = 461/7583 (asteptat independent, nu cursorul clasei) - obtinut " + ;
+ IIF(USED('crsnota2') AND RECCOUNT('crsnota2') = 1, ALLTRIM(NVL(crsnota2.scd,'?')) + '/' + ALLTRIM(NVL(crsnota2.scc,'?')), '')
+IF USED('crsnota2')
+ USE IN crsnota2
+ENDIF
+
+*==========================================================================================
+* CAZ (3): incarca_nota_politica citeste inapoi identic (instanta noua)
+*==========================================================================================
+gcCaz = "[3-incarca_nota_politica] "
+LOCAL loD, llRes3
+
+loD = CREATEOBJECT('cus_pret_nomenclator')
+llRes3 = loD.incarca_nota_politica(lnPolA)
+DO Verdict WITH llRes3, "incarca_nota_politica(" + TRANSFORM(lnPolA) + ") = .T."
+DO Verdict WITH ALLTRIM(loD.cScd) == "461", "incarca_nota_politica: cScd=461 (obtinut [" + ALLTRIM(loD.cScd) + "])"
+DO Verdict WITH ALLTRIM(loD.cScc) == "7583", "incarca_nota_politica: cScc=7583 (obtinut [" + ALLTRIM(loD.cScc) + "])"
+
+DO Final
+
+*==================================================================================================
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk)
+ IF TYPE('gnTransOriginal') = 'N'
+ SQLSETPROP(gnHandle, "Transactions", gnTransOriginal)
+ ENDIF
+ DO AfLog WITH "TOTAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_12b_s8_cai_1_3.prg b/utile/Teste/facturare_unificat/probe_12b_s8_cai_1_3.prg
new file mode 100644
index 0000000..2e23963
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s8_cai_1_3.prg
@@ -0,0 +1,401 @@
+* probe_12b_s8_cai_1_3.prg
+* Plan 12b, S8-4b: proba headless a caii 1 (do_adauga_articol) si caii 3 (do_adauga_tot) din
+* frm_facturare_articole2 (COMUN\clase\ofacturare.vc2) pentru verificarea prietenoasa D10 a
+* contului de venit (S8-3). Calea 2 (do_adauga_articol_cautat) e alt fisier.
+*
+* Instantiere formular headless (tipar dovedit, COMUN\utile\Teste\facturare_unificat\test_s3_4b_incarca_articole.prg,
+* 95 PASS): SET PATH/CLASSLIB gridextras + _cb_base ADDITIVE inainte de Createobject, crsfactura
+* deschis (structura goala + camp gestiune) inainte de Createobject (grd_factura.Column e legat la
+* crsFactura.denumire), o singura instanta refolosita pe cele 3 cazuri.
+*
+* crsarticole: structura REALA descoperita cu AFIELDS pe pack_facturare.cursor_preturi(tnTip=1)
+* (24 campuri), nu cursorul sintetic din mock_cursor_articole.prg (are pretftva/pretctva direct,
+* incompatibil cu do_initializeaza_articol care cere Pret/pret_val si le deriva singur).
+*
+* Politica de stoc (ID_NOTA NULL, tranzactie, ROLLBACK la final) + cele doua articole (cont dedus /
+* fara cont dedus) alese din baza vie prin acelasi tipar ca probe_12b_s8_verifica_linie.prg (caz3/caz4).
+* Articolele sunt marcate gestionabil=0 in crsarticole (nu reflecta starea reala din nomenclator) ca
+* sa ocoleasca do_alege_stoc (ramura de stoc, neatinsa de S8-3) - do_verifica_articol si Do Case-ul
+* de ramificare din do_adauga_articol trec amandoua pe gestionabil=0, indiferent de gnScadereStoc.
+*
+* Spion amessagebox propriu (contor + text), incarcat PRIMUL (SET PROCEDURE TO (acest fisier), &lcProcExistent).
+*
+* Cazuri:
+* (1) calea 1, articol FARA cont dedus -> do_adauga_articol(.T.) nu adauga (Reccount(crsfactura)
+* neschimbat), spion: 1 mesaj continand denumirea articolului. PASS.
+* (2) calea 1, articol CU cont dedus -> linia se adauga (Reccount+1), 0 mesaje. PASS.
+* (3) calea 3, do_adauga_tot() pe crsarticole cu ambele articole (problema + OK) -> AMBELE linii
+* adaugate (Reccount+2), spion: EXACT 1 mesaj, continand denumirea articolului problema, nu si
+* pe a celui OK. PASS.
+*
+* S8-4d: blocajul (2)/(3) era lipsa cursorului 'saft_taxtable' - Createobject("frm_articol_factura",...)
+* (ofacturare.vc2:18751) executa in Init (:2678, gl406) un Requery() pe un combo RowSourceType=3 legat
+* de 'saft_taxtable'; cu SET TABLEPROMPT OFF eroarea reala era "File 'saft_taxtable.dbf' does not exist."
+* Fix: update_saft_taxtable() (COMUN\programe\updateserver.prg), acelasi apel facut de aplicatie in
+* factureaza() (COMUN\programe\ofacturare.prg) imediat dupa update_jtva_coloane(), inainte de
+* Createobject('frm_facturare_articole2'). glIncearcaCazSucces implicit .T.
+*
+* Rulare: vfp9.exe -A -T "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_12b_s8_cai_1_3.prg"
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\s8_cai_1_3.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+SET DELETED ON
+SET EXACT ON
+SET CENTURY ON
+SET DATE DMY
+SET DECIMALS TO 4
+SET NULLDISPLAY TO ''
+SET TABLEPROMPT OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail, gnTransOriginal
+PUBLIC gcSpionMesaje, gnSpionCount
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s8_cai_1_3.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog, 1)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+gcSpionMesaje = ""
+gnSpionCount = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+ON SHUTDOWN QUIT
+
+*-- spion amessagebox: se incarca PRIMUL (inaintea aplicatiei), ca sa castige la nume duplicat
+LOCAL lcProcExistent, lcCmdProc
+lcProcExistent = SET("PROCEDURE")
+lcCmdProc = [SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_12b_s8_cai_1_3.prg"]
+IF !EMPTY(lcProcExistent)
+ lcCmdProc = lcCmdProc + ", " + lcProcExistent
+ENDIF
+&lcCmdProc
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+gnIdUtil = 8
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle)
+
+gnTransOriginal = SQLGETPROP(gnHandle, "Transactions")
+SQLSETPROP(gnHandle, "Transactions", 2)
+DO AfLog WITH "Transactions manual, original=" + TRANSFORM(gnTransOriginal)
+
+IF !actualizeaza_optiuni_program()
+ DO AfLog WITH "FAIL: actualizeaza_optiuni_program()"
+ DO Final
+ENDIF
+DO AfLog WITH "actualizeaza_optiuni_program OK, gnScadereStoc=" + TRANSFORM(NVL(gnScadereStoc, -1))
+
+SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras" ADDITIVE
+SET CLASSLIB TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras\gridextras.vcx" ADDITIVE
+SET CLASSLIB TO "D:\ROA\ROAFACTURARE\COMUN\clase\_cb_base.vcx" ADDITIVE
+DO AfLog WITH "SET CLASSLIB suplimentar OK"
+
+update_jtva_coloane([JV], [jtva_coloane_temp])
+update_saft_taxtable()
+DO AfLog WITH "update_saft_taxtable OK, Reccount=" + TRANSFORM(IIF(USED('saft_taxtable'), RECCOUNT('saft_taxtable'), -1))
+
+*==========================================================================================
+* alegere date: politica de stoc curenta + articol OK (cont dedus) + articol problema (fara cont)
+*==========================================================================================
+LOCAL lnOk, lnIdPolStoc, lnIdArtOk, lnIdArtProblema, lcDenOk, lcDenProblema
+LOCAL llGasitOk, llGasitProblema
+
+gcCaz = "[setup] "
+lnOk = SQLEXEC(gnHandle, "select varvalue from optiuni where program='ROAFACTURARE' and varname='ID_POL_PRET_STOC'", "crsopt")
+lnIdPolStoc = IIF(lnOk > 0 AND USED('crsopt') AND !ISNULL(crsopt.varvalue), VAL(ALLTRIM(crsopt.varvalue)), 0)
+IF USED('crsopt')
+ USE IN crsopt
+ENDIF
+DO Verdict WITH lnIdPolStoc > 0, "politica de stoc citita din OPTIUNI, id_pol=" + TRANSFORM(lnIdPolStoc)
+IF lnIdPolStoc <= 0
+ DO Final
+ENDIF
+PUBLIC gnId_pol_pret_stoc
+gnId_pol_pret_stoc = lnIdPolStoc
+
+* articol OK: rand al politicii de stoc, ID_NOTA propriu NULL, cont_venit_articol_stoc rezolvat
+lnOk = SQLEXEC(gnHandle, ;
+ "select a.id_articol from crm_politici_pret_art a " + ;
+ "where a.id_pol = " + TRANSFORM(lnIdPolStoc) + " and a.id_nota is null " + ;
+ "and pack_facturare.cont_venit_articol_stoc(a.id_articol) is not null and rownum = 1", "crsok")
+llGasitOk = lnOk > 0 AND USED('crsok') AND RECCOUNT('crsok') = 1
+lnIdArtOk = IIF(llGasitOk, crsok.id_articol, 0)
+IF USED('crsok')
+ USE IN crsok
+ENDIF
+DO AfLog WITH "articol OK ales: id_articol=" + TRANSFORM(lnIdArtOk)
+
+* articol problema: alt rand al politicii de stoc, ID_NOTA propriu NULL, fara cont dedus
+lnOk = SQLEXEC(gnHandle, ;
+ "select a.id_articol from crm_politici_pret_art a " + ;
+ "where a.id_pol = " + TRANSFORM(lnIdPolStoc) + " and a.id_nota is null " + ;
+ "and a.id_articol <> " + TRANSFORM(lnIdArtOk) + " " + ;
+ "and pack_facturare.cont_venit_articol_stoc(a.id_articol) is null and rownum = 1", "crsprob")
+llGasitProblema = lnOk > 0 AND USED('crsprob') AND RECCOUNT('crsprob') = 1
+lnIdArtProblema = IIF(llGasitProblema, crsprob.id_articol, 0)
+IF USED('crsprob')
+ USE IN crsprob
+ENDIF
+DO AfLog WITH "articol PROBLEMA ales: id_articol=" + TRANSFORM(lnIdArtProblema)
+
+IF !llGasitOk OR !llGasitProblema
+ DO AfLog WITH "FAIL: date insuficiente in baza vie (articol OK sau PROBLEMA negasit), opresc proba"
+ gnFail = gnFail + 1
+ DO Final
+ENDIF
+
+lnOk = SQLEXEC(gnHandle, "select denumire from nom_articole where id_articol = " + TRANSFORM(lnIdArtOk), "crsden1")
+lcDenOk = IIF(lnOk > 0 AND USED('crsden1') AND RECCOUNT('crsden1') = 1, ALLTRIM(NVL(crsden1.denumire, [])), [])
+IF USED('crsden1')
+ USE IN crsden1
+ENDIF
+lnOk = SQLEXEC(gnHandle, "select denumire from nom_articole where id_articol = " + TRANSFORM(lnIdArtProblema), "crsden2")
+lcDenProblema = IIF(lnOk > 0 AND USED('crsden2') AND RECCOUNT('crsden2') = 1, ALLTRIM(NVL(crsden2.denumire, [])), [])
+IF USED('crsden2')
+ USE IN crsden2
+ENDIF
+DO AfLog WITH "denumiri: OK=[" + lcDenOk + "] PROBLEMA=[" + lcDenProblema + "]"
+
+* politica de stoc cu ID_NOTA NULL (tranzactie, ROLLBACK la final) - fortez ramura "fara cont dedus"
+gcCaz = "[setup] "
+lnOk = SQLEXEC(gnHandle, "UPDATE crm_politici_preturi SET id_nota = NULL WHERE id_pol = " + TRANSFORM(lnIdPolStoc))
+DO Verdict WITH lnOk > 0, "UPDATE politica de stoc ID_NOTA=NULL (tranzactie, ROLLBACK la final) - lnOk=" + TRANSFORM(lnOk)
+
+*==========================================================================================
+* mediu formular: poDate, jtva_coloane, crsfactura gol, Createobject
+*==========================================================================================
+PRIVATE poDate, poGeneratorNumere
+LOCAL lnIdSet
+lnIdSet = 25000 + 30 - 1 + NVL(gnScadereStoc, 0) * 10
+poDate = CREATEOBJECT("oDateFactura", lnIdSet, 30)
+poDate.dataireg = DATE(gnAn, gnLuna, 10)
+poDate.dataact = poDate.dataireg
+poDate.zi_curs = poDate.dataireg
+poDate.id_client = 1
+poDate.nIdTipDoc = 6
+poGeneratorNumere = NULL
+DO AfLog WITH "poDate OK, tip=" + TRANSFORM(poDate.tip) + " in_valuta=" + TRANSFORM(poDate.in_valuta) + " tva_incasare=" + TRANSFORM(NVL(poDate.tva_incasare, -1))
+
+IF USED('jtva_coloane')
+ USE IN jtva_coloane
+ENDIF
+IF NVL(poDate.tva_incasare, 0) = 0
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_ex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ELSE
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_neex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ENDIF
+DO AfLog WITH "jtva_coloane Reccount=" + TRANSFORM(RECCOUNT('jtva_coloane'))
+
+DO PregatesteFacturaGoala
+
+LOCAL loForm
+loForm = CREATEOBJECT('frm_facturare_articole2')
+DO Verdict WITH VARTYPE(loForm) = 'O', "Createobject frm_facturare_articole2"
+IF VARTYPE(loForm) <> 'O'
+ DO Final
+ENDIF
+* fara Show()/WindowType - formularul ramane necreat vizual, ca in test_s3_4b_incarca_articole.prg
+DO AfLog WITH "formular creat, nu afisat (fara Show())"
+
+*==========================================================================================
+* CAZ (1): calea 1, articol fara cont dedus -> refuz
+*==========================================================================================
+gcCaz = "[1-calea1-refuz] "
+DO PregatesteArticoleUnRand WITH lnIdArtProblema, lcDenProblema, lnIdPolStoc
+
+LOCAL lnReccountInainte
+lnReccountInainte = RECCOUNT('crsfactura')
+gnSpionCount = 0
+gcSpionMesaje = ""
+
+loForm.do_adauga_articol(.T.)
+
+DO Verdict WITH RECCOUNT('crsfactura') == lnReccountInainte, ;
+ "Reccount(crsfactura) neschimbat (" + TRANSFORM(RECCOUNT('crsfactura')) + ", era " + TRANSFORM(lnReccountInainte) + ")"
+DO Verdict WITH gnSpionCount == 1, "spion: 1 mesaj (obtinut " + TRANSFORM(gnSpionCount) + ")"
+DO Verdict WITH lcDenProblema $ gcSpionMesaje, "mesajul contine denumirea articolului [" + lcDenProblema + "] - mesaj: [" + gcSpionMesaje + "]"
+
+*==========================================================================================
+* CAZ (2): calea 1, articol cu cont dedus -> linia se adauga
+*==========================================================================================
+IF TYPE('glIncearcaCazSucces') = 'U'
+ PUBLIC glIncearcaCazSucces
+ glIncearcaCazSucces = .T.
+ENDIF
+
+gcCaz = "[2-calea1-cont-dedus] "
+IF !glIncearcaCazSucces
+ DO AfLog WITH "BLOCAT: " + gcCaz + "sarit (glIncearcaCazSucces=.F.) - ramura de succes a lui do_adauga_articol atarna headless, vezi antetul fisierului"
+ELSE
+ DO PregatesteArticoleUnRand WITH lnIdArtOk, lcDenOk, lnIdPolStoc
+
+ lnReccountInainte = RECCOUNT('crsfactura')
+ gnSpionCount = 0
+ gcSpionMesaje = ""
+
+ loForm.do_adauga_articol(.T.)
+
+ DO Verdict WITH RECCOUNT('crsfactura') == lnReccountInainte + 1, ;
+ "Reccount(crsfactura) creste cu 1 (" + TRANSFORM(RECCOUNT('crsfactura')) + ", era " + TRANSFORM(lnReccountInainte) + ")"
+ DO Verdict WITH gnSpionCount == 0, "spion: 0 mesaje (obtinut " + TRANSFORM(gnSpionCount) + ") - " + gcSpionMesaje
+ENDIF
+
+*==========================================================================================
+* CAZ (3): calea 3, do_adauga_tot() pe ambele articole -> ambele linii, UN singur mesaj
+* (scaneaza crsarticole si cheama do_adauga_articol pe fiecare rand)
+*==========================================================================================
+gcCaz = "[3-calea3-adauga-tot] "
+IF !glIncearcaCazSucces
+ DO AfLog WITH "BLOCAT: " + gcCaz + "sarit (glIncearcaCazSucces=.F.) - aceeasi ramura de succes ca (2)"
+ELSE
+ DO PregatesteFacturaGoala
+ loForm.grd_factura.RecordSource = ''
+ loForm.grd_factura.RecordSource = 'crsfactura'
+ DO PregatesteArticoleDoiaRanduri WITH lnIdArtProblema, lcDenProblema, lnIdArtOk, lcDenOk, lnIdPolStoc
+
+ lnReccountInainte = RECCOUNT('crsfactura')
+ gnSpionCount = 0
+ gcSpionMesaje = ""
+
+ loForm.do_adauga_tot()
+
+ DO Verdict WITH RECCOUNT('crsfactura') == lnReccountInainte + 2, ;
+ "Reccount(crsfactura) creste cu 2, ambele linii adaugate (" + TRANSFORM(RECCOUNT('crsfactura')) + ", era " + TRANSFORM(lnReccountInainte) + ")"
+ DO Verdict WITH gnSpionCount == 1, "spion: EXACT 1 mesaj (obtinut " + TRANSFORM(gnSpionCount) + ") - " + gcSpionMesaje
+ DO Verdict WITH lcDenProblema $ gcSpionMesaje, "mesajul contine denumirea articolului problema [" + lcDenProblema + "]"
+ DO Verdict WITH !(lcDenOk $ gcSpionMesaje), "mesajul NU contine denumirea articolului OK [" + lcDenOk + "]"
+ENDIF
+
+IF VARTYPE(loForm) = 'O' AND !ISNULL(loForm)
+ loForm.Release()
+ENDIF
+loForm = NULL
+
+DO Final
+
+*==================================================================================================
+*-- spion amessagebox - contor + texte, incarcat PRIMUL (vezi SET PROCEDURE la inceput)
+FUNCTION amessagebox
+ LPARAMETERS tcMessage, tnDialogBoxType, tcTitle, tcFont, tnTimeOut, tnTimeoutValue
+ gnSpionCount = gnSpionCount + 1
+ gcSpionMesaje = gcSpionMesaje + "[" + TRANSFORM(tcMessage) + "]" + CHR(13) + CHR(10)
+ DO AfLog WITH " [spion amessagebox] " + TRANSFORM(tcMessage)
+ RETURN 6
+ENDFUNC
+
+*-- crsfactura gol, cu campul 'gestiune' suplimentar cerut de grd_factura.cGestiune (ca in
+*-- test_s3_4b_incarca_articole.prg) - obligatoriu inainte de Createobject (legare ControlSource)
+PROCEDURE PregatesteFacturaGoala
+ IF USED('crsfactura')
+ USE IN crsfactura
+ ENDIF
+ creeaza_facturacrs([crsfactura])
+ SELECT *, CAST(NULL AS C(100)) AS gestiune FROM crsfactura INTO CURSOR crsfact_tmp READWRITE
+ USE IN crsfactura
+ SELECT * FROM crsfact_tmp INTO CURSOR crsfactura READWRITE
+ USE IN crsfact_tmp
+ENDPROC
+
+*-- crsarticole cu structura REALA (24 campuri, AFIELDS pe cursor_preturi tnTip=1), UN singur rand,
+*-- gestionabil=0 (ocoleste do_alege_stoc, neatins de S8-3)
+PROCEDURE PregatesteArticoleUnRand
+ LPARAMETERS tnIdArticol, tcDenumire, tnIdPol
+ IF USED('crsarticole')
+ USE IN crsarticole
+ ENDIF
+ DO CreeazaStructuraArticole
+ INSERT INTO crsarticole (id_c, id_articol, lot, serie, id_pol, id_valuta, nume_lista_preturi, ;
+ discount_unitar, discount_unitar_val, codmat, codbare, denumire, um, gestionabil, ;
+ cantitate, proc_tvav, preturi_cu_tva, curs, multiplicator, pret, pret_val, tip_valuta, ;
+ nume_val, modificabil) ;
+ VALUES (1, tnIdArticol, [], [], tnIdPol, 1, [S8-4b], 0, 0, [S8-4b], [], tcDenumire, [BUC], 0, ;
+ 1, 1.19, 0, 0, 1, 100, 0, 0, [RON], 1)
+ GO TOP IN crsarticole
+ENDPROC
+
+*-- crsarticole cu DOUA randuri (problema + OK), pentru do_adauga_tot
+PROCEDURE PregatesteArticoleDoiaRanduri
+ LPARAMETERS tnIdArtProblema, tcDenProblema, tnIdArtOk, tcDenOk, tnIdPol
+ IF USED('crsarticole')
+ USE IN crsarticole
+ ENDIF
+ DO CreeazaStructuraArticole
+ INSERT INTO crsarticole (id_c, id_articol, lot, serie, id_pol, id_valuta, nume_lista_preturi, ;
+ discount_unitar, discount_unitar_val, codmat, codbare, denumire, um, gestionabil, ;
+ cantitate, proc_tvav, preturi_cu_tva, curs, multiplicator, pret, pret_val, tip_valuta, ;
+ nume_val, modificabil) ;
+ VALUES (1, tnIdArtProblema, [], [], tnIdPol, 1, [S8-4b], 0, 0, [S8-4b], [], tcDenProblema, [BUC], 0, ;
+ 1, 1.19, 0, 0, 1, 100, 0, 0, [RON], 1)
+ INSERT INTO crsarticole (id_c, id_articol, lot, serie, id_pol, id_valuta, nume_lista_preturi, ;
+ discount_unitar, discount_unitar_val, codmat, codbare, denumire, um, gestionabil, ;
+ cantitate, proc_tvav, preturi_cu_tva, curs, multiplicator, pret, pret_val, tip_valuta, ;
+ nume_val, modificabil) ;
+ VALUES (2, tnIdArtOk, [], [], tnIdPol, 1, [S8-4b], 0, 0, [S8-4b], [], tcDenOk, [BUC], 0, ;
+ 1, 1.19, 0, 0, 1, 100, 0, 0, [RON], 1)
+ GO TOP IN crsarticole
+ENDPROC
+
+PROCEDURE CreeazaStructuraArticole
+ CREATE CURSOR crsarticole (id_c N(8,0), id_articol N(20,0), lot C(20), serie C(20), id_pol N(7,0), ;
+ id_valuta N(7,0), nume_lista_preturi C(100), discount_unitar N(8,2), discount_unitar_val N(8,2), ;
+ codmat C(50), codbare C(50), denumire C(100), um C(20), gestionabil N(3,0), cantitate N(8,2), ;
+ proc_tvav N(12,4), preturi_cu_tva N(3,0), curs N(14,4), multiplicator N(12,0), pret N(8,2), ;
+ pret_val N(8,2), tip_valuta N(3,0), nume_val C(20), modificabil N(3,0))
+ENDPROC
+
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ LOCAL lnI, laStack
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ DO AfLog WITH " MESSAGE(1)=" + TRANSFORM(MESSAGE(1))
+ DO AfLog WITH " SYS(16)=" + TRANSFORM(SYS(16))
+ IF ASTACKINFO(laStack) > 0
+ LOCAL lnJ, lcRand
+ FOR lnI = 1 TO ALEN(laStack, 1)
+ lcRand = " STACK[" + TRANSFORM(lnI) + "]"
+ FOR lnJ = 1 TO ALEN(laStack, 2)
+ lcRand = lcRand + " c" + TRANSFORM(lnJ) + "=" + TRANSFORM(laStack(lnI, lnJ))
+ ENDFOR
+ DO AfLog WITH lcRand
+ ENDFOR
+ ENDIF
+ gnFail = gnFail + 1
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ IF TYPE('gnHandle') = 'N' AND gnHandle > 0
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk)
+ IF TYPE('gnTransOriginal') = 'N'
+ SQLSETPROP(gnHandle, "Transactions", gnTransOriginal)
+ ENDIF
+ ENDIF
+ DO AfLog WITH "TOTAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_12b_s8_calea_2.prg b/utile/Teste/facturare_unificat/probe_12b_s8_calea_2.prg
new file mode 100644
index 0000000..a7dfc79
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s8_calea_2.prg
@@ -0,0 +1,382 @@
+* probe_12b_s8_calea_2.prg
+* Plan 12b, S8-4a: proba headless a caii 2 (do_adauga_articol_cautat) din frm_facturare_articole2
+* (COMUN\clase\ofacturare.vc2) pentru verificarea prietenoasa D10 a contului de venit (S8-3/S8-4a).
+*
+* PAS 0 (dovada): pe aceasta cale, obiectul toArticol vine dintr-un Scatter Name pe crsCodmat/
+* crsDenumire. Analiza statica din raportul S8-3 a citat proprietatile design-time csourcesql/
+* csourcewhere de pe combosql_cautare (:17528/:17564, doar 7 coloane, fara id_pol) - dar acelea NU
+* sunt folosite la rulare: refreshdata/selectdata (ofacturare.vc2:463-529) ignora total csourcesql
+* si cheama This.cursor_preturi_call() (:446-461), adica {call pack_facturare.cursor_preturi(...)}
+* (sau cursor_gestiune pentru tip=41) - acelasi mecanism ca la crsarticole (calea 1). Structura reala
+* a cursorului (creeaza_cursor_gol :426-444, reordoneaza :498-512) INCLUDE id_pol. Asadar in cazul
+* normal Type('toArticol.Id_Pol')='N' e adevarat, iar linia scrisa in crsfactura (Gather la
+* ofacturare.vc2:19018) primeste chiar politica reala rezolvata de cursor_preturi pentru articolul
+* respectiv - nu politica de stoc.
+*
+* Fix S8-4a (ofacturare.vc2:18968-18972): confirmat empiric (probe separat, Gather Name cu
+* proprietate lipsa NU arunca eroare si LASA campul destinatie neschimbat, adica linia ar fi ramas
+* cu Id_Pol vechi/implicit daca toArticol nu are proprietatea) ca fallback-ul gnId_pol_pret_stoc
+* calculat pentru verificare (lnIdPolLinie) nu ajungea niciodata in linia scrisa cand proprietatea
+* lipsea din toArticol - AddProperty(toArticol,'Id_Pol',lnIdPolLinie) inchide acest gol; e no-op
+* cand Type('toArticol.Id_Pol')='N' (cazul normal, politica reala).
+*
+* Cazuri (fara mock goExecutor, politica de stoc cu ID_NOTA NULL in tranzactie, ROLLBACK la final):
+* (a) toArticol FARA proprietatea Id_Pol, articol fara cont dedus -> do_adauga_articol_cautat = .F.,
+* Reccount(crsfactura) neschimbat, spion amessagebox: mesaj continand denumirea articolului.
+* (b) toArticol FARA proprietatea Id_Pol, articol CU cont dedus -> linia se adauga (Reccount+1),
+* spion 0 apeluri, iar crsfactura.Id_Pol al liniei noi == gnId_pol_pret_stoc (fallback aplicat).
+* (c) toArticol CU Id_Pol = o politica reala (<> politica de stoc, cu nota proprie valida) -> linia
+* se adauga, crsfactura.Id_Pol al liniei noi == acea politica reala (Type='N', fix no-op,
+* politica ramane cea reala, nu cea de stoc).
+*
+* Rulare: vfp9.exe -A -T "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_12b_s8_calea_2.prg"
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\s8_calea_2.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+SET DELETED ON
+SET EXACT ON
+SET CENTURY ON
+SET DATE DMY
+SET DECIMALS TO 4
+SET NULLDISPLAY TO ''
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail, gnTransOriginal
+PUBLIC gcSpionMesaje, gnSpionCount
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s8_calea_2.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+gcSpionMesaje = ""
+gnSpionCount = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+ON SHUTDOWN QUIT
+
+*-- spion amessagebox: se incarca PRIMUL (inaintea aplicatiei), ca sa castige la nume duplicat
+LOCAL lcProcExistent, lcCmdProc
+lcProcExistent = SET("PROCEDURE")
+lcCmdProc = [SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\probe_12b_s8_calea_2.prg"]
+IF !EMPTY(lcProcExistent)
+ lcCmdProc = lcCmdProc + ", " + lcProcExistent
+ENDIF
+&lcCmdProc
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+gnIdUtil = 8
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle)
+
+gnTransOriginal = SQLGETPROP(gnHandle, "Transactions")
+SQLSETPROP(gnHandle, "Transactions", 2)
+DO AfLog WITH "Transactions manual, original=" + TRANSFORM(gnTransOriginal)
+
+IF !actualizeaza_optiuni_program()
+ DO AfLog WITH "FAIL: actualizeaza_optiuni_program()"
+ DO Final
+ENDIF
+DO AfLog WITH "actualizeaza_optiuni_program OK, gnScadereStoc=" + TRANSFORM(NVL(gnScadereStoc, -1))
+
+SET PATH TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras" ADDITIVE
+SET CLASSLIB TO "D:\ROA\ROAFACTURARE\COMUN\utile\gridextras\gridextras.vcx" ADDITIVE
+SET CLASSLIB TO "D:\ROA\ROAFACTURARE\COMUN\clase\_cb_base.vcx" ADDITIVE
+DO AfLog WITH "SET CLASSLIB suplimentar OK"
+
+update_jtva_coloane([JV], [jtva_coloane_temp])
+
+*==========================================================================================
+* alegere date: politica de stoc curenta + articol OK (cont dedus) + articol problema (fara cont)
+* + o politica reala cu nota proprie valida (caz c) - acelasi tipar ca probe_12b_s8_cai_1_3.prg /
+* probe_12b_s8_verifica_linie.prg
+*==========================================================================================
+LOCAL lnOk, lnIdPolStoc, lnIdArtOk, lnIdArtProblema, lcDenOk, lcDenProblema, lnIdPolReal, lnIdArtReal
+LOCAL llGasitOk, llGasitProblema, llGasitPolReal, llGasitArtReal
+
+gcCaz = "[setup] "
+lnOk = SQLEXEC(gnHandle, "select varvalue from optiuni where program='ROAFACTURARE' and varname='ID_POL_PRET_STOC'", "crsopt")
+lnIdPolStoc = IIF(lnOk > 0 AND USED('crsopt') AND !ISNULL(crsopt.varvalue), VAL(ALLTRIM(crsopt.varvalue)), 0)
+IF USED('crsopt')
+ USE IN crsopt
+ENDIF
+DO Verdict WITH lnIdPolStoc > 0, "politica de stoc citita din OPTIUNI, id_pol=" + TRANSFORM(lnIdPolStoc)
+IF lnIdPolStoc <= 0
+ DO Final
+ENDIF
+PUBLIC gnId_pol_pret_stoc
+gnId_pol_pret_stoc = lnIdPolStoc
+
+* articol OK: rand al politicii de stoc, ID_NOTA propriu NULL, cont_venit_articol_stoc rezolvat
+lnOk = SQLEXEC(gnHandle, ;
+ "select a.id_articol from crm_politici_pret_art a " + ;
+ "where a.id_pol = " + TRANSFORM(lnIdPolStoc) + " and a.id_nota is null " + ;
+ "and pack_facturare.cont_venit_articol_stoc(a.id_articol) is not null and rownum = 1", "crsok")
+llGasitOk = lnOk > 0 AND USED('crsok') AND RECCOUNT('crsok') = 1
+lnIdArtOk = IIF(llGasitOk, crsok.id_articol, 0)
+IF USED('crsok')
+ USE IN crsok
+ENDIF
+DO AfLog WITH "articol OK ales: id_articol=" + TRANSFORM(lnIdArtOk)
+
+* articol problema: alt rand al politicii de stoc, ID_NOTA propriu NULL, fara cont dedus
+lnOk = SQLEXEC(gnHandle, ;
+ "select a.id_articol from crm_politici_pret_art a " + ;
+ "where a.id_pol = " + TRANSFORM(lnIdPolStoc) + " and a.id_nota is null " + ;
+ "and a.id_articol <> " + TRANSFORM(lnIdArtOk) + " " + ;
+ "and pack_facturare.cont_venit_articol_stoc(a.id_articol) is null and rownum = 1", "crsprob")
+llGasitProblema = lnOk > 0 AND USED('crsprob') AND RECCOUNT('crsprob') = 1
+lnIdArtProblema = IIF(llGasitProblema, crsprob.id_articol, 0)
+IF USED('crsprob')
+ USE IN crsprob
+ENDIF
+DO AfLog WITH "articol PROBLEMA ales: id_articol=" + TRANSFORM(lnIdArtProblema)
+
+* caz (c): o politica reala (<> politica de stoc) cu nota proprie valida (scc nenul) + un articol activ
+lnOk = SQLEXEC(gnHandle, ;
+ "select p.id_pol from crm_politici_preturi p " + ;
+ "join crm_note_vanzari v on v.id_nota = p.id_nota " + ;
+ "join note_contabile n on n.id_set = v.id_set and n.scc is not null " + ;
+ "where p.id_pol <> " + TRANSFORM(lnIdPolStoc) + " and rownum = 1", "crspolreal")
+llGasitPolReal = lnOk > 0 AND USED('crspolreal') AND RECCOUNT('crspolreal') = 1
+lnIdPolReal = IIF(llGasitPolReal, crspolreal.id_pol, 0)
+IF USED('crspolreal')
+ USE IN crspolreal
+ENDIF
+lnOk = SQLEXEC(gnHandle, "select id_articol from nom_articole where sters = 0 and rownum = 1", "crsartreal")
+llGasitArtReal = lnOk > 0 AND USED('crsartreal') AND RECCOUNT('crsartreal') = 1
+lnIdArtReal = IIF(llGasitArtReal, crsartreal.id_articol, 0)
+IF USED('crsartreal')
+ USE IN crsartreal
+ENDIF
+DO AfLog WITH "CAZ(c) ales: id_pol_real=" + TRANSFORM(lnIdPolReal) + " id_articol=" + TRANSFORM(lnIdArtReal)
+
+IF !llGasitOk OR !llGasitProblema OR !llGasitPolReal OR !llGasitArtReal
+ DO AfLog WITH "FAIL: date insuficiente in baza vie, opresc proba"
+ gnFail = gnFail + 1
+ DO Final
+ENDIF
+
+lnOk = SQLEXEC(gnHandle, "select denumire from nom_articole where id_articol = " + TRANSFORM(lnIdArtOk), "crsden1")
+lcDenOk = IIF(lnOk > 0 AND USED('crsden1') AND RECCOUNT('crsden1') = 1, ALLTRIM(NVL(crsden1.denumire, [])), [])
+IF USED('crsden1')
+ USE IN crsden1
+ENDIF
+lnOk = SQLEXEC(gnHandle, "select denumire from nom_articole where id_articol = " + TRANSFORM(lnIdArtProblema), "crsden2")
+lcDenProblema = IIF(lnOk > 0 AND USED('crsden2') AND RECCOUNT('crsden2') = 1, ALLTRIM(NVL(crsden2.denumire, [])), [])
+IF USED('crsden2')
+ USE IN crsden2
+ENDIF
+DO AfLog WITH "denumiri: OK=[" + lcDenOk + "] PROBLEMA=[" + lcDenProblema + "]"
+
+* politica de stoc cu ID_NOTA NULL (tranzactie, ROLLBACK la final) - fortez ramura "fara cont dedus"
+gcCaz = "[setup] "
+lnOk = SQLEXEC(gnHandle, "UPDATE crm_politici_preturi SET id_nota = NULL WHERE id_pol = " + TRANSFORM(lnIdPolStoc))
+DO Verdict WITH lnOk > 0, "UPDATE politica de stoc ID_NOTA=NULL (tranzactie, ROLLBACK la final) - lnOk=" + TRANSFORM(lnOk)
+
+*==========================================================================================
+* mediu formular: poDate, jtva_coloane, crsfactura gol, Createobject
+*==========================================================================================
+PRIVATE poDate, poGeneratorNumere
+LOCAL lnIdSet
+lnIdSet = 25000 + 30 - 1 + NVL(gnScadereStoc, 0) * 10
+poDate = CREATEOBJECT("oDateFactura", lnIdSet, 30)
+poDate.dataireg = DATE(gnAn, gnLuna, 10)
+poDate.dataact = poDate.dataireg
+poDate.zi_curs = poDate.dataireg
+poDate.id_client = 1
+poDate.nIdTipDoc = 6
+poGeneratorNumere = NULL
+DO AfLog WITH "poDate OK, tip=" + TRANSFORM(poDate.tip) + " id_pol=" + TRANSFORM(NVL(poDate.id_pol,-1)) + " in_valuta=" + TRANSFORM(poDate.in_valuta)
+
+IF USED('jtva_coloane')
+ USE IN jtva_coloane
+ENDIF
+IF NVL(poDate.tva_incasare, 0) = 0
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_ex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ELSE
+ SELECT * FROM jtva_coloane_temp WHERE ISNULL(id_jtva_neex) AND !'RORTC'$UPPER(coloana_jv) INTO CURSOR jtva_coloane
+ENDIF
+DO AfLog WITH "jtva_coloane Reccount=" + TRANSFORM(RECCOUNT('jtva_coloane'))
+
+DO PregatesteFacturaGoala
+
+LOCAL loForm
+loForm = CREATEOBJECT('frm_facturare_articole2')
+DO Verdict WITH VARTYPE(loForm) = 'O', "Createobject frm_facturare_articole2"
+IF VARTYPE(loForm) <> 'O'
+ DO Final
+ENDIF
+DO AfLog WITH "formular creat, nu afisat (fara Show())"
+
+*==========================================================================================
+* CAZ (a): toArticol fara Id_Pol, articol fara cont dedus -> refuz
+*==========================================================================================
+gcCaz = "[a-calea2-refuz] "
+LOCAL loArticol, lnReccountInainte
+
+loArticol = PregatesteToArticol(lnIdArtProblema, lcDenProblema, .F., 0)
+lnReccountInainte = RECCOUNT('crsfactura')
+gnSpionCount = 0
+gcSpionMesaje = ""
+
+LOCAL llRezA
+llRezA = loForm.do_adauga_articol_cautat(loArticol, loArticol.cantitate)
+
+DO Verdict WITH llRezA = .F., "do_adauga_articol_cautat = .F. (obtinut " + TRANSFORM(llRezA) + ")"
+DO Verdict WITH RECCOUNT('crsfactura') == lnReccountInainte, ;
+ "Reccount(crsfactura) neschimbat (" + TRANSFORM(RECCOUNT('crsfactura')) + ", era " + TRANSFORM(lnReccountInainte) + ")"
+DO Verdict WITH gnSpionCount >= 1, "spion: cel putin 1 mesaj (obtinut " + TRANSFORM(gnSpionCount) + ")"
+DO Verdict WITH lcDenProblema $ gcSpionMesaje, "mesajul contine denumirea articolului [" + lcDenProblema + "] - mesaj: [" + gcSpionMesaje + "]"
+
+*==========================================================================================
+* CAZ (b): toArticol fara Id_Pol, articol CU cont dedus -> linia se adauga cu Id_Pol = politica de stoc
+*==========================================================================================
+gcCaz = "[b-calea2-cont-dedus] "
+loArticol = PregatesteToArticol(lnIdArtOk, lcDenOk, .F., 0)
+DO Verdict WITH TYPE('loArticol.Id_Pol') = 'U', "toArticol FARA proprietatea Id_Pol (Type=" + TYPE('loArticol.Id_Pol') + ")"
+
+SELECT crsfactura
+APPEND BLANK
+lnReccountInainte = RECCOUNT('crsfactura')
+gnSpionCount = 0
+gcSpionMesaje = ""
+
+LOCAL llRezB
+llRezB = loForm.do_adauga_articol_cautat(loArticol, loArticol.cantitate)
+
+DO Verdict WITH llRezB = .T., "do_adauga_articol_cautat = .T. (obtinut " + TRANSFORM(llRezB) + ")"
+DO Verdict WITH gnSpionCount == 0, "spion: 0 mesaje (obtinut " + TRANSFORM(gnSpionCount) + ") - " + gcSpionMesaje
+DO Verdict WITH VARTYPE(crsfactura.Id_Pol) = 'N' AND crsfactura.Id_Pol == gnId_pol_pret_stoc, ;
+ "linia noua primeste Id_Pol = politica de stoc (" + TRANSFORM(gnId_pol_pret_stoc) + ", obtinut " + TRANSFORM(NVL(crsfactura.Id_Pol,-999)) + ")"
+
+*==========================================================================================
+* CAZ (c): toArticol CU Id_Pol = politica reala (<> politica de stoc) -> linia pastreaza politica reala
+*==========================================================================================
+gcCaz = "[c-calea2-politica-reala] "
+loArticol = PregatesteToArticol(lnIdArtReal, "articol-real", .T., lnIdPolReal)
+DO Verdict WITH TYPE('loArticol.Id_Pol') = 'N' AND loArticol.Id_Pol == lnIdPolReal, ;
+ "toArticol.Id_Pol = politica reala aleasa (" + TRANSFORM(lnIdPolReal) + ", obtinut " + TRANSFORM(NVL(loArticol.Id_Pol,-999)) + ")"
+
+SELECT crsfactura
+APPEND BLANK
+gnSpionCount = 0
+gcSpionMesaje = ""
+
+LOCAL llRezC
+llRezC = loForm.do_adauga_articol_cautat(loArticol, loArticol.cantitate)
+
+DO Verdict WITH llRezC = .T., "do_adauga_articol_cautat = .T. (obtinut " + TRANSFORM(llRezC) + ")"
+DO Verdict WITH gnSpionCount == 0, "spion: 0 mesaje (obtinut " + TRANSFORM(gnSpionCount) + ") - " + gcSpionMesaje
+DO Verdict WITH VARTYPE(crsfactura.Id_Pol) = 'N' AND crsfactura.Id_Pol == lnIdPolReal, ;
+ "linia noua pastreaza Id_Pol = politica reala (" + TRANSFORM(lnIdPolReal) + ", obtinut " + TRANSFORM(NVL(crsfactura.Id_Pol,-999)) + "), nu politica de stoc"
+
+IF VARTYPE(loForm) = 'O' AND !ISNULL(loForm)
+ loForm.Release()
+ENDIF
+loForm = NULL
+
+DO Final
+
+*==================================================================================================
+*-- spion amessagebox - contor + texte, incarcat PRIMUL (vezi SET PROCEDURE la inceput)
+FUNCTION amessagebox
+ LPARAMETERS tcMessage, tnDialogBoxType, tcTitle, tcFont, tnTimeOut, tnTimeoutValue
+ gnSpionCount = gnSpionCount + 1
+ gcSpionMesaje = gcSpionMesaje + "[" + TRANSFORM(tcMessage) + "]" + CHR(13) + CHR(10)
+ DO AfLog WITH " [spion amessagebox] " + TRANSFORM(tcMessage)
+ RETURN 6
+ENDFUNC
+
+*-- crsfactura gol, cu campul 'gestiune' suplimentar cerut de grd_factura.cGestiune (ca in
+*-- probe_12b_s8_cai_1_3.prg) - obligatoriu inainte de Createobject (legare ControlSource)
+PROCEDURE PregatesteFacturaGoala
+ IF USED('crsfactura')
+ USE IN crsfactura
+ ENDIF
+ creeaza_facturacrs([crsfactura])
+ SELECT *, CAST(NULL AS C(100)) AS gestiune FROM crsfactura INTO CURSOR crsfact_tmp READWRITE
+ USE IN crsfactura
+ SELECT * FROM crsfact_tmp INTO CURSOR crsfactura READWRITE
+ USE IN crsfact_tmp
+ENDPROC
+
+*-- toArticol: obiect echivalent unui Scatter Name pe crsCodmat/crsDenumire (structura reala,
+*-- creeaza_cursor_gol/reordoneaza din ofacturare.vc2, 20 coloane), fara/cu id_pol dupa caz
+FUNCTION PregatesteToArticol
+ LPARAMETERS tnIdArticol, tcDenumire, tlCuIdPol, tnIdPol
+ LOCAL lcCursor, loObj
+ IF USED('crstoart')
+ USE IN crstoart
+ ENDIF
+ IF m.tlCuIdPol
+ CREATE CURSOR crstoart (codmat C(100), denumire C(100), um C(10), pret N(20,4), ;
+ nume_val C(20), nume_lista_preturi C(100), proc_tvav N(20,4), codbare C(50), id_articol N(20), ;
+ id_pol N(20), gestionabil N(1), preturi_cu_tva N(1), tip_valuta N(1), curs N(20,4), ;
+ multiplicator N(10), id_valuta N(10), discount_unitar N(20,4), discount_unitar_val N(20,4), ;
+ cantitate N(20,4), pret_val N(20,4))
+ INSERT INTO crstoart (codmat, denumire, um, pret, nume_val, nume_lista_preturi, proc_tvav, codbare, ;
+ id_articol, id_pol, gestionabil, preturi_cu_tva, tip_valuta, curs, multiplicator, id_valuta, ;
+ discount_unitar, discount_unitar_val, cantitate, pret_val) ;
+ VALUES ([S8-4A], tcDenumire, [BUC], 100, [RON], [S8-4a], 1.19, [], tnIdArticol, ;
+ tnIdPol, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0)
+ ELSE
+ CREATE CURSOR crstoart (codmat C(100), denumire C(100), um C(10), pret N(20,4), ;
+ nume_val C(20), nume_lista_preturi C(100), proc_tvav N(20,4), codbare C(50), id_articol N(20), ;
+ gestionabil N(1), preturi_cu_tva N(1), tip_valuta N(1), curs N(20,4), ;
+ multiplicator N(10), id_valuta N(10), discount_unitar N(20,4), discount_unitar_val N(20,4), ;
+ cantitate N(20,4), pret_val N(20,4))
+ INSERT INTO crstoart (codmat, denumire, um, pret, nume_val, nume_lista_preturi, proc_tvav, codbare, ;
+ id_articol, gestionabil, preturi_cu_tva, tip_valuta, curs, multiplicator, id_valuta, ;
+ discount_unitar, discount_unitar_val, cantitate, pret_val) ;
+ VALUES ([S8-4A], tcDenumire, [BUC], 100, [RON], [S8-4a], 1.19, [], tnIdArticol, ;
+ 0, 0, 0, 1, 1, 1, 0, 0, 1, 0)
+ ENDIF
+ SELECT crstoart
+ GO TOP
+ SCATTER NAME loObj MEMO
+ RETURN loObj
+ENDFUNC
+
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ gnFail = gnFail + 1
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ IF TYPE('gnHandle') = 'N' AND gnHandle > 0
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk)
+ IF TYPE('gnTransOriginal') = 'N'
+ SQLSETPROP(gnHandle, "Transactions", gnTransOriginal)
+ ENDIF
+ ENDIF
+ DO AfLog WITH "TOTAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_12b_s8_verifica_linie.prg b/utile/Teste/facturare_unificat/probe_12b_s8_verifica_linie.prg
new file mode 100644
index 0000000..a449233
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_12b_s8_verifica_linie.prg
@@ -0,0 +1,213 @@
+* probe_12b_s8_verifica_linie.prg
+* Proba headless pentru ofacturare_comun.prg / verifica_cont_venit_linie (langa deriva_cont_venit_fara_pol).
+* Fara mock pe goExecutor - toate verificarile trec prin Oracle real (MARIUSM_AUTO), in tranzactie
+* manuala, ROLLBACK la final.
+*
+* Datele (articole, politici, note) se aleg din baza vie la rulare, nu sunt fixe - scrise in log.
+* Cazuri:
+* (1) politica reala (id_pol <> politica de stoc), cu nota proprie valida -> []
+* (2) politica de stoc, rand cu ID_NOTA propriu pe articol, valid -> []
+* (3) politica de stoc, rand fara ID_NOTA propriu, dar cont_venit_articol_stoc(articol) rezolvat -> []
+* (4) politica de stoc cu ID_NOTA NULL (fortat in tranzactie), rand fara ID_NOTA propriu, fara cont
+* dedus -> mesaj nevid, continand denumirea articolului
+*
+* Rulare: powershell -File ruleaza_suita.ps1 -Nume probe_12b_s8_verifica_linie (sau vfp9.exe -A -T direct)
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\s8_verifica_linie.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail, gnTransOriginal
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s8_verifica_linie.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+gnIdUtil = 8
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle)
+
+gnTransOriginal = SQLGETPROP(gnHandle, "Transactions")
+SQLSETPROP(gnHandle, "Transactions", 2)
+DO AfLog WITH "Transactions manual, original=" + TRANSFORM(gnTransOriginal)
+
+LOCAL lnOk, lnIdPolStoc, lnIdArtCaz1, lnIdPolCaz1, lnIdArtCaz2, lnIdPolArtCaz2, lnIdNotaCaz2, ;
+ lnIdArtCaz3, lnIdArtCaz4, lcMesaj, lcDenumireCaz4, ;
+ llGasitCaz1, llGasitArtCaz1, llGasitCaz2, llGasitNotaCaz2, llGasitCaz3, llGasitCaz4
+
+*==========================================================================================
+* alegere date: politica de stoc curenta
+*==========================================================================================
+gcCaz = "[setup] "
+lnOk = SQLEXEC(gnHandle, "select varvalue from optiuni where program='ROAFACTURARE' and varname='ID_POL_PRET_STOC'", "crsopt")
+lnIdPolStoc = IIF(lnOk > 0 AND USED('crsopt') AND !ISNULL(crsopt.varvalue), VAL(ALLTRIM(crsopt.varvalue)), 0)
+IF USED('crsopt')
+ USE IN crsopt
+ENDIF
+DO Verdict WITH lnIdPolStoc > 0, "politica de stoc citita din OPTIUNI, id_pol=" + TRANSFORM(lnIdPolStoc)
+IF lnIdPolStoc <= 0
+ DO Final
+ENDIF
+PUBLIC gnId_pol_pret_stoc
+gnId_pol_pret_stoc = lnIdPolStoc
+
+* caz (1): o politica reala cu nota proprie valida (scc nenul) - orice articol activ merge, ramura
+* reala nu foloseste randul din crm_politici_pret_art
+lnOk = SQLEXEC(gnHandle, ;
+ "select p.id_pol from crm_politici_preturi p " + ;
+ "join crm_note_vanzari v on v.id_nota = p.id_nota " + ;
+ "join note_contabile n on n.id_set = v.id_set and n.scc is not null " + ;
+ "where p.id_pol <> " + TRANSFORM(lnIdPolStoc) + " and rownum = 1", "crs1")
+llGasitCaz1 = lnOk > 0 AND USED('crs1') AND RECCOUNT('crs1') = 1
+lnIdPolCaz1 = IIF(llGasitCaz1, crs1.id_pol, 0)
+IF USED('crs1')
+ USE IN crs1
+ENDIF
+lnOk = SQLEXEC(gnHandle, "select id_articol from nom_articole where sters = 0 and rownum = 1", "crsart1")
+llGasitArtCaz1 = lnOk > 0 AND USED('crsart1') AND RECCOUNT('crsart1') = 1
+lnIdArtCaz1 = IIF(llGasitArtCaz1, crsart1.id_articol, 0)
+IF USED('crsart1')
+ USE IN crsart1
+ENDIF
+DO AfLog WITH "CAZ1 ales: id_pol=" + TRANSFORM(lnIdPolCaz1) + " id_articol=" + TRANSFORM(lnIdArtCaz1)
+
+* caz (2): rand existent al politicii de stoc, cu ID_NOTA propriu setat (in tranzactie) la o nota valida
+lnOk = SQLEXEC(gnHandle, ;
+ "select id_pol_art, id_articol from crm_politici_pret_art where id_pol = " + TRANSFORM(lnIdPolStoc) + " and rownum = 1", "crs2")
+llGasitCaz2 = lnOk > 0 AND USED('crs2') AND RECCOUNT('crs2') = 1
+lnIdPolArtCaz2 = IIF(llGasitCaz2, crs2.id_pol_art, 0)
+lnIdArtCaz2 = IIF(llGasitCaz2, crs2.id_articol, 0)
+IF USED('crs2')
+ USE IN crs2
+ENDIF
+lnOk = SQLEXEC(gnHandle, ;
+ "select v.id_nota from crm_note_vanzari v, note_contabile n " + ;
+ "where n.id_set = v.id_set and n.scc is not null and rownum = 1", "crs2b")
+llGasitNotaCaz2 = lnOk > 0 AND USED('crs2b') AND RECCOUNT('crs2b') = 1
+lnIdNotaCaz2 = IIF(llGasitNotaCaz2, crs2b.id_nota, 0)
+IF USED('crs2b')
+ USE IN crs2b
+ENDIF
+DO AfLog WITH "CAZ2 ales: id_pol_art=" + TRANSFORM(lnIdPolArtCaz2) + " id_articol=" + TRANSFORM(lnIdArtCaz2) + " id_nota_fortata=" + TRANSFORM(lnIdNotaCaz2)
+
+* caz (3): alt rand al politicii de stoc, ID_NOTA propriu NULL, cu cont_venit_articol_stoc rezolvat
+lnOk = SQLEXEC(gnHandle, ;
+ "select a.id_articol from crm_politici_pret_art a " + ;
+ "where a.id_pol = " + TRANSFORM(lnIdPolStoc) + " and a.id_nota is null " + ;
+ "and a.id_articol <> " + TRANSFORM(lnIdArtCaz2) + " " + ;
+ "and pack_facturare.cont_venit_articol_stoc(a.id_articol) is not null and rownum = 1", "crs3")
+llGasitCaz3 = lnOk > 0 AND USED('crs3') AND RECCOUNT('crs3') = 1
+lnIdArtCaz3 = IIF(llGasitCaz3, crs3.id_articol, 0)
+IF USED('crs3')
+ USE IN crs3
+ENDIF
+DO AfLog WITH "CAZ3 ales: id_articol=" + TRANSFORM(lnIdArtCaz3)
+
+* caz (4): alt rand al politicii de stoc, ID_NOTA propriu NULL, fara cont dedus
+lnOk = SQLEXEC(gnHandle, ;
+ "select a.id_articol from crm_politici_pret_art a " + ;
+ "where a.id_pol = " + TRANSFORM(lnIdPolStoc) + " and a.id_nota is null " + ;
+ "and a.id_articol not in (" + TRANSFORM(lnIdArtCaz2) + "," + TRANSFORM(lnIdArtCaz3) + ") " + ;
+ "and pack_facturare.cont_venit_articol_stoc(a.id_articol) is null and rownum = 1", "crs4")
+llGasitCaz4 = lnOk > 0 AND USED('crs4') AND RECCOUNT('crs4') = 1
+lnIdArtCaz4 = IIF(llGasitCaz4, crs4.id_articol, 0)
+IF USED('crs4')
+ USE IN crs4
+ENDIF
+DO AfLog WITH "CAZ4 ales: id_articol=" + TRANSFORM(lnIdArtCaz4)
+
+IF !llGasitCaz1 OR !llGasitArtCaz1 OR !llGasitCaz2 OR !llGasitNotaCaz2 OR !llGasitCaz3 OR !llGasitCaz4
+ DO AfLog WITH "FAIL: date insuficiente in baza vie pentru cele 4 cazuri, opresc proba"
+ gnFail = gnFail + 1
+ DO Final
+ENDIF
+
+*==========================================================================================
+* CAZ (1): politica reala -> []
+*==========================================================================================
+gcCaz = "[1-politica-reala] "
+lcMesaj = verifica_cont_venit_linie(lnIdArtCaz1, lnIdPolCaz1)
+DO Verdict WITH EMPTY(lcMesaj), "verifica_cont_venit_linie(" + TRANSFORM(lnIdArtCaz1) + "," + TRANSFORM(lnIdPolCaz1) + ") = [] (obtinut [" + lcMesaj + "])"
+
+*==========================================================================================
+* CAZ (2): politica de stoc, ID_NOTA pe rand -> []
+*==========================================================================================
+gcCaz = "[2-nota-pe-rand] "
+lnOk = SQLEXEC(gnHandle, "UPDATE crm_politici_pret_art SET id_nota = " + TRANSFORM(lnIdNotaCaz2) + " WHERE id_pol_art = " + TRANSFORM(lnIdPolArtCaz2))
+DO Verdict WITH lnOk > 0, "UPDATE id_nota pe rand (tranzactie, ROLLBACK la final) - lnOk=" + TRANSFORM(lnOk)
+lcMesaj = verifica_cont_venit_linie(lnIdArtCaz2, lnIdPolStoc)
+DO Verdict WITH EMPTY(lcMesaj), "verifica_cont_venit_linie(" + TRANSFORM(lnIdArtCaz2) + "," + TRANSFORM(lnIdPolStoc) + ") = [] (obtinut [" + lcMesaj + "])"
+
+*==========================================================================================
+* CAZ (3): politica de stoc, fara nota pe rand, cont dedus -> []
+*==========================================================================================
+gcCaz = "[3-cont-dedus] "
+lcMesaj = verifica_cont_venit_linie(lnIdArtCaz3, lnIdPolStoc)
+DO Verdict WITH EMPTY(lcMesaj), "verifica_cont_venit_linie(" + TRANSFORM(lnIdArtCaz3) + "," + TRANSFORM(lnIdPolStoc) + ") = [] (obtinut [" + lcMesaj + "])"
+
+*==========================================================================================
+* CAZ (4): politica de stoc cu ID_NOTA NULL, fara nota rand, fara cont dedus -> mesaj nevid
+*==========================================================================================
+gcCaz = "[4-fara-cont] "
+lnOk = SQLEXEC(gnHandle, "UPDATE crm_politici_preturi SET id_nota = NULL WHERE id_pol = " + TRANSFORM(lnIdPolStoc))
+DO Verdict WITH lnOk > 0, "UPDATE politica de stoc ID_NOTA=NULL (tranzactie, ROLLBACK la final) - lnOk=" + TRANSFORM(lnOk)
+lcMesaj = verifica_cont_venit_linie(lnIdArtCaz4, lnIdPolStoc)
+DO Verdict WITH !EMPTY(lcMesaj), "verifica_cont_venit_linie(" + TRANSFORM(lnIdArtCaz4) + "," + TRANSFORM(lnIdPolStoc) + ") <> [] (obtinut [" + lcMesaj + "])"
+
+lnOk = SQLEXEC(gnHandle, "select denumire from nom_articole where id_articol = " + TRANSFORM(lnIdArtCaz4), "crsden4")
+lcDenumireCaz4 = IIF(lnOk > 0 AND USED('crsden4') AND RECCOUNT('crsden4') = 1, ALLTRIM(NVL(crsden4.denumire,[])), [])
+IF USED('crsden4')
+ USE IN crsden4
+ENDIF
+DO Verdict WITH !EMPTY(lcDenumireCaz4) AND lcDenumireCaz4 $ lcMesaj, ;
+ "mesajul contine denumirea articolului ales [" + lcDenumireCaz4 + "] - mesaj: [" + lcMesaj + "]"
+
+DO Final
+
+*==================================================================================================
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ IF TYPE('gnHandle') = 'N' AND gnHandle > 0
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk)
+ IF TYPE('gnTransOriginal') = 'N'
+ SQLSETPROP(gnHandle, "Transactions", gnTransOriginal)
+ ENDIF
+ ENDIF
+ DO AfLog WITH "TOTAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/probe_vanzare_ui_cota_tva.prg b/utile/Teste/facturare_unificat/probe_vanzare_ui_cota_tva.prg
new file mode 100644
index 0000000..8c6b548
--- /dev/null
+++ b/utile/Teste/facturare_unificat/probe_vanzare_ui_cota_tva.prg
@@ -0,0 +1,258 @@
+* probe_vanzare_ui_cota_tva.prg
+* Proba headless pe pagina "Vanzare" din fisa articolului (COMUN\clase\onom_articole.vc2, clasa
+* frm_catalog_articole_nou) si pe clasa cus_pret_nomenclator (COMUN\programe\ofacturare_comun.prg):
+* combo-ul de cota TVA din tabela pe luni, pastrarea PROC_TVAV NULL ("ales la facturare"), cota
+* standard pe articol nou, recalculul pretului derivat si etichetele paginii.
+*
+* Fara dialoguri: formularul nu se arata niciodata (CREATEOBJECT fara Show()), iar AMESSAGEBOX e
+* inlocuit de mock-ul incarcat de test_init_env_auto_roafacturare.prg sub -A -T.
+* Fara scriere permanenta in Oracle: singura scriere (cazul NOMEN) se face in tranzactie manuala,
+* inchisa cu ROLLBACK.
+* Cazurile ruleaza in procese vfp9 separate - a doua instantiere a formularului in acelasi proces
+* se autoblocheaza (tiparul probe_12b_s6c_fisa_pagina_vanzare.prg).
+*
+* Articol de proba: 2528841557, pe politica 41 (PRETURI_CU_TVA = 0, PROC_TVAV = NULL).
+* Cotele lunii (comun.vcote_tva): 21/1.21, 19/1.19, 11/1.11, 0/1, apoi randul "".
+*
+* Rulare (form): powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume probe_vanzare_ui_cota_tva
+* Rulare (nomen): "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A -T probe_vanzare_ui_cota_tva.prg NOMEN
+* Log: D:\ROA\ROAFACTURARE\docs\loguri_12b\vanzare_ui_cota_tva.log (fiecare proces face APPEND)
+
+PARAMETERS tcModo
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+LOCAL lcMod
+lcMod = UPPER(ALLTRIM(IIF(VARTYPE(tcModo) = "C", tcModo, "")))
+IF EMPTY(lcMod)
+ lcMod = "FORM"
+ENDIF
+
+PUBLIC gcLog, gcCaz, gnPass, gnFail
+gcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\vanzare_ui_cota_tva.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("--- caz (" + lcMod + ") START " + TTOC(DATETIME()) + " ---" + CHR(13) + CHR(10), gcLog, 1)
+gcCaz = ""
+gnPass = 0
+gnFail = 0
+ON ERROR DO AfErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
+IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
+ DO AfLog WITH "FAIL: conexiune Oracle esuata"
+ DO Final
+ENDIF
+PUBLIC gnPc
+gnPc = 2
+gnIdUtil = 8
+gcNumeProgram = [ROAFACTURARE]
+DO AfLog WITH "ENV OK gnHandle=" + TRANSFORM(gnHandle) + " gnPc=" + TRANSFORM(gnPc) + " gnAn=" + TRANSFORM(gnAn) + " gnLuna=" + TRANSFORM(gnLuna) + " gnPc=" + TRANSFORM(gnPc)
+
+LOCAL lnIdArtProba, lnProcStd, lnCoefStd
+lnIdArtProba = 2528841557
+lnProcStd = GetProcTvaStandard()
+lnCoefStd = ROUND((lnProcStd + 100)/100, 4)
+DO AfLog WITH "cota standard " + TRANSFORM(gnLuna) + "/" + TRANSFORM(gnAn) + ": procent=" + TRANSFORM(lnProcStd) + " coeficient=" + TRANSFORM(lnCoefStd)
+
+DO CASE
+*=================================================================================================
+* Cazul FORM: pagina "Vanzare" - combo cota TVA din vcote_tva, etichete, recalcul
+*=================================================================================================
+CASE lcMod == "FORM"
+ * incarcare explicita din calea COMPLETA (tiparul S7a): ofacturare.vcx inainte de
+ * onom_articole.vcx, ca la instalarea reala
+ SET PATH TO (gcAppPath + "COMUN\CLASE") ADDITIVE
+ SET CLASSLIB TO (gcAppPath + "COMUN\CLASE\ofacturare.vcx") ADDITIVE
+ SET CLASSLIB TO (gcAppPath + "COMUN\CLASE\onom_articole.vcx") ADDITIVE
+
+ * precondition-urile pe care le face onomenclatoare.prg inainte sa deschida fisa
+ update_um()
+ update_um_iso()
+ update_grupe_art()
+ update_subgrupe_art()
+
+ gcCaz = "[form-precondition] "
+ LOCAL lnOk, loRec
+ lnOk = goExecutor.oExecuta('select * from vnom_articole where id_articol = ' + TRANSFORM(lnIdArtProba), 'vnom_articole_nou')
+ DO Verdict WITH lnOk # .F. AND USED('vnom_articole_nou') AND RECCOUNT('vnom_articole_nou') = 1, "SELECT vnom_articole pentru articolul de proba"
+ SELECT vnom_articole_nou
+ SCATTER NAME loRec MEMO
+ loRec.conditii_pastrare = NVL(loRec.conditii_pastrare,'')
+ USE IN vnom_articole_nou
+
+ lnOk = SQLEXEC(gnHandle, "select a.proc_tvav, nvl(p.preturi_cu_tva,0) ptva from crm_politici_pret_art a, crm_politici_preturi p where a.id_pol = p.id_pol and a.id_pol = 41 and a.id_articol = " + TRANSFORM(lnIdArtProba), "crsref")
+ DO Verdict WITH lnOk > 0 AND USED('crsref') AND RECCOUNT('crsref') = 1, "referinta directa proc_tvav / preturi_cu_tva pentru politica 41"
+ LOCAL llRefProcNull, lnRefPreturiCuTva
+ llRefProcNull = .F.
+ lnRefPreturiCuTva = -1
+ IF USED('crsref') AND RECCOUNT('crsref') = 1
+ llRefProcNull = ISNULL(crsref.proc_tvav)
+ lnRefPreturiCuTva = crsref.ptva
+ ENDIF
+ IF USED('crsref')
+ USE IN crsref
+ ENDIF
+ DO AfLog WITH " referinta: proc_tvav=" + IIF(llRefProcNull,"NULL",TRANSFORM(lnCoefStd)) + " preturi_cu_tva=" + TRANSFORM(lnRefPreturiCuTva)
+ DO Verdict WITH llRefProcNull, "preconditie: articolul de proba are PROC_TVAV NULL (cazul 'ales la facturare')"
+ DO Verdict WITH lnRefPreturiCuTva = 0, "preconditie: politica 41 are PRETURI_CU_TVA = 0 (referinta e pretul fara TVA)"
+
+ gcCaz = "[form-createobject] "
+ PRIVATE poRec, pnIdAMS
+ poRec = loRec
+ pnIdAMS = lnIdArtProba
+ LOCAL loForm, llCrapat, lcErrMsg, lnErrNo
+ llCrapat = .F.
+ lcErrMsg = ''
+ lnErrNo = 0
+ TRY
+ loForm = CREATEOBJECT('frm_catalog_articole_nou', loRec, lnIdArtProba, 'UPDATE')
+ CATCH TO loExc
+ llCrapat = .T.
+ lnErrNo = loExc.ErrorNo
+ lcErrMsg = loExc.Message
+ DO AfLog WITH " diagnostic exceptie: Procedure=[" + TRANSFORM(loExc.Procedure) + "] LineNo=" + TRANSFORM(loExc.LineNo) + " LineContents=[" + TRANSFORM(loExc.LineContents) + "] Details=[" + TRANSFORM(loExc.Details) + "]"
+ ENDTRY
+ DO AfLog WITH " rezultat CREATEOBJECT: llCrapat=" + TRANSFORM(llCrapat) + " errno=" + TRANSFORM(lnErrNo) + " mesaj=[" + lcErrMsg + "]"
+ DO Verdict WITH !llCrapat AND lnErrNo = 0, "CREATEOBJECT frm_catalog_articole_nou (UPDATE) trece (errno=0)"
+
+ IF !llCrapat
+ LOCAL loCb, lnI, lcLista
+
+ gcCaz = "[form-combo-cota] "
+ DO Verdict WITH loForm._pageframe1.PageCount = 3, "PageCount = 3 (Page3 Vanzare vizibila)"
+ DO Verdict WITH PEMSTATUS(loForm._pageframe1.Page3,"Cb_tx_proc_tvav",5), "controlul Cb_tx_proc_tvav exista pe Page3"
+ DO Verdict WITH PEMSTATUS(loForm._pageframe1.Page3,"Clb_tx_proc_tvav",5) = .F., "vechiul Clb_tx_proc_tvav (textbox) nu mai exista"
+ loCb = loForm._pageframe1.Page3.Cb_tx_proc_tvav._cbbase1
+ DO Verdict WITH UPPER(ALLTRIM(loCb.BaseClass)) = "COMBOBOX", "Cb_tx_proc_tvav._cbbase1 e ComboBox (obtinut " + ALLTRIM(loCb.BaseClass) + ")"
+ DO Verdict WITH loCb.RowSourceType = 2, "RowSourceType = 2 alias (obtinut " + TRANSFORM(loCb.RowSourceType) + ")"
+ DO Verdict WITH UPPER(ALLTRIM(loCb.RowSource)) = "CRS_COTE_TVA", "RowSource = crs_cote_tva (obtinut [" + loCb.RowSource + "])"
+ DO Verdict WITH USED('crs_cote_tva'), "cursorul crs_cote_tva e deschis"
+ DO Verdict WITH loCb.ListCount = 5, "ListCount = 5 (4 cote ale lunii + randul 'ales la facturare') (obtinut " + TRANSFORM(loCb.ListCount) + ")"
+ lcLista = ""
+ FOR lnI = 1 TO loCb.ListCount
+ lcLista = lcLista + "[" + ALLTRIM(loCb.List(lnI)) + "]"
+ ENDFOR
+ DO AfLog WITH " lista combo: " + lcLista
+ DO Verdict WITH ALLTRIM(loCb.List(1)) = "21.00", "primul rand afiseaza procentul 21 (obtinut [" + ALLTRIM(loCb.List(1)) + "])"
+ DO Verdict WITH ALLTRIM(loCb.List(loCb.ListCount)) = "", "ultimul rand e (obtinut [" + ALLTRIM(loCb.List(loCb.ListCount)) + "])"
+ DO Verdict WITH loCb.ListIndex = loCb.ListCount, "ListIndex pe randul 'ales la facturare' (PROC_TVAV NULL) (obtinut " + TRANSFORM(loCb.ListIndex) + ")"
+ DO Verdict WITH loForm._pageframe1.Page3.Cb_tx_proc_tvav.TabIndex = 3, "TabIndex Cb_tx_proc_tvav = 3"
+
+ gcCaz = "[form-date-neatinse] "
+ DO Verdict WITH ISNULL(loForm.oPretNom.nProcTvav), "nProcTvav a ramas NULL dupa Init (cota din baza nu a fost alterata) (obtinut " + IIF(ISNULL(loForm.oPretNom.nProcTvav),"NULL",TRANSFORM(loForm.oPretNom.nProcTvav)) + ")"
+ DO Verdict WITH loForm.oPretNom.lPreturiCuTva = .F., "lPreturiCuTva = .F. (politica 41)"
+
+ gcCaz = "[form-etichete] "
+ DO Verdict WITH loForm._pageframe1.Page3.Clb_tx_cont_dedus.Lb_simplu1.Caption = "Cont venit articol", "eticheta contului de venit = 'Cont venit articol' (obtinut [" + loForm._pageframe1.Page3.Clb_tx_cont_dedus.Lb_simplu1.Caption + "])"
+ DO Verdict WITH loForm._pageframe1.Page3.Clb_tx_pret_ftva.Lb_simplu1.Caption = "Pret fara TVA (pret lista)", "eticheta pretului de referinta = 'Pret fara TVA (pret lista)' (obtinut [" + loForm._pageframe1.Page3.Clb_tx_pret_ftva.Lb_simplu1.Caption + "])"
+ DO Verdict WITH loForm._pageframe1.Page3.Clb_tx_pret_ftva.Lb_simplu1.FontBold, "eticheta pretului de referinta e FontBold"
+ DO Verdict WITH loForm._pageframe1.Page3.Clb_tx_pret_ctva.Lb_simplu1.Caption = "Pret cu TVA", "eticheta celuilalt pret = 'Pret cu TVA' (obtinut [" + loForm._pageframe1.Page3.Clb_tx_pret_ctva.Lb_simplu1.Caption + "])"
+ DO Verdict WITH !loForm._pageframe1.Page3.Clb_tx_pret_ctva.Lb_simplu1.FontBold, "eticheta celuilalt pret NU e FontBold"
+ DO Verdict WITH PEMSTATUS(loForm._pageframe1.Page3,"Lb_info_conturi",5), "controlul Lb_info_conturi exista pe Page3"
+ DO Verdict WITH loForm._pageframe1.Page3.Lb_info_conturi.Caption = "Necompletate: debit 4111, credit contul de venit al articolului", "textul informativ al conturilor (obtinut [" + loForm._pageframe1.Page3.Lb_info_conturi.Caption + "])"
+
+ gcCaz = "[form-interactive-change] "
+ SELECT crs_cote_tva
+ LOCATE FOR !ISNULL(proc_tva) AND proc_tva = lnCoefStd
+ DO Verdict WITH FOUND(), "randul cotei standard (" + TRANSFORM(lnCoefStd) + ") gasit in crs_cote_tva"
+ loCb.ListIndex = RECNO()
+ loForm.oPretNom.nPretFtva = 100
+ loForm.oPretNom.nPretCtva = 0
+ loCb.InteractiveChange()
+ DO Verdict WITH ROUND(NVL(loForm.oPretNom.nProcTvav,0),4) = lnCoefStd, "InteractiveChange a scris coeficientul " + TRANSFORM(lnCoefStd) + " in nProcTvav (obtinut " + TRANSFORM(loForm.oPretNom.nProcTvav) + ")"
+ DO Verdict WITH ROUND(loForm.oPretNom.nPretCtva,2) = ROUND(100 * lnCoefStd,2), "pretul derivat recalculat de combo: 100 fara TVA -> " + TRANSFORM(ROUND(100 * lnCoefStd,2)) + " cu TVA (obtinut " + TRANSFORM(loForm.oPretNom.nPretCtva) + ")"
+
+ gcCaz = "[form-recalcul] "
+ loForm.oPretNom.nProcTvav = .NULL.
+ DO Verdict WITH loForm.oPretNom.recalculeaza_pret(100, .T.) = ROUND(100 * lnCoefStd, gnPc), "recalculeaza_pret cu cota lipsa (NULL) foloseste cota standard a lunii: 100 -> " + TRANSFORM(ROUND(100 * lnCoefStd, gnPc)) + " (obtinut " + TRANSFORM(loForm.oPretNom.recalculeaza_pret(100, .T.)) + ")"
+ loForm.oPretNom.nProcTvav = 1.21
+ DO Verdict WITH loForm.oPretNom.recalculeaza_pret(100, .T.) = 121, "recalculeaza_pret(100,.T.) cu coeficientul 1.21 = 121 (obtinut " + TRANSFORM(loForm.oPretNom.recalculeaza_pret(100, .T.)) + ")"
+ DO Verdict WITH loForm.oPretNom.recalculeaza_pret(121, .F.) = 100, "recalculeaza_pret(121,.F.) = 100 (reciproc, obtinut " + TRANSFORM(loForm.oPretNom.recalculeaza_pret(121, .F.)) + ")"
+
+ RELEASE loForm
+ ENDIF
+
+*=================================================================================================
+* Cazul NOMEN: clasa cus_pret_nomenclator - cota standard pe articol nou, PROC_TVAV NULL salvat
+*=================================================================================================
+CASE lcMod == "NOMEN"
+ gcCaz = "[nomen-articol-nou] "
+ LOCAL loPN
+ loPN = CREATEOBJECT('cus_pret_nomenclator')
+ DO Verdict WITH VARTYPE(loPN) = "O", "cus_pret_nomenclator instantiat"
+ DO Verdict WITH loPN.incarca(0), "incarca(0) (articol nou) = .T."
+ DO Verdict WITH !ISNULL(loPN.nProcTvav) AND ROUND(loPN.nProcTvav,4) = lnCoefStd, "articol nou: nProcTvav = coeficientul standard " + TRANSFORM(lnCoefStd) + " (obtinut " + TRANSFORM(loPN.nProcTvav) + ")"
+ DO Verdict WITH loPN.nPretFtva = 0 AND loPN.nPretCtva = 0, "articol nou: preturile pornesc de la 0"
+ DO Verdict WITH loPN.recalculeaza_pret(100, .T.) = ROUND(100 * lnCoefStd, gnPc), "articol nou: 100 fara TVA -> " + TRANSFORM(ROUND(100 * lnCoefStd, gnPc)) + " cu TVA"
+ DO Verdict WITH loPN.recalculeaza_pret(ROUND(100 * lnCoefStd, gnPc), .F.) = 100, "articol nou: revenire la 100 fara TVA (reciproc)"
+
+ gcCaz = "[nomen-articol-existent-null] "
+ LOCAL loPE
+ loPE = CREATEOBJECT('cus_pret_nomenclator')
+ DO Verdict WITH loPE.incarca(lnIdArtProba), "incarca(" + TRANSFORM(lnIdArtProba) + ") = .T."
+ DO Verdict WITH ISNULL(loPE.nProcTvav), "articol existent cu PROC_TVAV NULL: nProcTvav ramane NULL (obtinut " + IIF(ISNULL(loPE.nProcTvav),"NULL",TRANSFORM(loPE.nProcTvav)) + ")"
+ DO Verdict WITH loPE.lPreturiCuTva = .F., "lPreturiCuTva = .F. pentru politica 41"
+ DO Verdict WITH loPE.recalculeaza_pret(100, .T.) = ROUND(100 * lnCoefStd, gnPc), "cota lipsa: recalculeaza_pret foloseste cota standard (100 -> " + TRANSFORM(ROUND(100 * lnCoefStd, gnPc)) + ") (obtinut " + TRANSFORM(loPE.recalculeaza_pret(100, .T.)) + ")"
+
+ gcCaz = "[nomen-salvare-proc-tvav-null] "
+ LOCAL lnTransOrig, lnOk2
+ lnTransOrig = SQLGETPROP(gnHandle, "Transactions")
+ SQLSETPROP(gnHandle, "Transactions", 2)
+ loPE.nPretFtva = 50
+ loPE.nPretCtva = 60.5
+ DO Verdict WITH ISNULL(loPE.nProcTvav), "preconditie: nProcTvav e NULL inainte de salveaza()"
+ DO Verdict WITH loPE.salveaza(lnIdArtProba), "salveaza() = .T. cu PROC_TVAV NULL"
+ lnOk2 = SQLEXEC(gnHandle, "select proc_tvav, pretftva, pretctva from crm_politici_pret_art where id_pol = 41 and id_articol = " + TRANSFORM(lnIdArtProba), "crsnull")
+ DO Verdict WITH lnOk2 > 0 AND USED('crsnull') AND RECCOUNT('crsnull') = 1, "randul din crm_politici_pret_art citit in tranzactie"
+ IF USED('crsnull') AND RECCOUNT('crsnull') = 1
+ DO Verdict WITH ISNULL(crsnull.proc_tvav), "Oracle: PROC_TVAV a ramas NULL dupa salvare"
+ DO Verdict WITH ROUND(crsnull.pretftva,2) = 50, "Oracle: PRETFTVA = 50 (obtinut " + TRANSFORM(crsnull.pretftva) + ")"
+ DO Verdict WITH ROUND(crsnull.pretctva,2) = 60.5, "Oracle: PRETCTVA = 60.5 (obtinut " + TRANSFORM(crsnull.pretctva) + ")"
+ ENDIF
+ IF USED('crsnull')
+ USE IN crsnull
+ ENDIF
+ lnOk2 = SQLEXEC(gnHandle, "ROLLBACK")
+ SQLSETPROP(gnHandle, "Transactions", lnTransOrig)
+ DO Verdict WITH lnOk2 > 0, "ROLLBACK dupa verificare (datele de proba nu raman)"
+ENDCASE
+
+DO Final
+
+PROCEDURE Verdict
+ LPARAMETERS tlCond, tcMsg
+ IF tlCond
+ gnPass = gnPass + 1
+ DO AfLog WITH "PASS: " + gcCaz + tcMsg
+ ELSE
+ gnFail = gnFail + 1
+ DO AfLog WITH "FAIL: " + gcCaz + tcMsg
+ ENDIF
+ENDPROC
+
+PROCEDURE AfLog
+ LPARAMETERS tcMsg
+ STRTOFILE(tcMsg + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC
+
+PROCEDURE AfErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + gcCaz + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
+ENDPROC
+
+PROCEDURE Final
+ LOCAL lnOk
+ gcCaz = "[final] "
+ IF TYPE('gnHandle') = 'N' AND gnHandle > 0
+ lnOk = SQLEXEC(gnHandle, "ROLLBACK")
+ DO AfLog WITH "ROLLBACK lnOk=" + TRANSFORM(lnOk) + " (plasa de siguranta)"
+ ENDIF
+ DO AfLog WITH "PARTIAL PASS=" + TRANSFORM(gnPass) + " FAIL=" + TRANSFORM(gnFail)
+ DO AfLog WITH "END " + TTOC(DATETIME())
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/s6c4_compile.prg b/utile/Teste/facturare_unificat/s6c4_compile.prg
new file mode 100644
index 0000000..de6c14e
--- /dev/null
+++ b/utile/Teste/facturare_unificat/s6c4_compile.prg
@@ -0,0 +1,23 @@
+* s6c4_compile.prg
+* Compilare headless onom_articole.vcx dupa garda NULL la INSERT (id_tara_origine).
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+lcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s6c4_compile.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
+ON ERROR DO CErr WITH ERROR(), MESSAGE(), LINENO()
+
+SET DEFAULT TO "D:\ROA\ROAFACTURARE\COMUN\clase"
+COMPILE CLASSLIB onom_articole.vcx
+STRTOFILE("COMPILE OK" + CHR(13) + CHR(10), lcLog, 1)
+STRTOFILE("END " + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
+QUIT
+
+PROCEDURE CErr
+LPARAMETERS tnErr, tcMsg, tnLine
+STRTOFILE("COMPILE FAIL " + TRANSFORM(tnErr) + " " + tcMsg + " line=" + TRANSFORM(tnLine) + CHR(13) + CHR(10), lcLog, 1)
+QUIT
diff --git a/utile/Teste/facturare_unificat/s7b2_compile.prg b/utile/Teste/facturare_unificat/s7b2_compile.prg
new file mode 100644
index 0000000..50eebd0
--- /dev/null
+++ b/utile/Teste/facturare_unificat/s7b2_compile.prg
@@ -0,0 +1,35 @@
+* s7b2_compile.prg - plan #12b, S7b-2: COMPILE CLASSLIB headless pe ofacturare.vcx dupa
+* write-back-ul textului (nota implicita a politicii de stoc in optiuni). Fara Oracle -
+* COMPILE CLASSLIB nu are nevoie de conexiune, doar verifica sintaxa claselor.
+*
+* Rulare: powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume s7b2_compile
+* Log: out\s7b2_compile.log (copiat apoi in docs\loguri_12b\s7b2_compile.log)
+
+SET SAFETY OFF
+SET TALK OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcVcx
+gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\s7b2_compile.log"
+gcVcx = "D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare.vcx"
+
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+
+ON ERROR DO s7b2_err WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+COMPILE CLASSLIB (gcVcx)
+
+IF FILE(STRTRAN(gcVcx, ".vcx", ".err"))
+ STRTOFILE("COMPILE ESEC" + CHR(13) + CHR(10), gcLog, 1)
+ STRTOFILE(FILETOSTR(STRTRAN(gcVcx, ".vcx", ".err")), gcLog, 1)
+ELSE
+ STRTOFILE("COMPILE OK" + CHR(13) + CHR(10), gcLog, 1)
+ENDIF
+
+QUIT
+
+PROCEDURE s7b2_err
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ STRTOFILE("EROARE " + TRANSFORM(tnErr) + " " + tcMsg + " in " + tcProg + " linia " + TRANSFORM(tnLine) + CHR(13) + CHR(10), gcLog, 1)
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/s8_3_compile.prg b/utile/Teste/facturare_unificat/s8_3_compile.prg
new file mode 100644
index 0000000..d842a1d
--- /dev/null
+++ b/utile/Teste/facturare_unificat/s8_3_compile.prg
@@ -0,0 +1,40 @@
+* s8_3_compile.prg - plan #12b, S8-3: COMPILE CLASSLIB headless pe ofacturare.vcx dupa
+* write-back-ul verificarii de cont de venit pe cele trei cai de adaugare a liniei.
+* Fara Oracle - COMPILE CLASSLIB nu are nevoie de conexiune, doar verifica sintaxa claselor.
+*
+* Rulare: vfp9.exe -A -T s8_3_compile.prg
+* Log: out\s8_3_compile.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET TABLEPROMPT OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcVcx
+gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\s8_3_compile.log"
+gcVcx = "D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare.vcx"
+
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+
+ON ERROR DO s8_3_err WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+IF FILE(STRTRAN(gcVcx, ".vcx", ".err"))
+ DELETE FILE (STRTRAN(gcVcx, ".vcx", ".err"))
+ENDIF
+
+COMPILE CLASSLIB (gcVcx)
+
+IF FILE(STRTRAN(gcVcx, ".vcx", ".err"))
+ STRTOFILE("COMPILE ESEC" + CHR(13) + CHR(10), gcLog, 1)
+ STRTOFILE(FILETOSTR(STRTRAN(gcVcx, ".vcx", ".err")), gcLog, 1)
+ELSE
+ STRTOFILE("COMPILE OK" + CHR(13) + CHR(10), gcLog, 1)
+ENDIF
+
+QUIT
+
+PROCEDURE s8_3_err
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ STRTOFILE("EROARE " + TRANSFORM(tnErr) + " " + tcMsg + " in " + tcProg + " linia " + TRANSFORM(tnLine) + CHR(13) + CHR(10), gcLog, 1)
+ QUIT
+ENDPROC
diff --git a/utile/Teste/facturare_unificat/s8_4a_compile.prg b/utile/Teste/facturare_unificat/s8_4a_compile.prg
new file mode 100644
index 0000000..40daec2
--- /dev/null
+++ b/utile/Teste/facturare_unificat/s8_4a_compile.prg
@@ -0,0 +1,23 @@
+* s8_4a_compile.prg
+* Compilare headless ofacturare.vcx dupa write-back S8-4a (toArticol.Id_Pol in do_adauga_articol_cautat).
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+lcLog = "D:\ROA\ROAFACTURARE\docs\loguri_12b\s8_4a_compile.log"
+IF !DIRECTORY("D:\ROA\ROAFACTURARE\docs\loguri_12b")
+ MD "D:\ROA\ROAFACTURARE\docs\loguri_12b"
+ENDIF
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
+ON ERROR DO CErr WITH ERROR(), MESSAGE(), LINENO()
+
+SET DEFAULT TO "D:\ROA\ROAFACTURARE\COMUN\clase"
+COMPILE CLASSLIB ofacturare.vcx
+STRTOFILE("COMPILE OK" + CHR(13) + CHR(10), lcLog, 1)
+STRTOFILE("END " + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
+QUIT
+
+PROCEDURE CErr
+LPARAMETERS tnErr, tcMsg, tnLine
+STRTOFILE("COMPILE FAIL " + TRANSFORM(tnErr) + " " + tcMsg + " line=" + TRANSFORM(tnLine) + CHR(13) + CHR(10), lcLog, 1)
+QUIT
diff --git a/utile/Teste/facturare_unificat/vanzare_ui_compile.prg b/utile/Teste/facturare_unificat/vanzare_ui_compile.prg
new file mode 100644
index 0000000..6d4579f
--- /dev/null
+++ b/utile/Teste/facturare_unificat/vanzare_ui_compile.prg
@@ -0,0 +1,57 @@
+* vanzare_ui_compile.prg
+* Compilare headless a fisierelor atinse de pagina "Vanzare" din fisa articolului: class library
+* onom_articole.vcx (clasa frm_catalog_articole_nou, combo cota TVA) si programul
+* ofacturare_comun.prg (clasa cus_pret_nomenclator). Fara Oracle - verifica doar sintaxa.
+*
+* Rulare: powershell -ExecutionPolicy Bypass -File ruleaza_suita.ps1 -Nume vanzare_ui_compile
+* Log: out\vanzare_ui_compile.log
+
+SET SAFETY OFF
+SET TALK OFF
+SET NOTIFY OFF
+CLOSE DATABASES
+
+PUBLIC gcLog, gcCaz, lnErori
+gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\vanzare_ui_compile.log"
+gcCaz = ""
+lnErori = 0
+
+STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog)
+ON ERROR DO CErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
+
+DO Compileaza WITH "D:\ROA\ROAFACTURARE\COMUN\clase", "onom_articole.vcx"
+DO Compileaza WITH "D:\ROA\ROAFACTURARE\COMUN\programe", "ofacturare_comun.prg"
+
+STRTOFILE("REZULTAT erori=" + TRANSFORM(lnErori) + CHR(13) + CHR(10), gcLog, 1)
+STRTOFILE("END " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog, 1)
+QUIT
+
+PROCEDURE Compileaza
+ LPARAMETERS tcDir, tcFisier
+ LOCAL lcCale, lcErr
+ lcCale = ADDBS(tcDir) + tcFisier
+ lcErr = STRTRAN(lcCale, ".vcx", ".err")
+ lcErr = STRTRAN(lcErr, ".prg", ".err")
+ IF FILE(lcErr)
+ DELETE FILE (lcErr)
+ ENDIF
+ SET DEFAULT TO (tcDir)
+ IF UPPER(JUSTEXT(tcFisier)) = "VCX"
+ COMPILE CLASSLIB (tcFisier)
+ ELSE
+ COMPILE (tcFisier)
+ ENDIF
+ IF FILE(lcErr)
+ lnErori = lnErori + 1
+ STRTOFILE("COMPILE ESEC " + tcFisier + CHR(13) + CHR(10), gcLog, 1)
+ STRTOFILE(FILETOSTR(lcErr), gcLog, 1)
+ ELSE
+ STRTOFILE("COMPILE OK " + tcFisier + CHR(13) + CHR(10), gcLog, 1)
+ ENDIF
+ENDPROC
+
+PROCEDURE CErr
+ LPARAMETERS tnErr, tcMsg, tcProg, tnLine
+ lnErori = lnErori + 1
+ STRTOFILE("EROARE " + TRANSFORM(tnErr) + " " + tcMsg + " in " + tcProg + " linia " + TRANSFORM(tnLine) + CHR(13) + CHR(10), gcLog, 1)
+ENDPROC