#6 editare factura emisa: S5 - scrierea sumelor editate in Oracle

La salvarea unei facturi deja emise, modificarile facute liniilor de articole
se scriu acum real in VANZARI_DETALII, in aceeasi tranzactie cu restul salvarii,
si totalurile documentului se recalculeaza din liniile efectiv salvate.

- ofacturare_editare.prg: helper nou ScrieArticoleFacturaEditate. Idiomul e
  "marcheaza tot sters, invie ce ramane", nu delta, pentru ca
  actualizeaza_vanzari face UPDATE ... SET STERS = 0 pe tot documentul, fara
  garda; o scriere delta ar lasa liniile sterse sa reinvie la fiecare salvare.
  Cursor gol = no-op, ca o eroare la incarcare sa nu goleasca factura.
- comun.vc2, ofacturare_comun.vc2: agatarea apelului dupa
  finalizeaza_modificare_nota si inainte de inchiderea tranzactiei, in ambele
  puncte de intrare.
- omodificari.vc2: coloana Pret achizitie in grid, editabila doar pe liniile
  noi; liniile de set devin needitabile, cu marcaj; cinci validari la salvare.
- teste: cinci suite noi (validari, grid UI, scriere reala, discount/valuta,
  rollback, al doilea punct de intrare) si asteptari actualizate in
  test_page3_articole.
- docs: oracle_export.md - exportul all_source cere linesize 32767, altfel
  rupe liniile lungi prin mijlocul identificatorilor; scripturi-migrare-db.md -
  UpdateVersiune adauga singur extensia .sql.

Cere scripturile ff_2026_08_09_01 (PACK_FACTURARE) si ff_2026_08_09_02
(VVANZARI_ARTICOLE).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
This commit is contained in:
2026-08-10 01:37:12 +03:00
parent b9eba29ebe
commit 1c42ae0af4
13 changed files with 3408 additions and 60 deletions

View File

@@ -0,0 +1,415 @@
* test_s5_al_doilea_intrare.prg
* Inchide golul "al doilea punct de intrare" din docs\livrare_s5.md, sectiunea 5: agatarea din
* comun.vc2:2491-2493 (afisjurcom.do_modifica, "Registrul jurnal" ROACONT/ROAGEST, textual identica
* cu cea din ofacturare_comun.vc2:3828-3830, deja testata cu scriere reala in test_s5_scriere_reala.prg)
* nu trecuse inca prin nicio scriere reala.
*
* Diferenta functionala fata de do_editare_factura (frm_facturi), singura care conteaza pentru acest
* test: afisjurcom.do_modifica NU apeleaza IncarcaVanzareDinNota direct - apeleaza
* PregatesteArticoleFacturaEditare('tact') (comun.vc2:2436) INAINTE de Createobject(frm_modific2024),
* care populeaza tvanz (si crsArticoleFactura) pe alta cale de cod. Testul reproduce EXACT secventa
* comun.vc2:2222-2569 (do_modifica), mai putin partea de UI (grid-ul actjur, frm_modific2024 - nu
* garda "Used('tvanz') And Reccount('tvanz')=1" testata prin PregatesteArticoleFacturaEditare reala,
* nici SCAN pe articole, care ramane la verificarea vizuala a lui Marius, per briefing), pe aceeasi
* nota folosita deja de test_s5_scriere_reala.prg/test_s5_discount_valuta.prg (id_vanzare=1049) -
* SINGURA din documentele de test cunoscute care are simultan rand real in VANZARI si nota in luna
* curenta (cerinta lui afisjurcom.do_modifica, linia 2265-2268).
*
* Fara nicio modificare de articole (ca in blocul C din test_s5_discount_valuta.prg): dovedeste ca
* PE ACEASTA CALE lnSucces ajunge > 0 dupa finalizeaza_modificare_nota, garda noua se satisface real
* (nu doar static) si ScrieArticoleFacturaEditate se executa cu tvanz.id_vanzare corect. Tranzactia
* se inchide cu COMMIT (Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1)), comun.vc2:2541) - lantul
* reuseste, deci NU ROLLBACK (spre deosebire de celelalte suite S5 cu esec provocat deliberat).
*
* ATENTIE - GASIT SI REPARAT IN TIMPUL SCRIERII ACESTUI TEST (nu ramane in fisierul final): o prima
* varianta apela ScrieArticoleFacturaEditate FARA sa incarce intai 'tvd' (frm_modific2024, sarit aici
* deliberat, e cel care il populeaza in fluxul real, din crsArticoleFactura). Garda externa
* (Used('tvanz') And Reccount('tvanz')=1) s-a satisfacut, dar garda INTERNA de no-op a helperului
* (!Used('tvd')) a facut din apel un no-op TACUT (intoarce tot .T.) - fara sa corecteze reset-ul
* STERS=0 pe care actualizeaza_vanzari il face pe TOT documentul (acelasi mecanism documentat in
* rec_s5_scriere_reala.md), iar tranzactia a COMMIS reset-ul necorectat: o linie definitiv stearsa
* in testele anterioare (det=1582, id_vanzare=1049) a fost reinviata real in Oracle. Reparat imediat
* (UPDATE vanzari_detalii SET STERS=1 WHERE id_vanzare_det=1582, COMMIT, verificat prin sqlplus) -
* varianta finala incarca 'tvd' cu IncarcaArticoleFactura chiar dupa PregatesteArticoleFacturaEditare
* (ca sa reproduca ce ar face Load()-ul lui frm_modific2024), deci helperul chiar corecteaza reset-ul,
* la fel ca in fluxul real. CONSUMA UN COD (finalizeaza_modificare_nota il realoca la orice salvare,
* chiar fara modificari de articole - acelasi efect ca blocul C din test_s5_discount_valuta.prg).
*
* Harness: do_deschide/inchide_tranzactie reproduse inline dupa _frm_base.vc2:252-302 (identic cu
* celelalte suite S5 cu scriere reala). Nu atinge cod de aplicatie, nu instantiaza afisjurcom sau
* frm_modific2024 (evita riscul de UI blocanta headless). QUIT la final.
SET SAFETY OFF
SET TALK OFF
LOCAL lcLog
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s5_al_doilea_intrare_log.txt'
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
PUBLIC gcErrLog, gcTestLog, gnPass, gnFail
gcErrLog = lcLog
gcTestLog = lcLog
gnPass = 0
gnFail = 0
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
QUIT
ENDIF
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\oscrie_in_fisiere.prg ADDITIVE
PUBLIC gnIdVanzareTest
gnIdVanzareTest = 1049
DO test_al_doilea_intrare WITH gnIdVanzareTest, lcLog
STRTOFILE(CHR(13) + CHR(10) + 'REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
QUIT
PROCEDURE asserteaza
LPARAMETERS tcNume, tlConditie, tcValoare
IF m.tlConditie
gnPass = gnPass + 1
STRTOFILE('PASS ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
ELSE
gnFail = gnFail + 1
STRTOFILE('FAIL ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
ENDIF
ENDPROC
*-- executa SELECT-ul prin goExecutor (cai care CITESC - fara risc) si intoarce codul de succes
PROCEDURE ExecSel
LPARAMETERS tcSql, tcCursor
LOCAL lnQ
IF USED(tcCursor)
USE IN (tcCursor)
ENDIF
lnQ = goExecutor.oExecute(tcSql, tcCursor)
RETURN lnQ
ENDPROC
*-- reproduce _frm_base.vc2:252-265 (do_deschide_tranzactie / Thisform.do_deschide_tranzactie()),
*-- fara sa instantieze niciun formular
PROCEDURE MyDeschideTranzactie
LOCAL llReturn, lnSuccesLocal
IF TYPE('goExecutor') = 'O'
goExecutor.oExecuta([select * from dual])
ENDIF
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 2)
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
RETURN llReturn
ENDPROC
*-- reproduce _frm_base.vc2:279-302 (do_inchide_tranzactie / Thisform.do_inchide_tranzactie()),
*-- fara sa instantieze niciun formular
PROCEDURE MyInchideTranzactie
LPARAMETERS tnTip
LOCAL llReturn, lnSuccesLocal
IF tnTip = 1
lnSuccesLocal = SQLCOMMIT(gnHandle)
ELSE
lnSuccesLocal = SQLROLLBACK(gnHandle)
ENDIF
IF lnSuccesLocal < 0
llReturn = .F.
ELSE
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 1)
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
ENDIF
RETURN llReturn
ENDPROC
PROCEDURE test_al_doilea_intrare
LPARAMETERS tnIdVanzare, tcLog
*-- pnAn/pnLuna/lnCod/lnIdFact/lnIdfactd/lnIdSet/pdDataOra PRIVATE - finalizeaza_modificare_nota
*-- foloseste ?pnLuna/?pnAn/?pdDataOra ca bind-variabile in josul stivei (comun.vc2:2487-2488)
PRIVATE pnAn, pnLuna, lnCod, lnIdFact, lnIdfactd, lnIdSet, pdDataOra
LOCAL lcSql, lnQ, lnSters, llEProforma, llSters, llGestInvantar, llRul, lnSucces
LOCAL lnCodInainte, lnCodDupa, lnDiscInainte, lnFtvaInainte, lnTvaInainte, lnCtvaInainte
LOCAL lnDiscDupa, lnFtvaDupa, lnTvaDupa, lnCtvaDupa, lnNrLiniiInainte, lnNrLiniiDupa
LOCAL llBlocExecutat
llBlocExecutat = .F.
STRTOFILE(CHR(13) + CHR(10) + '========== al doilea punct de intrare (afisjurcom.do_modifica, comun.vc2:2222-2569), ' + ;
'id_vanzare=' + TRANSFORM(tnIdVanzare) + ' ==========' + CHR(13) + CHR(10), tcLog, 1)
*-- starea documentului INAINTE, citita direct din VANZARI (echivalentul "cod-ul se realoca la fiecare salvare")
lcSql = [select cod, nvl(sters,0) as sters, discount, total_fara_tva, total_tva, total_cu_tva, ] + ;
[extract(year from data_act) as anact, extract(month from data_act) as lunaact ] + ;
[from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecSel(lcSql, 'v_vz0')
IF lnQ <= 0 OR RECCOUNT('v_vz0') <> 1
DO asserteaza WITH '0: VANZARI citit', .F., 'lnQ=' + TRANSFORM(lnQ)
RETURN
ENDIF
SELECT v_vz0
lnCod = cod
lnCodInainte = cod
lnDiscInainte = NVL(discount, 0)
lnFtvaInainte = total_fara_tva
lnTvaInainte = total_tva
lnCtvaInainte = total_cu_tva
USE IN v_vz0
lcSql = [select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ and sters = 0]
lnQ = ExecSel(lcSql, 'v_cnt0')
lnNrLiniiInainte = IIF(lnQ > 0, v_cnt0.nr, -1)
USE IN v_cnt0
STRTOFILE(' VANZARI inainte: cod=' + TRANSFORM(lnCodInainte) + ' discount=' + TRANSFORM(lnDiscInainte) + ;
' ftva=' + TRANSFORM(lnFtvaInainte) + ' tva=' + TRANSFORM(lnTvaInainte) + ' ctva=' + TRANSFORM(lnCtvaInainte) + ;
' linii active=' + TRANSFORM(lnNrLiniiInainte) + CHR(13) + CHR(10), tcLog, 1)
*-- 1) "Select actjur" (comun.vc2:2253-2263) - un rand din vact_tot, exact ca gridul registrului jurnal
lcSql = [select cod, an, luna, id_set, sters, id_fact, id_factd, dataora from vact_tot ] + ;
[where cod = ] + TRANSFORM(lnCod) + [ and rownum = 1]
lnQ = ExecSel(lcSql, 'actjur')
IF lnQ <= 0 OR RECCOUNT('actjur') <> 1
DO asserteaza WITH '1: actjur (randul din registrul jurnal) gasit pentru cod=' + TRANSFORM(lnCod), .F., 'lnQ=' + TRANSFORM(lnQ)
RETURN
ENDIF
SELECT actjur
pnAn = an
pnLuna = luna
lnIdSet = id_set
lnSters = sters
lnIdFact = id_fact
lnIdfactd = id_factd
pdDataOra = NULL
STRTOFILE(' actjur: cod=' + TRANSFORM(lnCod) + ' an/luna=' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ;
' id_set=' + TRANSFORM(lnIdSet) + ' sters=' + TRANSFORM(lnSters) + ' id_fact=' + TRANSFORM(lnIdFact) + CHR(13) + CHR(10), tcLog, 1)
*-- 2) garzile din do_modifica (comun.vc2:2265-2290), fara UI
DO asserteaza WITH '2: nota din luna curenta (garda comun.vc2:2265)', (pnAn * 12) + pnLuna = (gnAn * 12) + gnLuna, ;
TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ' vs curent ' + TRANSFORM(gnAn) + '/' + TRANSFORM(gnLuna)
IF (pnAn * 12) + pnLuna <> (gnAn * 12) + gnLuna
RETURN
ENDIF
DO asserteaza WITH '3: id_set NU e in intervalul ROAPRODUCTIE (30000-30009, comun.vc2:2278)', !BETWEEN(lnIdSet, 30000, 30009), TRANSFORM(lnIdSet)
IF BETWEEN(lnIdSet, 30000, 30009)
RETURN
ENDIF
llSters = (lnSters = 1)
DO asserteaza WITH '4: nota nu e deja stearsa (llSters=.F.)', !llSters, TRANSFORM(lnSters)
llGestInvantar = (lnIdSet = 90101)
DO asserteaza WITH '5: nu e nota de inventariere (id_set<>90101, ramura pdDataOra=actjur.dataora nu se activeaza)', !llGestInvantar, TRANSFORM(lnIdSet)
IF llGestInvantar
pdDataOra = actjur.dataora
ENDIF
*-- 3) cursoarele notei (actactan/tact/trul/trul_obinv) - identic cu comun.vc2:2313-2427,
*-- deja extras ca helper si folosit de test_s5_scriere_reala.prg pe aceeasi nota
IF !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.)
DO asserteaza WITH '6: IncarcaCursoareModificareNota', .F., 'a esuat'
RETURN
ENDIF
DO asserteaza WITH '6: nota are randuri in actactan/tact', RECCOUNT('actactan') > 0, TRANSFORM(RECCOUNT('actactan'))
IF RECCOUNT('actactan') = 0
RETURN
ENDIF
*-- 4) cu_Tva pe tact - a doua reasignare, comun.vc2:2433 (identica cu ofacturare_comun.vc2/test_s5_scriere_reala.prg)
SELECT a.*, IIF(NVL(id_jtva_coloana, 0) = 0, 0, 1) AS cu_Tva FROM tact a INTO CURSOR tact READWRITE
*-- 5) PregatesteArticoleFacturaEditare('tact') - comun.vc2:2436, DIFERENTA functionala fata de
*-- ofacturare_comun.vc2/do_editare_factura (care apeleaza IncarcaVanzareDinNota direct); aici
*-- populeaza tvanz SI crsArticoleFactura, calea specifica acestui punct de intrare
IF USED('tvanz')
USE IN tvanz
ENDIF
IF USED('crsArticoleFactura')
USE IN crsArticoleFactura
ENDIF
LOCAL llGasitTvanz
llGasitTvanz = PregatesteArticoleFacturaEditare('tact')
DO asserteaza WITH '7: PregatesteArticoleFacturaEditare gaseste documentul in VANZARI (calea specifica acestui punct de intrare)', ;
llGasitTvanz, TRANSFORM(llGasitTvanz)
DO asserteaza WITH '8: garda noua satisfacuta REAL (nu static): Used(tvanz) And Reccount(tvanz)=1', ;
USED('tvanz') AND RECCOUNT('tvanz') = 1, 'Used=' + TRANSFORM(USED('tvanz')) + ' Reccount=' + IIF(USED('tvanz'), TRANSFORM(RECCOUNT('tvanz')), '-')
DO asserteaza WITH '9: tvanz.id_vanzare corect (populat de PregatesteArticoleFacturaEditare, nu presupus)', ;
USED('tvanz') AND RECCOUNT('tvanz') = 1 AND tvanz.id_vanzare = tnIdVanzare, ;
IIF(USED('tvanz') AND RECCOUNT('tvanz') = 1, TRANSFORM(tvanz.id_vanzare), 'tvanz gol')
DO asserteaza WITH '10: crsArticoleFactura precarcat (acelasi apel)', USED('crsArticoleFactura'), TRANSFORM(USED('crsArticoleFactura'))
*-- frm_modific2024 SARIT (nu se instantiaza - risc de UI blocanta headless, verificare vizuala
*-- ramane la Marius, per briefing); buton=1 fortat direct, ca in celelalte suite S5. In fluxul
*-- real, Load()-ul formularului populeaza 'tvd' din crsArticoleFactura - reprodus aici explicit,
*-- FARA nicio modificare, ca ScrieArticoleFacturaEditate sa nu fie no-op (vezi ATENTIE din antet)
IF USED('tvd')
USE IN tvd
ENDIF
IncarcaArticoleFactura(tnIdVanzare, 'tvd')
DO asserteaza WITH '10b: tvd incarcat cu liniile active reale (ca Load()-ul lui frm_modific2024)', ;
USED('tvd') AND RECCOUNT('tvd') = lnNrLiniiInainte, 'Reccount=' + IIF(USED('tvd'), TRANSFORM(RECCOUNT('tvd')), '-') + ' asteptat=' + TRANSFORM(lnNrLiniiInainte)
*-- 6) ramura buton=1 (comun.vc2:2447-2493), copiata identic; llRul=.T. neconditionat (:2449,
*-- "este posibil sa modific si rul, rul_obinv" - asa cum scrie codul, nu dupa Reccount(trul))
llRul = .T.
lnSucces = 0
TRY
IF MyDeschideTranzactie()
SELECT actactan
IF !llSters
lnSucces = OSCRIE_IN_FISIERE(2, .T., llRul)
ELSE
lnSucces = 1
ENDIF
STRTOFILE(' OSCRIE_IN_FISIERE(2,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
IF lnSucces > 0
IF USED('actactan')
USE IN actactan
ENDIF
SELECT tact
IF gnAn >= IIF(TYPE('gnAnFormNou') = 'U', 2007, gnAnFormNou)
REPLACE id_jtva_coloana WITH NULL, proc_tva WITH 0 FOR cu_Tva = 0
ENDIF
SELECT * FROM tact INTO CURSOR actactan READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
IF llRul
IF USED('rul_temp')
USE IN RUL_TEMP
ENDIF
SELECT * FROM trul INTO CURSOR RUL_TEMP READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
IF USED('rul_temp_obinv')
USE IN RUL_TEMP_OBINV
ENDIF
SELECT * FROM trul_obinv INTO CURSOR RUL_TEMP_OBINV READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
ENDIF
lnSucces = OSCRIE_IN_FISIERE(0, .T., llRul)
STRTOFILE(' OSCRIE_IN_FISIERE(0,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
ENDIF
IF lnSucces > 0
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,?pdDataOra,] + ALLTRIM(STR(lnIdSet)) + [,] + ;
ALLTRIM(STR(lnCod)) + [,] + ALLTRIM(STR(lnIdFact)) + [,] + ALLTRIM(STR(lnIdfactd)) + [,?gnIdUtil); end;]
lnSucces = IIF(goExecutor.oExecuta(lcSql), 1, -1)
STRTOFILE(' finalizeaza_modificare_nota => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
ENDIF
DO asserteaza WITH '11: lantul pana la finalizeaza_modificare_nota a reusit (lnSucces>0)', lnSucces > 0, 'lnSucces=' + TRANSFORM(lnSucces)
*-- blocul nou, comun.vc2:2491-2493, identic textual cu ofacturare_comun.vc2:3828-3830
IF lnSucces > 0 AND "OFACTURARE_EDITARE" $ UPPER(SET("Procedure")) AND USED('tvanz') AND RECCOUNT('tvanz') = 1
llBlocExecutat = .T.
lnSucces = IIF(ScrieArticoleFacturaEditate(tvanz.id_vanzare, 'tvd', 'tvanz'), 1, -1)
STRTOFILE(' ScrieArticoleFacturaEditate => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
ELSE
STRTOFILE(' ATENTIE: blocul ScrieArticoleFacturaEditate NU s-a executat' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
*-- comun.vc2:2541 - Thisform.do_inchide_tranzactie(Iif(lnSucces<0,2,1))
IF MyInchideTranzactie(IIF(lnSucces < 0, 2, 1))
STRTOFILE(' tranzactie inchisa cu ' + IIF(lnSucces < 0, 'ROLLBACK', 'COMMIT') + CHR(13) + CHR(10), tcLog, 1)
ELSE
STRTOFILE(' FAIL la inchiderea tranzactiei' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
ELSE
STRTOFILE(' FAIL: deschiderea tranzactiei a esuat' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
CATCH TO loExc
STRTOFILE(' EXCEPTIE in lantul de scriere: ' + TRANSFORM(loExc.ErrorNo) + ' [' + loExc.Message + '] ' + ;
loExc.Procedure + ':' + TRANSFORM(loExc.LineNo) + ' -> ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
lnSucces = -99
MyInchideTranzactie(2)
ENDTRY
DO asserteaza WITH '12: blocul ScrieArticoleFacturaEditate S-A EXECUTAT pe aceasta cale (garda satisfacuta)', ;
llBlocExecutat, TRANSFORM(llBlocExecutat)
DO asserteaza WITH '13: lantul complet (inclusiv ScrieArticoleFacturaEditate prin acest punct de intrare) a reusit', ;
lnSucces > 0, 'lnSucces=' + TRANSFORM(lnSucces)
IF USED('actactan')
USE IN actactan
ENDIF
IF USED('tact')
USE IN tact
ENDIF
IF USED('rul_temp')
USE IN rul_temp
ENDIF
IF USED('trul')
USE IN trul
ENDIF
IF USED('rul_temp_obinv')
USE IN rul_temp_obinv
ENDIF
IF USED('trul_obinv')
USE IN trul_obinv
ENDIF
IF USED('crsArticoleFactura')
USE IN crsArticoleFactura
ENDIF
IF USED('tvd')
USE IN tvd
ENDIF
IF USED('tvanz')
USE IN tvanz
ENDIF
IF USED('actjur')
USE IN actjur
ENDIF
*-- verificare de fond: lantul a COMIS (lnSucces>0) - COD-ul se realoca (ca in blocul C din
*-- test_s5_discount_valuta.prg), dar continutul liniilor si totalurile raman identice, pentru ca
*-- 'tvd' a fost incarcat fara nicio modificare (vezi ATENTIE din antet)
lcSql = [select cod, nvl(discount,0) as discount, total_fara_tva, total_tva, total_cu_tva from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecSel(lcSql, 'v_vz1')
IF lnQ > 0 AND RECCOUNT('v_vz1') = 1
lnCodDupa = v_vz1.cod
lnDiscDupa = v_vz1.discount
lnFtvaDupa = v_vz1.total_fara_tva
lnTvaDupa = v_vz1.total_tva
lnCtvaDupa = v_vz1.total_cu_tva
ENDIF
USE IN v_vz1
lcSql = [select count(*) as nr from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ and sters = 0]
lnQ = ExecSel(lcSql, 'v_cnt1')
lnNrLiniiDupa = IIF(lnQ > 0, v_cnt1.nr, -1)
USE IN v_cnt1
STRTOFILE(' DUPA COMMIT: cod=' + TRANSFORM(lnCodDupa) + ' (era ' + TRANSFORM(lnCodInainte) + ') discount=' + TRANSFORM(lnDiscDupa) + ;
' ftva=' + TRANSFORM(lnFtvaDupa) + ' tva=' + TRANSFORM(lnTvaDupa) + ' ctva=' + TRANSFORM(lnCtvaDupa) + ;
' linii active=' + TRANSFORM(lnNrLiniiDupa) + CHR(13) + CHR(10), tcLog, 1)
DO asserteaza WITH '14: COD s-a realocat la salvare (ca la orice trecere prin finalizeaza_modificare_nota, chiar fara modificari)', ;
lnCodDupa <> lnCodInainte, TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(lnCodDupa)
DO asserteaza WITH '15: discount/totalurile raman neschimbate (nicio modificare in tvd)', ;
ABS(lnDiscDupa - lnDiscInainte) < 0.0001 AND ABS(lnFtvaDupa - lnFtvaInainte) < 0.0001 ;
AND ABS(lnTvaDupa - lnTvaInainte) < 0.0001 AND ABS(lnCtvaDupa - lnCtvaInainte) < 0.0001, ;
'disc=' + TRANSFORM(lnDiscDupa) + ' ftva=' + TRANSFORM(lnFtvaDupa) + ' tva=' + TRANSFORM(lnTvaDupa) + ' ctva=' + TRANSFORM(lnCtvaDupa)
DO asserteaza WITH '16: numarul de linii active ramane neschimbat (idempotent, ca la reeditare fara modificari)', ;
lnNrLiniiDupa = lnNrLiniiInainte, 'dupa=' + TRANSFORM(lnNrLiniiDupa) + ' inainte=' + TRANSFORM(lnNrLiniiInainte)
*-- verificarea CRITICA: linia definitiv stearsa in testele anterioare (det=1582) trebuie sa
*-- RAMANA stearsa - exact reset-ul pe care ScrieArticoleFacturaEditate trebuie sa-l corecteze
LOCAL lnStersLiniaVecheStearsa
lcSql = [select nvl(sters,0) as sters from vanzari_detalii where id_vanzare_det = 1582]
lnQ = ExecSel(lcSql, 'v_1582')
lnStersLiniaVecheStearsa = IIF(lnQ > 0 AND RECCOUNT('v_1582') = 1, v_1582.sters, -1)
USE IN v_1582
DO asserteaza WITH '17: linia definitiv stearsa in testele anterioare (det=1582) a ramas stearsa dupa aceasta salvare', ;
lnStersLiniaVecheStearsa = 1, 'sters=' + TRANSFORM(lnStersLiniaVecheStearsa)
ENDPROC
PROCEDURE test_error_handler
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC