* test_s8_unicitate_cursuri_aplica.prg * S8 pas 1, caz B din verificarea de unicitate ceruta de orchestrator: rescrie * VVANZARI_ARTICOLE.CURS/MULTIPLICATOR ca subinterogari scalare (max(...)) in loc de LEFT JOIN pe * VANZARI_CURSURI - (id_vanzare, id_valuta) NU e unic garantat prin constrangere/index (doar index * NONUNIQUE), deci un LEFT JOIN ar putea multiplica randurile daca apare vreodata un duplicat. * O subinterogare scalara intoarce cel mult un rand prin constructie. Restul view-ului neatins. * Reia neregresia din raport: randuri sters=0 pe 1040/1047/1050/1055/1125 trebuie 1/2/4/2/4, si * continutul real pe 894/1301 (pretd=100,id_valutad=2) si 1040/1568 (id_ctr=235,curs=5.243). * Scrie in Oracle (CREATE OR REPLACE VIEW, idempotent). QUIT la final. SET SAFETY OFF SET TALK OFF PUBLIC gcErrLog gcErrLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s8_unicitate_cursuri_aplica_log.txt' STRTOFILE('start' + CHR(13) + CHR(10), gcErrLog) ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT', 2026, 8 IF gnHandle <= 0 STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), gcErrLog, 1) QUIT ENDIF LOCAL lcOut, lcSql, llOk lcOut = '' *!* --- 1. aplica CREATE OR REPLACE VIEW cu subinterogari scalare in loc de join pe vanzari_cursuri --- lcSql = [create or replace view vvanzari_articole as ] + ; [select vd.id_vanzare, vd.id_vanzare_det, vd.id_articol, vd.cantitate, vd.pret, vd.pret_cu_tva, vd.proc_tvav, ] + ; [vd.discount_unitar, vd.id_gestiune, vd.cont, vd.id_valuta, vd.id_jtva_coloana, vd.serie, vd.explicatie, ] + ; [vd.taxcode, vd.lot, vd.sters, vd.id_vanzare_set, vd.pret_achizitie, na.denumire, na.codmat, ng.nume_gestiune, ] + ; [nv.nume_val, vd.id_pol, vd.id_ctr, vd.diferenta, vd.pretd, vd.id_valutad, ] + ; [(select max(vc.curs) from vanzari_cursuri vc where vc.id_vanzare = vd.id_vanzare and vc.id_valuta = vd.id_valuta) as curs, ] + ; [(select max(vc.multiplicator) from vanzari_cursuri vc where vc.id_vanzare = vd.id_vanzare and vc.id_valuta = vd.id_valuta) as multiplicator ] + ; [from vanzari_detalii vd ] + ; [left join nom_articole na on na.id_articol = vd.id_articol ] + ; [left join nom_gestiuni ng on ng.id_gestiune = vd.id_gestiune ] + ; [left join nom_valute nv on nv.id_valuta = vd.id_valuta] llOk = goExecutor.oExecuta(m.lcSql) lcOut = lcOut + '--- CREATE OR REPLACE VIEW (subinterogari scalare) ---' + CHR(13) + CHR(10) lcOut = lcOut + 'rezultat: ' + TRANSFORM(m.llOk) + CHR(13) + CHR(10) IF !m.llOk lcOut = lcOut + 'EROARE: ' + goExecutor.cEroare + CHR(13) + CHR(10) ENDIF goExecutor.oReset() STRTOFILE(m.lcOut, gcErrLog, 1) lcOut = '' IF !m.llOk STRTOFILE('OPRIT dupa eroare la CREATE OR REPLACE - nu se mai verifica.' + CHR(13) + CHR(10), gcErrLog, 1) STRTOFILE('done' + CHR(13) + CHR(10), gcErrLog, 1) QUIT ENDIF *!* --- 1b. re-marcheaza versiunea (script revizuit, aceeasi cheie - idempotent) --- llOk = goExecutor.oExecuta([begin pack_migrare.UpdateVersiune('wip13_2026_09_02_01_COMUN_VVANZARI_ARTICOLE_EXT'); end;]) lcOut = lcOut + '--- UpdateVersiune (reaplicare) ---' + CHR(13) + CHR(10) + 'rezultat: ' + TRANSFORM(m.llOk) + CHR(13) + CHR(10) IF !m.llOk lcOut = lcOut + 'EROARE: ' + goExecutor.cEroare + CHR(13) + CHR(10) ENDIF goExecutor.oReset() STRTOFILE(m.lcOut, gcErrLog, 1) lcOut = '' *!* --- 2. randuri DUPA pe cele 5 id_vanzare de control - trebuie identice cu raportul (1/2/4/2/4) --- lcSql = [select id_vanzare, count(*) as nr from vvanzari_articole where id_vanzare in (1050,1047,1055,1040,1125) and sters = 0 group by id_vanzare order by id_vanzare] IF Used('crscnt') Use In crscnt ENDIF IF goExecutor.oExecute(m.lcSql, [crscnt]) < 0 lcOut = lcOut + 'EROARE numarare dupa: ' + goExecutor.cEroare + CHR(13) + CHR(10) ELSE lcOut = lcOut + '--- randuri sters=0 pe id_vanzare de control (DUPA rescriere) - asteptat 1040->1,1047->2,1050->4,1055->2,1125->4 ---' + CHR(13) + CHR(10) SELECT crscnt SCAN lcOut = lcOut + 'id_vanzare=' + TRANSFORM(id_vanzare) + ' -> ' + TRANSFORM(nr) + ' randuri' + CHR(13) + CHR(10) ENDSCAN USE IN crscnt ENDIF goExecutor.oReset() STRTOFILE(m.lcOut, gcErrLog, 1) lcOut = '' *!* --- 3. continut real: 894/1301 (pretd=100, id_valutad=2), 1040/1568 (id_ctr=235, curs=5.243) --- lcSql = [select id_vanzare, id_vanzare_det, id_ctr, pretd, id_valutad, curs, multiplicator ] + ; [from vvanzari_articole where (id_vanzare = 894 and id_vanzare_det = 1301) or (id_vanzare = 1040 and id_vanzare_det = 1568) order by id_vanzare, id_vanzare_det] IF Used('crscheck') Use In crscheck ENDIF IF goExecutor.oExecute(m.lcSql, [crscheck]) < 0 lcOut = lcOut + 'EROARE continut nou: ' + goExecutor.cEroare + CHR(13) + CHR(10) ELSE lcOut = lcOut + CHR(13) + CHR(10) + '--- continut de control: 894/1301 (pretd=100,id_valutad=2) si 1040/1568 (id_ctr=235,curs=5.243) ---' + CHR(13) + CHR(10) SELECT crscheck SCAN lcOut = lcOut + 'id_vanzare=' + TRANSFORM(id_vanzare) + ' det=' + TRANSFORM(id_vanzare_det) + ; ' id_ctr=' + TRANSFORM(NVL(id_ctr,-1)) + ' pretd=' + TRANSFORM(NVL(pretd,-1)) + ; ' id_valutad=' + TRANSFORM(NVL(id_valutad,-1)) + ' curs=' + TRANSFORM(NVL(curs,-1)) + ; ' multiplicator=' + TRANSFORM(NVL(multiplicator,-1)) + CHR(13) + CHR(10) ENDSCAN USE IN crscheck ENDIF goExecutor.oReset() STRTOFILE(m.lcOut, gcErrLog, 1) lcOut = '' STRTOFILE('done' + CHR(13) + CHR(10), gcErrLog, 1) QUIT PROCEDURE test_error_handler LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + tcProgram + ':' + TRANSFORM(tnLineNo) + '] ' + tcMessage + CHR(13) + CHR(10), gcErrLog, 1) ENDPROC