Files
comun/utile/Teste/facturare_unificat/test_s4e_3_linie_libera.prg
Marius Mutu 8e022d332e #13: formular de facturare unificat - etapa curenta
Squash al branch-ului de lucru plan13-s2.

Clase: ofacturare (nucleul formularului unificat), ofacturare_comun,
ferestre_cere_date, ocomenzi, caut_ora (lista de preturi in combo-urile de
cautare), omodificari.

Programe: ofacturare impartit - ofacturare_antet, ofacturare_rutare_scriere si
ogrid_latimi sunt fisiere noi; oproceduri_facturare primeste discountul pe linie
si cota standard de TVA cand articolul nu are cota pe politica.

Documentatie: capcana SQLExec no_data_found, conventia de encoding, depanarea
testelor VFP si regulile de lucru - conflictele cu modificarile venite din alte
proiecte sunt rezolvate pastrand ambele parti.

Loguri de rulare a testelor scoase din versionare; testele raman.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
2026-09-09 21:38:25 +03:00

307 lines
13 KiB
Plaintext

* test_s4e_3_linie_libera.prg
* Headless: S4e-3 - validarea de cantitate/stoc pentru linia libera adaugata prin combosql (cautare in
* lista de preturi/registru), pe frm_facturare_articole2 (COMUN\clase\ofacturare.vc2),
* do_adauga_articol_cautat (introdusa la S4-3b, azi extinsa cu apelul do_verifica_articol).
*
* Executa metoda REALA (nu recalculeaza in paralel): APPEND BLANK pe crsfactura (simuleaza But_nou1),
* apoi do_adauga_articol_cautat(loArticol, loArticol.cantitate) - identic cu apelul din LostFocus
* (grd_factura.cCodMat.cboCodmat / cDenumire.cCboDenumire, ofacturare.vc2:21514/:21541).
*
* poArticol e construit dintr-un cursor local cu structura identica cu cursorul brut al cautarii
* (mock_cursor_preturi.prg / cursor_preturi din pack_facturare, 24 coloane) - FARA Oracle si FARA
* combosql_cautare.RefreshData; Oracle nu are ce sa valideze aici (validarea e locala, pe randul deja
* adus). Formularul tot are nevoie de parintele combosql (SET CLASSLIB _cb_base.vcx ADDITIVE) ca sa
* se poata face CREATEOBJECT fara eroare de clasa - combosql_cautare insasi traieste azi direct in
* ofacturare.vc2 (mutata acolo la 30.08.2026, commit e2ee622), nu mai exista ofacturare_cautare.prg.
*
* Gatare disjuncta verificata explicit: tipurile S4e-3 (3,4,21,25,28,42,47) primesc validarea noua;
* tipul 1 (lista de preturi, perimetrul plafonului Rol B - S4-5, poveste separata) NU o primeste -
* cazul ROL_B_DISJUNCT arata ca acelasi articol cu cantitate 0 intra necontestat pe tip 1, exact ca
* inaintea acestei sarcini, si ca do_initializeaza_articol ii zeroeste cantitatea (:19646-19648) -
* spre deosebire de tipurile S4e-3, unde cantitatea ramane cea reala (nu 0) dupa acceptare.
*
* Cazuri:
* STOC_ZERO_T3 tip=3 gest=1 cant=0 -> refuz, linia NU intra (crsfactura revine la 0 randuri)
* STOC_NEGATIV_T3 tip=3 gest=1 cant=-5 -> refuz (aceeasi conditie, cantitate<=0)
* STOC_SUFICIENT_T3 tip=3 gest=1 cant=10 -> accept, intra cu pret/TVA/id_jtva_coloana si
* cantitate REALA (10, nu 0)
* NEGESTIONABIL_T3 tip=3 gest=0 cant=0 -> accept (fara plafon pe articol negestionabil)
* STOC_ZERO_T4 tip=4 gest=1 cant=0 -> refuz (factura din avize)
* STOC_SUFICIENT_T21 tip=21 gest=1 cant=5 -> accept (aviz catre clienti din comanda)
* ROL_B_DISJUNCT_T1 tip=1 gest=1 cant=0 -> accept FARA nicio validare (gatare disjuncta;
* cantitate ajunge 0 in crsfactura - zeroita de
* do_initializeaza_articol, comportament neschimbat)
*
* amessagebox e mocat (mock_validare_antet.prg) ca sa nu apara dialogul real; textul capturat se
* verifica sa fie cel neschimbat "Acest articol nu este pe stoc!" (decizia Marius, nu se schimba).
*
* Rulare: vfp9.exe -A -T "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\test_s4e_3_linie_libera.prg"
* Log: D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\test_s4e_3_linie_libera.log
* Mediu: ROA_CENTRAL / MARIUSM_AUTO; gnIdUtil = 8 inainte de creeaza_cursor_serii; gnScadereStoc = 1.
SET SAFETY OFF
SET TALK OFF
SET NOTIFY OFF
PUBLIC gcLog, gnFail, gnPass, gnErr, gcCaz, gcErr
PUBLIC gcMockApeluri, gnMockNumar, gcMockSql, gnMockSucces, gnMockEroare, gcMockMod, gcMockCurs
PUBLIC gnMockRaspuns, gcMockDuplicat, goExecutorReal
PUBLIC gnPc, gnPVal, gnPPretV, gnScadereStoc, gnMemProcDisc
gcLog = "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\out\test_s4e_3_linie_libera.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)
gnFail = 0
gnPass = 0
gnErr = 0
gcCaz = ""
gcErr = ""
gcMockApeluri = ""
gnMockNumar = 0
gcMockSql = ""
gnMockSucces = 1
gnMockEroare = 0
gcMockMod = "PLIN"
gcMockCurs = ""
gnMockRaspuns = 6
gcMockDuplicat = ""
gnPc = 2
gnPVal = 2
gnPPretV = 4
gnScadereStoc = 1
gnMemProcDisc = 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
LOCAL lcProc
lcProc = SET("PROCEDURE")
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\mock_validare_antet.prg", ;
"D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_unificat\mock_generator_numere.prg", ;
&lcProc
IF !actualizeaza_optiuni_program()
DO AfLog WITH "FAIL: actualizeaza_optiuni_program()"
DO Final
ENDIF
gnIdUtil = 8
gnPc = 2
gnPVal = 2
gnPPretV = 4
gnScadereStoc = 1
gnMemProcDisc = 0
goExecutor.oExecuta([begin pack_sesiune.set_Id_Util(?gnIdUtil); end;])
DO AfLog WITH "ENV OK, gnAn=" + TRANSFORM(gnAn) + " gnLuna=" + TRANSFORM(gnLuna)
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
* combosql_cautare traieste azi in ofacturare.vc2 insusi (mutata acolo la 30.08.2026, commit
* e2ee622) - nu mai exista ofacturare_cautare.prg separat, deci nu mai e nimic de inregistrat
* suplimentar aici; SET CLASSLIB _cb_base.vcx de mai sus ramane necesar (parintele combosql).
* jtva_coloane: cursorul folosit de derivarea id_jtva_coloana din proc_tvav (do_adauga_articol_cautat)
IF USED('jtva_coloane')
USE IN jtva_coloane
ENDIF
CREATE CURSOR jtva_coloane (id_jtva_coloana N(14), denumire C(50), cota_tva N(6,2))
INSERT INTO jtva_coloane VALUES (190, 'TVA 19%', 19)
INSERT INTO jtva_coloane VALUES (210, 'TVA 21%', 21)
INSERT INTO jtva_coloane VALUES (110, 'TVA 11%', 11)
GO TOP IN jtva_coloane
PRIVATE poDate, poGeneratorNumere, plVizibil, pnTotalDiscountAvize
plVizibil = .F.
pnTotalDiscountAvize = 0
poGeneratorNumere = CREATEOBJECT("oGeneratorMock")
poDate = NULL
DO Caz WITH "STOC_ZERO_T3", 3, 1, 0, .T., 101, "CM101"
DO Caz WITH "STOC_NEGATIV_T3", 3, 1, -5, .T., 102, "CM102"
DO Caz WITH "STOC_SUFICIENT_T3", 3, 1, 10, .F., 103, "CM103"
DO Caz WITH "NEGESTIONABIL_T3", 3, 0, 0, .F., 104, "CM104"
DO Caz WITH "STOC_ZERO_T4", 4, 1, 0, .T., 105, "CM105"
DO Caz WITH "STOC_SUFICIENT_T21",21, 1, 5, .F., 106, "CM106"
DO Caz WITH "ROL_B_DISJUNCT_T1", 1, 1, 0, .F., 107, "CM107"
DO Final
*----------------------------------------------------------------------------------------
* tcCaz, tnTip, tnGestionabil, tnCantitate, tlAsteptatRefuz, tnIdArticol, tcCodmat
PROCEDURE Caz
LPARAMETERS tcCaz, tnTip, tnGestionabil, tnCantitate, tlAsteptatRefuz, tnIdArticol, tcCodmat
LOCAL loForm, llRezultat, loArticol
gcCaz = "[" + tcCaz + "] "
DO AfLog WITH "PAS: " + gcCaz
DO Reseteaza WITH tnTip
loForm = CREATEOBJECT('frm_facturare_articole2')
DO Assert WITH VARTYPE(loForm) = 'O', "Createobject frm_facturare_articole2"
IF VARTYPE(loForm) <> 'O'
RETURN
ENDIF
loArticol = CreeazaArticolCautat(tnIdArticol, tcCodmat, tnGestionabil, tnCantitate)
SELECT crsfactura
APPEND BLANK
DO Assert WITH RECCOUNT('crsfactura') = 1, "crsfactura are o linie goala (But_nou1) inainte de adaugare"
gcMockApeluri = ""
llRezultat = loForm.do_adauga_articol_cautat(loArticol, loArticol.cantitate)
IF tlAsteptatRefuz
DO Assert WITH !llRezultat, "Return .F. (refuz) asteptat"
DO Assert WITH RECCOUNT('crsfactura') = 0, "linia NU intra in crsfactura dupa refuz"
DO Assert WITH "amessagebox(" $ gcMockApeluri, "mesaj de stoc afisat (mocat)"
DO Assert WITH "nu este pe stoc" $ LOWER(gcMockApeluri), "textul mesajului ramane cel de azi, neschimbat"
ELSE
DO Assert WITH llRezultat, "Return .T. (accept) asteptat"
DO Assert WITH RECCOUNT('crsfactura') = 1, "do_adauga_articol_cautat NU a adaugat o a doua linie"
DO Assert WITH !("amessagebox(" $ gcMockApeluri), "niciun mesaj de stoc la acceptare"
DO Assert WITH crsfactura.id_articol = tnIdArticol, "crsfactura.id_articol corect"
DO Assert WITH ALLTRIM(crsfactura.codmat) == tcCodmat, "crsfactura.codmat corect"
DO Assert WITH crsfactura.proc_tvav = 1.19, "crsfactura.proc_tvav = 1.19 (pastrat din randul cautat)"
DO Assert WITH crsfactura.pretftva = 50, "crsfactura.pretftva = 50 (valoare reala, nu 0 - capcana FACT-013)"
DO Assert WITH crsfactura.id_jtva_coloana = 190, "crsfactura.id_jtva_coloana = 190 (derivat din proc_tvav=1.19)"
IF tnTip = 1
DO Assert WITH crsfactura.cantitate = 0, "ROL_B_DISJUNCT: cantitate ZEROITA de do_initializeaza_articol (tip 1 e in grupul :19646) - neschimbat de S4e-3"
ELSE
DO Assert WITH crsfactura.cantitate = tnCantitate, "cantitate REALA pastrata (tip S4e-3 nu e in grupul zeroit de do_initializeaza_articol)"
ENDIF
ENDIF
loForm.Release()
RELEASE loForm
ENDPROC
*----------------------------------------------------------------------------------------
* construieste poArticol exact ca randul scaterat dintr-un cursor brut de cursor_preturi
* (structura identica cu mock_cursor_preturi.prg / cursor_preturi din pack_facturare)
FUNCTION CreeazaArticolCautat
LPARAMETERS tnIdArticol, tcCodmat, tnGestionabil, tnCantitate
LOCAL loArticol
IF USED('crstestarticols4e3')
USE IN crstestarticols4e3
ENDIF
CREATE CURSOR crstestarticols4e3 (id_c N(20), id_articol N(20), lot C(20) NULL, serie C(20) NULL, ;
id_pol N(20), id_valuta N(10), nume_lista_preturi C(100), discount_unitar N(20,4), ;
discount_unitar_val N(20,4), codmat C(100), codbare C(50), denumire C(100), um C(10), ;
gestionabil N(1), cantitate N(20,4), proc_tvav N(20,4), preturi_cu_tva N(1), ;
curs N(20,4), multiplicator N(10), pret N(20,4), pret_val N(20,4), tip_valuta N(1), ;
nume_val C(20), modificabil N(1))
INSERT INTO crstestarticols4e3 VALUES (0, tnIdArticol, NULL, NULL, 31, 1, "LISTA TEST", 0, 0, ;
tcCodmat, "CB" + TRANSFORM(tnIdArticol), "Articol test " + TRANSFORM(tnIdArticol), "BUC", ;
tnGestionabil, tnCantitate, 1.19, 0, 1, 1, 50, 50, 1, "RON", 1)
GO TOP IN crstestarticols4e3
SCATTER NAME loArticol MEMO
USE IN crstestarticols4e3
RETURN loArticol
ENDFUNC
*----------------------------------------------------------------------------------------
PROCEDURE Reseteaza
LPARAMETERS tnTip
LOCAL lnIdSet
DO Inchide WITH 'crsarticole'
DO Inchide WITH 'crsarticole1'
DO Inchide WITH 'crsfactura'
DO Inchide WITH 'crscursuri'
DO Inchide WITH 'crspolitici'
DO Inchide WITH 'crscontracte'
DO Inchide WITH 'crsgestiunidest'
DO Inchide WITH 'crsCtrTemp'
DO Inchide WITH 'CrsCotaTva'
DO Inchide WITH 'scrsCodmat'
DO Inchide WITH 'crsCodmat'
DO Inchide WITH 'scrsDenumire'
DO Inchide WITH 'crsDenumire'
SELECT 0
IF !USED('saft_tip_facturi')
CREATE CURSOR saft_tip_facturi (cod N(3) NULL, tip_saftname C(200) NULL)
INSERT INTO saft_tip_facturi (cod, tip_saftname) VALUES (NULL, '')
INDEX ON cod TAG cod
ENDIF
DO creeaza_facturacrs WITH '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
gcMockApeluri = ""
gcMockSql = ""
gcMockCurs = ""
gcErr = ""
gnMockNumar = 100
gnMockRaspuns = 6
gcMockDuplicat = ""
gcMockMod = "PLIN"
gnMockSucces = 1
gnMockEroare = 0
lnIdSet = 26000 + tnTip
poDate = NULL
poDate = CREATEOBJECT("oDateFactura", lnIdSet, tnTip)
poDate.dataireg = DATE(gnAn, gnLuna, 1)
poDate.dataact = poDate.dataireg
poDate.zi_curs = poDate.dataireg
poDate.id_fdoc = 1
poDate.fdoc = "FEL TEST"
poDate.nract = 77
poDate.serie_act = "TST"
poDate.id_client = 1
poDate.id_furnizor = 1
poDate.nrfactachi = 1
poDate.id_valuta = 1
poDate.in_valuta = 0
poDate.listaid = "1"
poGeneratorNumere.ResetNumere()
poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(poDate.nIdTipDoc)
gcMockApeluri = ""
ENDPROC
PROCEDURE Inchide
LPARAMETERS tcAlias
IF USED(tcAlias)
USE IN (tcAlias)
ENDIF
ENDPROC
PROCEDURE Assert
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
gcErr = gcErr + TRANSFORM(tnErr) + " " + tcMsg + " (" + TRANSFORM(tcProg) + ":" + TRANSFORM(tnLine) + ")" + CHR(13) + CHR(10)
gnErr = gnErr + 1
DO AfLog WITH "ERROR " + TRANSFORM(tnErr) + " [" + tcProg + ":" + TRANSFORM(tnLine) + "] " + tcMsg
ENDPROC
PROCEDURE Final
IF TYPE('goExecutorReal') = 'O'
goExecutor = goExecutorReal
ENDIF
DO AfLog WITH "TOTAL pass=" + TRANSFORM(gnPass) + " fail=" + TRANSFORM(gnFail) + " err=" + TRANSFORM(gnErr)
DO AfLog WITH "END " + TTOC(DATETIME())
QUIT
ENDPROC