Files
comun/utile/Teste/editare_factura/test_s5_scriere_reala.prg
Marius Mutu 1c42ae0af4 #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
2026-08-10 01:37:12 +03:00

625 lines
26 KiB
Plaintext

* test_s5_scriere_reala.prg
* Test REAL de scriere in VANZARI_DETALII pentru lantul de editare a unei facturi emise -
* APROBAT explicit de Marius (09.08.2026) sa scrie in schema de dev MARIUSM_AUTO@ROA_CENTRAL.
*
* Ce dovedeste, si nu poate fi dovedit headless: pack_facturare.actualizeaza_vanzari (apelata din
* pack_contafin.finalizeaza_modificare_nota) face UPDATE VANZARI_DETALII SET STERS = 0 pe TOT
* documentul, deci INVIE liniile sterse la o editare anterioara. Idiomul "marcheaza tot sters,
* invie ce ramane" din ScrieArticoleFacturaEditate (ofacturare_editare.prg), apelat DUPA
* finalizeaza_modificare_nota si in aceeasi tranzactie, trebuie sa corecteze ambele consecinte.
*
* Ordinea testata (o singura tranzactie manuala), copiata din ofacturare_comun.vc2:3799-3837:
* do_deschide_tranzactie -> OSCRIE_IN_FISIERE(2) -> OSCRIE_IN_FISIERE(0) ->
* finalizeaza_modificare_nota -> ScrieArticoleFacturaEditate -> do_inchide_tranzactie
*
* Doua treceri pe acelasi document:
* TRECEREA 1 - o linie stearsa, o linie cu cantitatea schimbata, o linie noua adaugata.
* TRECEREA 2 - reeditare fara nicio modificare; singura care dovedeste ca linia stearsa la
* trecerea 1 RAMANE stearsa (consecinta 2 a resetului).
*
* In interiorul tranzactiei, dupa finalizeaza_modificare_nota si inainte de scrierea liniilor,
* se citeste starea necomisa a lui VANZARI_DETALII (aceeasi conexiune) - proba directa ca resetul
* STERS = 0 chiar ruleaza inainte, si ca scrierea liniilor il corecteaza dupa.
*
* Harness, nu UI: frm_modific2024 e ocolit (se blocheaza headless pe un dialog nativ - capcana j din
* testare-ui-vfp.md), buton=1 e fortat direct, deci inainte_de_do_termin NU se executa.
* do_deschide_tranzactie/do_inchide_tranzactie sunt reproduse inline dupa _frm_base.vc2:252-302.
* OSCRIE_IN_FISIERE, finalizeaza_modificare_nota si ScrieArticoleFacturaEditate ruleaza reale.
*
* CONSUMA DATE DE TEST: VANZARI.COD se realoca la fiecare salvare, iar liniile sterse raman sterse.
* Documentul e id_vanzare = 1049 (nu 1050, cel ales de descopera_caz_test pentru FACTURA_ARTICOLE).
* Nu modifica cod de aplicatie, nu atinge .PJX/.exe. QUIT la final.
SET SAFETY OFF
SET TALK OFF
LOCAL lcLog
lcLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s5_scriere_reala_log.txt'
STRTOFILE('start ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog)
PUBLIC gcErrLog, gcTestLog, gnPass, gnFail
gcErrLog = lcLog
gcTestLog = lcLog
gnPass = 0
gnFail = 0
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
*-- mock amessagebox incarcat PRIMUL, inaintea lantului real (la nume duplicat castiga primul gasit)
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), lcLog, 1)
QUIT
ENDIF
LOCAL lnVerifMock
lnVerifMock = amessagebox('verificare mock', 4+32, 'test')
STRTOFILE('verificare mock amessagebox = ' + TRANSFORM(lnVerifMock) + ;
IIF(lnVerifMock = 6, ' (OK, mock activ)', ' (ATENTIE: amessagebox real, risc de blocaj)') + CHR(13) + CHR(10), lcLog, 1)
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\oscrie_in_fisiere.prg ADDITIVE
*-- garda de referinte din do_editare_factura sta in odocumente.prg, care nu e in mediul de test
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\odocumente.prg ADDITIVE
IF TYPE('gnPC') <> 'N'
PUBLIC gnPC
gnPC = 2
ENDIF
PUBLIC gcMockUltimMesaj, gnMockUltimTip
gcMockUltimMesaj = ''
gnMockUltimTip = 0
STRTOFILE('gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + ' gnIdUtil=' + TRANSFORM(gnIdUtil) + CHR(13) + CHR(10), lcLog, 1)
*-- valorile alese pentru linia noua; pret_achizitie distinctiv, ca sa se poata urmari peste treceri
PUBLIC gnPretAchNou, gnCantNoua, gnPretNou
gnPretAchNou = 77.77
gnCantNoua = 3
gnPretNou = 50
PUBLIC gnIdVanzareTest
gnIdVanzareTest = 1049
*-- liniile urmarite peste ambele treceri: la trecerea 2 documentul se reincarca din Oracle, iar
*-- linia stearsa nu mai e in tvd - identitatea ei trebuie pastrata din trecerea 1
PUBLIC gnDetModificat, gnDetSters, gnDetNou
gnDetModificat = 0
gnDetSters = 0
gnDetNou = 0
*-- starea de plecare, inainte de orice scriere
DO LogStareLinii WITH 'STARE INITIALA', gnIdVanzareTest, lcLog
DO ruleaza_trecere WITH gnIdVanzareTest, 'TRECEREA 1 - sterge o linie, schimba o cantitate, adauga o linie', .T., lcLog
DO ruleaza_trecere WITH gnIdVanzareTest, 'TRECEREA 2 - reeditare fara nicio modificare', .F., lcLog
STRTOFILE(CHR(13) + CHR(10) + 'REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
STRTOFILE('done ' + TTOC(DATETIME()) + CHR(13) + CHR(10), lcLog, 1)
QUIT
PROCEDURE asserteaza
LPARAMETERS tcNume, tlConditie, tcValoare
IF m.tlConditie
gnPass = gnPass + 1
STRTOFILE('PASS ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
ELSE
gnFail = gnFail + 1
STRTOFILE('FAIL ' + m.tcNume + ' [' + m.tcValoare + ']' + CHR(13) + CHR(10), gcTestLog, 1)
ENDIF
ENDPROC
*-- executa SELECT-ul prin goExecutor si intoarce codul de succes; cursorul vechi se inchide intai
PROCEDURE ExecSel
LPARAMETERS tcSql, tcCursor
LOCAL lnQ
IF USED(tcCursor)
USE IN (tcCursor)
ENDIF
lnQ = goExecutor.oExecute(tcSql, tcCursor)
RETURN lnQ
ENDPROC
*-- logheaza starea tuturor liniilor documentului (inclusiv cele sterse); folosit si INTRE pasii
*-- tranzactiei manuale - citirea merge pe aceeasi conexiune, deci vede si ce nu e inca comis
PROCEDURE LogStareLinii
LPARAMETERS tcEticheta, tnIdVanzare, tcLog
LOCAL lcSql, lnQ, lcRand
lcSql = [select id_vanzare_det, nvl(sters,0) as sters, nvl(cantitate,0) as cantitate, ] + ;
[nvl(pret,0) as pret, nvl(pret_achizitie,0) as pret_achizitie ] + ;
[from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ order by id_vanzare_det]
lnQ = ExecSel(lcSql, 'v_stare')
IF lnQ <= 0
STRTOFILE(' [' + tcEticheta + '] EROARE citire linii: ' + ALLTRIM(TRANSFORM(NVL(goExecutor.cEroare, ''))) + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
lcRand = ' [' + tcEticheta + '] linii:' + CHR(13) + CHR(10)
SELECT v_stare
SCAN
lcRand = lcRand + ' det=' + TRANSFORM(id_vanzare_det) + ' sters=' + TRANSFORM(sters) + ;
' cant=' + TRANSFORM(cantitate) + ' pret=' + TRANSFORM(pret) + ' pret_ach=' + TRANSFORM(pret_achizitie) + CHR(13) + CHR(10)
ENDSCAN
STRTOFILE(lcRand, tcLog, 1)
USE IN v_stare
ENDPROC
*-- citeste STERS de pe o linie anume, direct din Oracle (si necomis, in tranzactie); -1 = eroare/lipsa
PROCEDURE CitesteSters
LPARAMETERS tnIdVanzareDet
LOCAL lcSql, lnQ, lnRez
lnRez = -1
lcSql = [select nvl(sters,0) as sters from vanzari_detalii where id_vanzare_det = ] + TRANSFORM(tnIdVanzareDet)
lnQ = ExecSel(lcSql, 'v_unsters')
IF lnQ > 0 AND RECCOUNT('v_unsters') = 1
lnRez = v_unsters.sters
ENDIF
IF USED('v_unsters')
USE IN v_unsters
ENDIF
RETURN lnRez
ENDPROC
*-- reproduce _frm_base.vc2:252-265 (do_deschide_tranzactie), fara sa instantieze niciun formular
PROCEDURE MyDeschideTranzactie
LOCAL llReturn, lnSuccesLocal
IF TYPE('goExecutor') = 'O'
goExecutor.oExecuta([select * from dual])
ENDIF
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 2)
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
RETURN llReturn
ENDPROC
*-- reproduce _frm_base.vc2:279-302 (do_inchide_tranzactie), fara sa instantieze niciun formular
PROCEDURE MyInchideTranzactie
LPARAMETERS tnTip
LOCAL llReturn, lnSuccesLocal
IF tnTip = 1
lnSuccesLocal = SQLCOMMIT(gnHandle)
ELSE
lnSuccesLocal = SQLROLLBACK(gnHandle)
ENDIF
IF lnSuccesLocal < 0
llReturn = .F.
ELSE
lnSuccesLocal = SQLSetprop(gnHandle, "Transactions", 1)
llReturn = IIF(lnSuccesLocal < 0, .F., .T.)
ENDIF
RETURN llReturn
ENDPROC
PROCEDURE ruleaza_trecere
LPARAMETERS tnIdVanzare, tcEticheta, tlAplicaModificari, tcLog
*-- pnAn/pnLuna/lnCod/lnIdFact PRIVATE (nu LOCAL), ca in ofacturare_comun.vc2:3730 -
*-- finalizeaza_modificare_nota le foloseste ca bind-variabile ?pnLuna/?pnAn in josul stivei
PRIVATE pnAn, pnLuna, lnCod, lnIdFact
LOCAL lnSters, llEProforma, lnIdSet, lnIdFactD, lnSucces, llGasitRand
LOCAL lcSql, lnQ, lnI
LOCAL lnDetModificat, lnDetSters, lnDetPastrat, lnCantVecheMod, lnPretAchMod
LOCAL lnMaxDetInainte, lnNrActiveInainte
LOCAL lnCodInainte, lnTotFtvaInainte, lnTotTvaInainte, lnTotCtvaInainte
LOCAL lnStersProbaDupaFinalizeaza, lnStersProbaDupaScriere
LOCAL lnCodDupa, lnStersDupa, lnTotFtvaDupa, lnTotTvaDupa, lnTotCtvaDupa
LOCAL lnDetNou, lnPretAchNouDupa, lnCantModDupa, lnPretAchModDupa, lnStersModDupa
LOCAL lnNrActiveDupa, lnBrutAsteptat, lnStersNouUrmarit, lnPretAchNouUrmarit
STRTOFILE(CHR(13) + CHR(10) + '========== ' + tcEticheta + ' (id_vanzare=' + TRANSFORM(tnIdVanzare) + ') ==========' + CHR(13) + CHR(10), tcLog, 1)
*-- 1) starea documentului din VANZARI (cod-ul se realoca la fiecare salvare)
lcSql = [select cod, sters, id_fact, eproforma, total_fara_tva, total_tva, total_cu_tva, discount, ] + ;
[extract(year from data_act) as anact, extract(month from data_act) as lunaact ] + ;
[from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecSel(lcSql, 'v_vz_inainte')
IF lnQ <= 0 OR RECCOUNT('v_vz_inainte') <> 1
DO asserteaza WITH tcEticheta + ': VANZARI citit', .F., 'lnQ=' + TRANSFORM(lnQ)
RETURN
ENDIF
SELECT v_vz_inainte
lnCod = cod
lnSters = sters
lnIdFact = id_fact
llEProforma = (NVL(eproforma, 0) = 1)
pnAn = anact
pnLuna = lunaact
lnCodInainte = cod
lnTotFtvaInainte = total_fara_tva
lnTotTvaInainte = total_tva
lnTotCtvaInainte = total_cu_tva
USE IN v_vz_inainte
STRTOFILE(' VANZARI inainte: cod=' + TRANSFORM(lnCod) + ' sters=' + TRANSFORM(lnSters) + ' id_fact=' + TRANSFORM(lnIdFact) + ;
' an/luna=' + TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna) + ' total_ftva=' + TRANSFORM(lnTotFtvaInainte) + ;
' total_tva=' + TRANSFORM(lnTotTvaInainte) + ' total_ctva=' + TRANSFORM(lnTotCtvaInainte) + CHR(13) + CHR(10), tcLog, 1)
*-- 2) garzile din do_editare_factura (ofacturare_comun.vc2:3742-3767), fara UI
IF lnSters = 1 OR llEProforma
DO asserteaza WITH tcEticheta + ': document editabil (nesters, neproforma)', .F., 'sters=' + TRANSFORM(lnSters)
RETURN
ENDIF
IF (pnAn*12) + pnLuna <> (gnAn*12) + gnLuna
DO asserteaza WITH tcEticheta + ': document din luna curenta', .F., TRANSFORM(pnAn) + '/' + TRANSFORM(pnLuna)
RETURN
ENDIF
IF ReferinteDocumenteNota(pnAn, pnLuna, lnCod) OR EsteInEFactura(lnIdFact)
DO asserteaza WITH tcEticheta + ': document fara referinte / netrimis in eFactura', .F., 'blocat de garda'
RETURN
ENDIF
*-- 3) instantaneul liniilor inainte de editare
lcSql = [select count(*) as nr, max(id_vanzare_det) as maxdet from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecSel(lcSql, 'v_max')
lnMaxDetInainte = IIF(lnQ > 0, NVL(v_max.maxdet, 0), 0)
IF USED('v_max')
USE IN v_max
ENDIF
*-- 4) cursoarele notei, exact ca do_editare_factura
IF !IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.)
DO asserteaza WITH tcEticheta + ': IncarcaCursoareModificareNota', .F., 'a esuat'
RETURN
ENDIF
IF RECCOUNT('actactan') = 0
DO asserteaza WITH tcEticheta + ': exista nota contabila', .F., 'Reccount(actactan)=0'
RETURN
ENDIF
SELECT actactan
llGasitRand = .F.
IF lnIdFact > 0
LOCATE FOR NVL(id_fact, 0) = lnIdFact
llGasitRand = FOUND()
ENDIF
IF !llGasitRand
GO TOP
lnIdFact = id_fact
ENDIF
lnIdSet = id_set
lnIdFactD = NVL(id_factd, 0)
SELECT a.*, IIF(NVL(id_jtva_coloana, 0) = 0, 0, 1) AS cu_Tva FROM tact a INTO CURSOR tact READWRITE
*-- 5) tvanz + tvd, cursoarele pe care le lasa calea reala inainte de Createobject(frm_modific2024)
IF !IncarcaVanzareDinNota('tact')
DO asserteaza WITH tcEticheta + ': IncarcaVanzareDinNota', .F., 'nu a gasit randul din VANZARI'
RETURN
ENDIF
IncarcaArticoleFactura(tnIdVanzare, 'tvd')
lnNrActiveInainte = RECCOUNT('tvd')
STRTOFILE(' tvd incarcat cu ' + TRANSFORM(lnNrActiveInainte) + ' linii active; tvanz.id_vanzare=' + TRANSFORM(tvanz.id_vanzare) + ;
' discount=' + TRANSFORM(NVL(tvanz.discount, 0)) + CHR(13) + CHR(10), tcLog, 1)
IF lnNrActiveInainte < 3
DO asserteaza WITH tcEticheta + ': documentul are cel putin 3 linii active', .F., TRANSFORM(lnNrActiveInainte)
RETURN
ENDIF
*-- 6) editarile utilizatorului, aplicate pe tvd exact cum le lasa pagina de articole:
*-- randul 1 primeste cantitate dubla, randul 2 e marcat sters (sters=1, ramane in cursor),
*-- randul 3 ramane neatins, plus o linie noua cu id_vanzare_det = 0
lnDetPastrat = 0
lnCantVecheMod = 0
lnPretAchMod = 0
IF tlAplicaModificari
SELECT tvd
GO TOP
gnDetModificat = id_vanzare_det
lnCantVecheMod = NVL(cantitate, 0)
lnPretAchMod = NVL(pret_achizitie, 0)
SKIP
gnDetSters = id_vanzare_det
SKIP
lnDetPastrat = id_vanzare_det
ELSE
*-- linia stearsa la trecerea 1 nu mai e in tvd; identitatile vin din trecerea 1
SELECT tvd
LOCATE FOR id_vanzare_det = gnDetModificat
IF !FOUND()
DO asserteaza WITH tcEticheta + ': linia editata la trecerea 1 e reincarcata', .F., 'det=' + TRANSFORM(gnDetModificat)
RETURN
ENDIF
lnCantVecheMod = NVL(cantitate, 0)
lnPretAchMod = NVL(pret_achizitie, 0)
ENDIF
lnDetModificat = gnDetModificat
lnDetSters = gnDetSters
IF tlAplicaModificari
SELECT tvd
GO TOP
REPLACE cantitate WITH lnCantVecheMod * 2, lmodificat WITH .T.
SKIP
REPLACE sters WITH 1, lmodificat WITH .T.
*-- linia noua: coloanele care conteaza pentru INSERT se iau de pe prima linie, ca sa fie
*-- coerenta cu documentul (cota TVA, jurnal, valuta, cont); gestiunea e cea a adaugarii
*-- din dialog (gnScadereStoc = 0 -> id_gestiune = -1000)
LOCAL lnArtNou, lnPretCuTvaNou, lnProcTvavNou, lnIdValNou, lnJtvaNou, lnTaxcodeNou, lcContNou
SELECT tvd
GO TOP
lnArtNou = id_articol
lnPretCuTvaNou = NVL(pret_cu_tva, 0)
lnProcTvavNou = NVL(proc_tvav, 1)
lnIdValNou = id_valuta
lnJtvaNou = id_jtva_coloana
lnTaxcodeNou = taxcode
lcContNou = NVL(cont, '')
APPEND BLANK IN tvd
REPLACE id_vanzare WITH tnIdVanzare, id_vanzare_det WITH 0, id_articol WITH lnArtNou, ;
cantitate WITH gnCantNoua, pret WITH gnPretNou, pret_cu_tva WITH lnPretCuTvaNou, ;
proc_tvav WITH lnProcTvavNou, discount_unitar WITH 0, id_gestiune WITH -1000, ;
cont WITH lcContNou, id_valuta WITH lnIdValNou, id_jtva_coloana WITH lnJtvaNou, ;
taxcode WITH lnTaxcodeNou, sters WITH 0, pret_achizitie WITH gnPretAchNou, ;
lmodificat WITH .T. IN tvd
STRTOFILE(' editari in tvd: det=' + TRANSFORM(lnDetModificat) + ' cantitate ' + TRANSFORM(lnCantVecheMod) + ;
' -> ' + TRANSFORM(lnCantVecheMod * 2) + ' (pret_achizitie ramane ' + TRANSFORM(lnPretAchMod) + ')' + CHR(13) + CHR(10) + ;
' det=' + TRANSFORM(lnDetSters) + ' marcata stearsa (tvd.sters=1)' + CHR(13) + CHR(10) + ;
' det=' + TRANSFORM(lnDetPastrat) + ' neatinsa' + CHR(13) + CHR(10) + ;
' linie noua: id_articol=' + TRANSFORM(lnArtNou) + ' cantitate=' + TRANSFORM(gnCantNoua) + ;
' pret=' + TRANSFORM(gnPretNou) + ' pret_achizitie=' + TRANSFORM(gnPretAchNou) + CHR(13) + CHR(10), tcLog, 1)
ELSE
STRTOFILE(' tvd nemodificat: det ' + TRANSFORM(lnDetModificat) + ' / ' + TRANSFORM(lnDetSters) + ' / ' + ;
TRANSFORM(lnDetPastrat) + ' (linia stearsa la trecerea 1 nici nu mai e incarcata)' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
*-- 7) frm_modific2024 ocolit, buton=1 fortat (inainte_de_do_termin NU se executa)
buton = 1
*-- 8) ramura buton=1 din do_editare_factura (ofacturare_comun.vc2:3799-3837), copiata identic;
*-- do_deschide/inchide_tranzactie sunt reproduse inline (MyDeschide/MyInchideTranzactie)
lnSucces = 0
lnStersProbaDupaFinalizeaza = -1
lnStersProbaDupaScriere = -1
TRY
IF MyDeschideTranzactie()
SELECT actactan
lnSucces = OSCRIE_IN_FISIERE(2, .T., .T.)
STRTOFILE(' OSCRIE_IN_FISIERE(2,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
IF lnSucces > 0
IF USED('actactan')
USE IN actactan
ENDIF
SELECT tact
REPLACE id_jtva_coloana WITH NULL, proc_tva WITH 0 FOR cu_Tva = 0
SELECT * FROM tact INTO CURSOR actactan READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
IF USED('rul_temp')
USE IN rul_temp
ENDIF
SELECT * FROM trul INTO CURSOR RUL_TEMP READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
IF USED('rul_temp_obinv')
USE IN rul_temp_obinv
ENDIF
SELECT * FROM trul_obinv INTO CURSOR RUL_TEMP_OBINV READWRITE
REPLACE ALL id_util WITH gnIdUtil, sters WITH 0
lnSucces = OSCRIE_IN_FISIERE(0, .T., .T.)
STRTOFILE(' OSCRIE_IN_FISIERE(0,...) => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
ENDIF
IF lnSucces > 0
lcSql = [begin pack_contafin.finalizeaza_modificare_nota(?pnLuna,?pnAn,Null,] + ALLTRIM(STR(lnIdSet)) + [,] + ;
ALLTRIM(STR(lnCod)) + [,] + ALLTRIM(STR(lnIdFact)) + [,] + ALLTRIM(STR(lnIdFactD)) + [,?gnIdUtil); end;]
lnSucces = IIF(goExecutor.oExecuta(lcSql), 1, -1)
STRTOFILE(' finalizeaza_modificare_nota => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
ENDIF
*-- PROBA DE ORDONARE: starea necomisa, dupa finalizeaza_modificare_nota si INAINTE de
*-- scrierea liniilor - aici se vede resetul STERS = 0 din actualizeaza_vanzari
IF lnSucces > 0
DO LogStareLinii WITH 'IN TRANZACTIE, dupa finalizeaza_modificare_nota', tnIdVanzare, tcLog
IF lnDetSters > 0
lnStersProbaDupaFinalizeaza = CitesteSters(lnDetSters)
ENDIF
ENDIF
*-- blocul nou, identic cu ofacturare_comun.vc2:3828-3830 si comun.vc2:2491
IF lnSucces > 0 AND "OFACTURARE_EDITARE" $ UPPER(SET("Procedure")) AND USED('tvanz') AND RECCOUNT('tvanz') = 1
lnSucces = IIF(ScrieArticoleFacturaEditate(tvanz.id_vanzare), 1, -1)
STRTOFILE(' ScrieArticoleFacturaEditate => ' + TRANSFORM(lnSucces) + CHR(13) + CHR(10), tcLog, 1)
ELSE
STRTOFILE(' ATENTIE: blocul ScrieArticoleFacturaEditate NU s-a executat' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
IF lnSucces > 0
DO LogStareLinii WITH 'IN TRANZACTIE, dupa ScrieArticoleFacturaEditate', tnIdVanzare, tcLog
IF lnDetSters > 0
lnStersProbaDupaScriere = CitesteSters(lnDetSters)
ENDIF
ENDIF
IF MyInchideTranzactie(IIF(lnSucces < 0, 2, 1))
STRTOFILE(' tranzactie inchisa cu ' + IIF(lnSucces < 0, 'ROLLBACK', 'COMMIT') + CHR(13) + CHR(10), tcLog, 1)
ELSE
STRTOFILE(' FAIL la inchiderea tranzactiei' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
ELSE
STRTOFILE(' FAIL: deschiderea tranzactiei a esuat' + CHR(13) + CHR(10), tcLog, 1)
ENDIF
CATCH TO loExc
STRTOFILE(' EXCEPTIE in lantul de scriere: ' + TRANSFORM(loExc.ErrorNo) + ' [' + loExc.Message + '] ' + ;
loExc.Procedure + ':' + TRANSFORM(loExc.LineNo) + ' -> ROLLBACK' + CHR(13) + CHR(10), tcLog, 1)
lnSucces = -99
MyInchideTranzactie(2)
ENDTRY
DO asserteaza WITH tcEticheta + ': lantul de scriere a mers pana la capat (lnSucces>0, COMMIT)', ;
lnSucces > 0, 'lnSucces=' + TRANSFORM(lnSucces)
IF USED('actactan')
USE IN actactan
ENDIF
IF USED('tact')
USE IN tact
ENDIF
IF USED('rul_temp')
USE IN rul_temp
ENDIF
IF USED('trul')
USE IN trul
ENDIF
IF USED('rul_temp_obinv')
USE IN rul_temp_obinv
ENDIF
IF USED('trul_obinv')
USE IN trul_obinv
ENDIF
IF lnSucces <= 0
STRTOFILE(' scrierea nu s-a produs - fara verificari dupa' + CHR(13) + CHR(10), tcLog, 1)
RETURN
ENDIF
*-- 9) verificarile de dupa commit
DO LogStareLinii WITH 'DUPA COMMIT', tnIdVanzare, tcLog
*-- proba de ordonare, singura care nu poate fi obtinuta din afara tranzactiei
DO asserteaza WITH tcEticheta + ': resetul STERS=0 din actualizeaza_vanzari a rulat inainte de scrierea liniilor', ;
lnStersProbaDupaFinalizeaza = 0, 'sters pe det=' + TRANSFORM(lnDetSters) + ' dupa finalizeaza = ' + TRANSFORM(lnStersProbaDupaFinalizeaza)
*-- starea liniilor dupa commit
lcSql = [select id_vanzare_det, nvl(sters,0) as sters, nvl(cantitate,0) as cantitate, ] + ;
[nvl(pret,0) as pret, nvl(pret_achizitie,0) as pret_achizitie ] + ;
[from vanzari_detalii where id_vanzare = ] + TRANSFORM(tnIdVanzare) + [ order by id_vanzare_det]
lnQ = ExecSel(lcSql, 'v_dupa')
IF lnQ <= 0
DO asserteaza WITH tcEticheta + ': citirea liniilor dupa commit', .F., 'lnQ=' + TRANSFORM(lnQ)
RETURN
ENDIF
lnStersModDupa = -1
lnCantModDupa = -1
lnPretAchModDupa = -1
lnDetNou = 0
lnPretAchNouDupa = -1
lnStersNouUrmarit = -1
lnPretAchNouUrmarit = -1
lnNrActiveDupa = 0
lnBrutAsteptat = 0
SELECT v_dupa
SCAN
IF sters = 0
lnNrActiveDupa = lnNrActiveDupa + 1
lnBrutAsteptat = lnBrutAsteptat + ROUND(cantitate * pret, 2)
ENDIF
IF id_vanzare_det = lnDetModificat
lnStersModDupa = sters
lnCantModDupa = cantitate
lnPretAchModDupa = pret_achizitie
ENDIF
IF id_vanzare_det > lnMaxDetInainte
lnDetNou = id_vanzare_det
lnPretAchNouDupa = pret_achizitie
ENDIF
*-- linia adaugata la trecerea 1, urmarita si la trecerea 2 (acolo e deja linie existenta)
IF gnDetNou > 0 AND id_vanzare_det = gnDetNou
lnStersNouUrmarit = sters
lnPretAchNouUrmarit = pret_achizitie
ENDIF
ENDSCAN
USE IN v_dupa
*-- linia marcata stearsa: STERS=1 dupa ce s-a intors finalizeaza_modificare_nota
LOCAL lnStersDetSters
lnStersDetSters = CitesteSters(lnDetSters)
DO asserteaza WITH tcEticheta + ': linia marcata stearsa are STERS=1 in VANZARI_DETALII', ;
lnStersDetSters = 1, 'det=' + TRANSFORM(lnDetSters) + ' sters=' + TRANSFORM(lnStersDetSters)
*-- si dovada ca scrierea liniilor e cea care a corectat resetul
DO asserteaza WITH tcEticheta + ': ScrieArticoleFacturaEditate a re-marcat linia stearsa in aceeasi tranzactie', ;
lnStersProbaDupaScriere = 1, 'sters pe det=' + TRANSFORM(lnDetSters) + ' dupa scriere = ' + TRANSFORM(lnStersProbaDupaScriere)
*-- liniile pastrate raman active, cu cantitatea editata
DO asserteaza WITH tcEticheta + ': linia pastrata e activa cu cantitatea editata', ;
lnStersModDupa = 0 AND ABS(lnCantModDupa - IIF(tlAplicaModificari, lnCantVecheMod * 2, lnCantVecheMod)) < 0.001, ;
'det=' + TRANSFORM(lnDetModificat) + ' sters=' + TRANSFORM(lnStersModDupa) + ' cant=' + TRANSFORM(lnCantModDupa)
*-- PRET_ACHIZITIE pe linia existenta ramane neatins (omis din SET-ul de UPDATE)
DO asserteaza WITH tcEticheta + ': PRET_ACHIZITIE pe linia existenta editata a ramas neatins', ;
ABS(lnPretAchModDupa - lnPretAchMod) < 0.0001, ;
'det=' + TRANSFORM(lnDetModificat) + ' inainte=' + TRANSFORM(lnPretAchMod) + ' dupa=' + TRANSFORM(lnPretAchModDupa)
IF tlAplicaModificari
*-- linia noua a intrat prin INSERT, cu ID_VANZARE_DET alocat de trigger
DO asserteaza WITH tcEticheta + ': linia noua a fost inserata cu ID_VANZARE_DET alocat de trigger', ;
lnDetNou > lnMaxDetInainte, 'det nou=' + TRANSFORM(lnDetNou) + ' (max inainte=' + TRANSFORM(lnMaxDetInainte) + ')'
DO asserteaza WITH tcEticheta + ': linia noua are PRET_ACHIZITIE exact valoarea tastata', ;
ABS(lnPretAchNouDupa - gnPretAchNou) < 0.0001, 'pret_achizitie=' + TRANSFORM(lnPretAchNouDupa) + ' (tastat ' + TRANSFORM(gnPretAchNou) + ')'
DO asserteaza WITH tcEticheta + ': documentul are 3 linii active (una stearsa, una noua)', ;
lnNrActiveDupa = 3, 'active=' + TRANSFORM(lnNrActiveDupa)
gnDetNou = lnDetNou
ELSE
DO asserteaza WITH tcEticheta + ': nicio linie noua nu a fost inserata', ;
lnDetNou = 0, 'det peste maximul dinainte=' + TRANSFORM(lnDetNou)
DO asserteaza WITH tcEticheta + ': numarul de linii active nu s-a schimbat', ;
lnNrActiveDupa = lnNrActiveInainte, 'active=' + TRANSFORM(lnNrActiveDupa) + ' (erau ' + TRANSFORM(lnNrActiveInainte) + ')'
DO asserteaza WITH tcEticheta + ': linia adaugata la trecerea 1 e activa si la reeditare', ;
lnStersNouUrmarit = 0, 'det=' + TRANSFORM(gnDetNou) + ' sters=' + TRANSFORM(lnStersNouUrmarit)
DO asserteaza WITH tcEticheta + ': PRET_ACHIZITIE al liniei adaugate la trecerea 1 a ramas neatins', ;
ABS(lnPretAchNouUrmarit - gnPretAchNou) < 0.0001, ;
'det=' + TRANSFORM(gnDetNou) + ' pret_achizitie=' + TRANSFORM(lnPretAchNouUrmarit) + ' (tastat ' + TRANSFORM(gnPretAchNou) + ')'
ENDIF
*-- totalurile din VANZARI dupa recalculeaza_totaluri_vanzari
lcSql = [select cod, nvl(sters,0) as sters, total_fara_tva, total_tva, total_cu_tva from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare)
lnQ = ExecSel(lcSql, 'v_vz_dupa')
IF lnQ <= 0 OR RECCOUNT('v_vz_dupa') <> 1
DO asserteaza WITH tcEticheta + ': VANZARI citit dupa commit', .F., 'lnQ=' + TRANSFORM(lnQ)
RETURN
ENDIF
SELECT v_vz_dupa
lnCodDupa = cod
lnStersDupa = sters
lnTotFtvaDupa = total_fara_tva
lnTotTvaDupa = total_tva
lnTotCtvaDupa = total_cu_tva
USE IN v_vz_dupa
STRTOFILE(' VANZARI dupa: cod=' + TRANSFORM(lnCodDupa) + ' (era ' + TRANSFORM(lnCodInainte) + ') sters=' + TRANSFORM(lnStersDupa) + ;
' total_ftva=' + TRANSFORM(lnTotFtvaDupa) + ' total_tva=' + TRANSFORM(lnTotTvaDupa) + ;
' total_ctva=' + TRANSFORM(lnTotCtvaDupa) + ' (brut din linii active=' + TRANSFORM(lnBrutAsteptat) + ')' + CHR(13) + CHR(10), tcLog, 1)
DO asserteaza WITH tcEticheta + ': VANZARI.COD realocat, documentul ramane activ', ;
lnCodDupa <> lnCodInainte AND lnStersDupa = 0, TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(lnCodDupa)
DO asserteaza WITH tcEticheta + ': totalurile din VANZARI sunt coerente (fara_tva + tva = cu_tva)', ;
ABS((lnTotFtvaDupa + lnTotTvaDupa) - lnTotCtvaDupa) < 0.01, ;
TRANSFORM(lnTotFtvaDupa) + ' + ' + TRANSFORM(lnTotTvaDupa) + ' = ' + TRANSFORM(lnTotCtvaDupa)
*-- toate liniile documentului au preturile cu TVA (pret_cu_tva=1), deci totalul brut al
*-- documentului e suma cantitate*pret pe liniile active - relatie verificata si inainte de editare
DO asserteaza WITH tcEticheta + ': total_cu_tva corespunde liniilor active dupa recalcul', ;
ABS(lnTotCtvaDupa - lnBrutAsteptat) < 0.01, ;
'total_cu_tva=' + TRANSFORM(lnTotCtvaDupa) + ' suma linii active=' + TRANSFORM(lnBrutAsteptat)
IF USED('tvd')
USE IN tvd
ENDIF
IF USED('tvanz')
USE IN tvanz
ENDIF
STRTOFILE(' REZUMAT ' + tcEticheta + ': cod ' + TRANSFORM(lnCodInainte) + ' -> ' + TRANSFORM(lnCodDupa) + CHR(13) + CHR(10), tcLog, 1)
ENDPROC
PROCEDURE test_error_handler
LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC