Files
comun/utile/Teste/editare_factura/test_s9_4_regenerare.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

1022 lines
48 KiB
Plaintext

* test_s9_4_regenerare.prg
* Proba S9-4: regenerarea documentului editat pe sume (stergere + reemitere in ACEEASI tranzactie
* manuala), cablata in frm_facturare_articole2.do_scrie_factura / .do_scrie_articole
* (COMUN\clase\ofacturare.vc2) peste StergeDocumentFacturare (ofacturare_rutare_scriere.prg).
*
* Parametru tnRulare:
* 1 = ATOMICITATE. Nu trece prin formular si NU consuma niciun document: deschide tranzactia
* manual, cheama StergeDocumentFacturare, verifica pe un AL DOILEA handle Oracle ca nimic
* n-a scapat comis, apoi face SQLRollback. Pica la A3 daca garda de COMMIT/ROLLBACK din
* StergeDocumentFacturare lipseste - e testul de regresie al acelei garzi.
* 2 = CICLU COMPLET. Reproduce drumul lui do_editare_unificata (ofacturare_comun.vc2:3890-3977)
* fara Show(), schimba o cantitate si cheama do_scrie_factura(). SCRIE IN ORACLE: sterge
* documentul ales si emite unul nou. Documentul nou e el insusi candidat pentru rularea
* urmatoare. Se alege un document din familia Otherwise (nu tip=4 - facturarea din aviz are
* riscul de dialog fals "aviz de retur", neprobat).
* 3 = S9-5, ATOMICITATEA ATASAMENTELOR. Seamana atasamente pe candidat, forteaza esecul
* reemiterii (serie_act mai lunga decat coloana => eroare Oracle dupa stergere) si verifica
* ca rollback-ul readuce si documentul, si atasamentele, la sters = 0. NU consuma documentul
* (rollback), iar atasamentele semanate se sterg fizic la final.
* 4 = S11, CONTROLUL NEGATIV. Aceeasi rulare 2, dar cu mock_muta_borderou.prg incarcat primul in
* SET PROCEDURE, deci MutaBorderouReemitere devine no-op = starea codului dinainte de
* reparatia S11. Trebuie sa cada EXACT B-b1, B-b2 si B-b4; B-b3 trebuie sa treaca (randul
* exista in borderou, dar arata documentul sters). SCRIE IN ORACLE, consuma un document.
* 5 = S11, ATOMICITATEA MUTARII. Cheama MutaBorderouReemitere REALA intr-o tranzactie manuala si
* verifica pe un al doilea handle ca mutarea nu a scapat comisa, apoi ca rollback-ul readuce
* randul pe id-ul vechi. Nu consuma documentul; borderoul semanat se sterge la final.
*
* S11 (2.1 din docs\propunere_s11_legaturi_id_vanzare.md - randul de borderou eFactura se muta de
* pe id_vanzare vechi pe cel nou) e probat de asertiunile B-b1..B-b4 din rularea 2, de controlul
* negativ din rularea 4 si de rularea 5. Borderoul se seamana de proba, prin chiar procedurile de
* productie (pack_fact_borderou.BorderouNou / BorderouAdaugaFactura): pe schema de test cele 39 de
* randuri FACT_BORDEROU_DETALII existente nu cad pe niciun candidat, deci proba ar trece vida.
*
* S9-5 (decizia 53 - atasamentele NU se remigreaza la reemitere) e probat de asertiunile B14-B17
* din rularea 2 si de rularea 3. Atasamentele documentului vechi se seamana de proba: pe schema de
* test nu exista niciun rand ATASAMENTE_VANZARI legat prin ID_VANZARE (cele 20 existente sunt
* legate prin COD, mostenire ROACONT, invizibile in VATASAMENTE_VANZARI).
*
* Candidatul trebuie sa aiba randuri reale in vact_tot: doar atunci stergerea trece prin ramura cu
* nota contabila, singura care contine COMMIT-ul pazit. Fara aceasta preconditie asertiunea A3 ar
* trece si cu garda lipsa, deci proba ar fi fara valoare.
*
* Documente EXCLUSE (folosite de alte suite / DATA_ACT alterata):
* 1047, 1048, 1055, 1113, 1130
LPARAMETERS tnRulare
SET SAFETY OFF
SET TALK OFF
PUBLIC gcErrLog, gnPass, gnFail, gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
PUBLIC poDate, poSnapshotEditare, glRegenerareEditare, gnMockMutaApeluri, glControlNegativ
gcErrLog = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\editare_factura\test_s9_4_regenerare_log_' + ;
STRTRAN(STRTRAN(STRTRAN(TTOC(DATETIME()), '/', ''), ':', ''), ' ', '_') + '.txt'
STRTOFILE('start ' + TRANSFORM(DATETIME()) + ' rulare=' + TRANSFORM(tnRulare) + CHR(13) + CHR(10), gcErrLog)
ON ERROR DO test_error_handler WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO ('D:\ROA\ROAFACTURARE\COMUN\utile\Teste\test_init_env_auto_roafacturare.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
STRTOFILE('EROARE: conectare esuata' + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
ENDIF
gnIdUtil = 8
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_rutare_scriere.prg ADDITIVE
*!* parametrul din linia de comanda soseste ca sir - fara VAL comparatia numerica da eroare de tip,
*!* iar ON ERROR ar lasa executia sa cada in rularea urmatoare
LOCAL lnRulare
lnRulare = VAL(TRANSFORM(tnRulare))
*!* la nume duplicat de procedura castiga PRIMUL fisier din lista SET PROCEDURE, nu ultimul
LOCAL lcProcExistent
lcProcExistent = SET("PROCEDURE")
IF lnRulare = 4
*!* controlul negativ S11: MutaBorderouReemitere devine no-op, fara sa se atinga fisierul comis
lcProcExistent = 'D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_muta_borderou.prg,' + lcProcExistent
ENDIF
SET PROCEDURE TO "D:\ROA\ROAFACTURARE\COMUN\utile\Teste\mock_amessagebox.prg", &lcProcExistent
*!* stub_verificare inaintea lui COMUN\FERESTRE: Do Form verificare (ofacturare.vc2) nu se afiseaza
LOCAL lcPathVechi, lcPathNou
lcPathVechi = SET("PATH")
lcPathNou = 'D:\ROA\ROAFACTURARE\COMUN\Utile\Teste\achizitie_import\stub_verificare;' + lcPathVechi
SET PATH TO &lcPathNou
*!* 7 = "Nu" la "Doriti sa se inchida comanda?" si la "Doriti sa se inregistreze si avizul de retur?"
gnMockRaspuns = 7
gcMockUltimMesaj = ''
gnMockUltimTip = 0
gnPass = 0
gnFail = 0
glRegenerareEditare = .F.
gnMockMutaApeluri = 0
glControlNegativ = (lnRulare = 4)
STRTOFILE('perioada activa gnAn/gnLuna = ' + TRANSFORM(gnAn) + '/' + TRANSFORM(gnLuna) + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('rulare ceruta: ' + TRANSFORM(lnRulare) + CHR(13) + CHR(10), gcErrLog, 1)
DO CASE
CASE lnRulare = 1
DO Rularea1
CASE lnRulare = 2
DO Rularea2
CASE lnRulare = 3
DO Rularea3
CASE lnRulare = 4
STRTOFILE('CONTROL NEGATIV S11: se asteapta sa cada EXACT B-b1, B-b2 si B-b4; B-b3 trece' + CHR(13) + CHR(10), gcErrLog, 1)
DO Rularea2
CASE lnRulare = 5
DO Rularea5
OTHERWISE
STRTOFILE('EROARE: tnRulare trebuie sa fie intre 1 si 5' + CHR(13) + CHR(10), gcErrLog, 1)
ENDCASE
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('end ' + TRANSFORM(DATETIME()) + CHR(13) + CHR(10), gcErrLog, 1)
QUIT
*==============================================================================================
* RULAREA 1 - atomicitatea. Nu consuma documente: rollback la final.
*==============================================================================================
PROCEDURE Rularea1
LOCAL lnIdV, lnCod, lnTip, lnAn, lnLuna, lnH2, lnActInainte
LOCAL lnStersH1, lnStersH2, lnTranz, llSters, lnIdSetIesit
IF !AlegeCandidat(@lnIdV, @lnCod, @lnTip, @lnAn, @lnLuna, .F.)
RETURN
ENDIF
*!* preconditie obligatorie: randuri in vact_tot => stergerea trece prin ramura cu nota contabila,
*!* singura care contine COMMIT-ul pazit (fara asta A3 ar trece si cu garda lipsa)
lnActInainte = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from ] + gcs + [.vact_tot where sters = 0 and an = ] + ;
TRANSFORM(gnAn) + [ and luna = ] + TRANSFORM(gnLuna) + [ and cod = ] + TRANSFORM(lnCod), @lnActInainte)
DO asserteaza WITH 'PRECONDITIE: candidatul are randuri vact_tot (ramura cu nota contabila)', lnActInainte > 0, TRANSFORM(lnActInainte)
IF lnActInainte <= 0
RETURN
ENDIF
*!* al doilea handle: vede numai ce e COMIS pe server
SQLSetprop(0, "DispLogin", 3)
lnH2 = SQLSTRINGCONNECT("dsn=CENTRAL;Uid=MARIUSM_AUTO;Pwd=ROMFASTSOFT;")
DO asserteaza WITH 'al doilea handle Oracle deschis', lnH2 > 0, TRANSFORM(lnH2)
IF lnH2 <= 0
RETURN
ENDIF
*!* tranzactie manuala, ca in _frm_base.do_deschide_tranzactie (trezirea conexiunii inclusa)
SQLEXEC(gnHandle, "select * from dual", "v_dual_s94")
IF USED('v_dual_s94')
USE IN v_dual_s94
ENDIF
SQLSetprop(gnHandle, "Transactions", 2)
lnIdSetIesit = 0
llSters = StergeDocumentFacturare(lnIdV, lnCod, lnAn, lnLuna, 8, @lnIdSetIesit)
DO asserteaza WITH 'A1 StergeDocumentFacturare a intors .T. sub tranzactie manuala', llSters, TRANSFORM(llSters)
lnTranz = SQLGetprop(gnHandle, "Transactions")
DO asserteaza WITH 'A2 tranzactia manuala e inca deschisa dupa stergere (Transactions = 2)', lnTranz = 2, TRANSFORM(lnTranz)
lnStersH2 = CitesteStersPeHandle(lnH2, lnIdV)
DO asserteaza WITH 'A3 pe al doilea handle documentul e inca NESTERS (nimic n-a scapat comis)', lnStersH2 = 0, TRANSFORM(lnStersH2)
lnStersH1 = -1
goExecutor.oSelecteaza2Value([select sters from vanzari where id_vanzare = ] + TRANSFORM(lnIdV), @lnStersH1)
DO asserteaza WITH 'A4 in interiorul tranzactiei documentul apare sters (sters = 1)', lnStersH1 = 1, TRANSFORM(lnStersH1)
STRTOFILE('id_set intors prin referinta (hunk C) = ' + TRANSFORM(lnIdSetIesit) + CHR(13) + CHR(10), gcErrLog, 1)
DO asserteaza WITH 'A6 id_set-ul notei vechi a iesit prin parametrul de referinta', lnIdSetIesit <> 0, TRANSFORM(lnIdSetIesit)
*!* rollback: documentul trebuie sa ramana intact pe ambele handle-uri
SQLRollback(gnHandle)
SQLSetprop(gnHandle, "Transactions", 1)
lnStersH1 = -1
goExecutor.oSelecteaza2Value([select sters from vanzari where id_vanzare = ] + TRANSFORM(lnIdV), @lnStersH1)
lnStersH2 = CitesteStersPeHandle(lnH2, lnIdV)
DO asserteaza WITH 'A5a dupa rollback documentul e intact pe handle-ul 1 (sters = 0)', lnStersH1 = 0, TRANSFORM(lnStersH1)
DO asserteaza WITH 'A5b dupa rollback documentul e intact pe handle-ul 2 (sters = 0)', lnStersH2 = 0, TRANSFORM(lnStersH2)
SQLDISCONNECT(lnH2)
STRTOFILE('rularea 1 NU a consumat documentul ' + TRANSFORM(lnIdV) + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
*==============================================================================================
* RULAREA 2 - ciclul complet sterge + reemite. SCRIE IN ORACLE.
*==============================================================================================
PROCEDURE Rularea2
LOCAL lnIdV, lnCod, lnTip, lnAn, lnLuna, lnIdFactVechi, lnDocVechi
LOCAL loForm, lnDiscRon, lnDiscVal, lnLiniiCrs, lnCantVeche, lnCantNoua, lnIdArtModificat
LOCAL llRez, lnIdVNou, lnNr, lnSters, lnLiniiNoi, lnCantNouaDb, lnIdFactNou, lnRulVechiNesters
LOCAL lcSerie, lnNumar, ldData, lnCorespVechi, lnCorespNou, lnSurse, lnSurseFacturate
LOCAL lnDocNou, lnRulSumInainte, lnRulSumDupa, lnVrulInainte, lcSerieNou, lnNumarNou
LOCAL ldDataIregVechi, ldDataIregNou, ldDataAct, lnIdVMaxInainte
LOCAL lnStersNotaVeche, lnIdFdocVechiMasurat, lnIdFdocNou
LOCAL lnAtasInainte, lnAtasNesterse, lnAtasSterse, lnAtasNou, lnAtasAudit
LOCAL lnIdBorderou, lnBordVechiInainte, lnTotalBordInainte, lnBordVechi, lnBordNou
LOCAL lnBordView, lnTotalBordDupa, lnTotalVanzNou
LOCAL lnIdUtilVechi, ldDataoraVechi, lnIdUtilNou, ldDataoraNou, lnIdUtilmNou, ldDataoramNou
IF !AlegeCandidat(@lnIdV, @lnCod, @lnTip, @lnAn, @lnLuna, .T.)
RETURN
ENDIF
*!* --- starea INAINTE ---
DO urma WITH 'antet INAINTE'
lnIdFactVechi = 0
lcSerie = ''
lnNumar = 0
IF USED('v_ant_s94')
USE IN v_ant_s94
ENDIF
ldDataAct = {}
lnIdUtilVechi = 0
ldDataoraVechi = {}
IF goExecutor.oExecuta([select id_fact, serie_act, numar_act, data_act, id_util, dataora from vanzari where id_vanzare = ] + TRANSFORM(lnIdV), 'v_ant_s94')
SELECT v_ant_s94
GO TOP
lnIdFactVechi = NVL(id_fact, 0)
lcSerie = ALLTRIM(NVL(serie_act, ''))
lnNumar = NVL(numar_act, 0)
ldDataAct = NVL(data_act, {})
lnIdUtilVechi = NVL(id_util, 0)
ldDataoraVechi = NVL(dataora, {})
USE IN v_ant_s94
ENDIF
DO urma WITH 'rul INAINTE'
lnVrulInainte = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from rul where sters = 0 and an = ] + TRANSFORM(lnAn) + ;
[ and luna = ] + TRANSFORM(lnLuna) + [ and cod = ] + TRANSFORM(lnCod), @lnVrulInainte)
*!* DOCUMENTE (nota contabila) nu are ID_FACT: cheia ei e ID_DOC, egal cu VANZARI.ID_FACT.
*!* ID_SET nu identifica nota - e setul contabil, comun mai multor documente din perioada.
DO urma WITH 'documente INAINTE'
lnDocVechi = -1
ldDataIregVechi = {}
IF USED('v_doc_s94')
USE IN v_doc_s94
ENDIF
IF goExecutor.oExecuta([select sters, dataireg from documente where id_doc = ] + TRANSFORM(lnIdFactVechi), 'v_doc_s94')
SELECT v_doc_s94
lnDocVechi = RECCOUNT('v_doc_s94')
IF lnDocVechi > 0
GO TOP
ldDataIregVechi = NVL(dataireg, {})
ENDIF
USE IN v_doc_s94
ENDIF
STRTOFILE('nota contabila INAINTE: id_doc=' + TRANSFORM(lnIdFactVechi) + ' randuri=' + TRANSFORM(lnDocVechi) + ;
' dataireg=' + TRANSFORM(ldDataIregVechi) + CHR(13) + CHR(10), gcErrLog, 1)
*!* id_fdoc e atribut per RAND contabil, nu per document (16% din documente au valori mixte).
*!* Mecanismul poarta valoarea primului rand (actactan: GO top peste order by id_act), deci
*!* asta se compara - nu max(), care ar da un fals esec pe documentele neuniforme.
DO urma WITH 'id_fdoc INAINTE'
lnIdFdocVechiMasurat = -1
goExecutor.oSelecteaza2Value([select id_fdoc from ] + gcs + [.vact_tot where id_act = ] + ;
[(select min(id_act) from ] + gcs + [.vact_tot where sters = 0 and an = ] + TRANSFORM(lnAn) + ;
[ and luna = ] + TRANSFORM(lnLuna) + [ and cod = ] + TRANSFORM(lnCod) + [)], @lnIdFdocVechiMasurat)
DO urma WITH 'max id_vanzare INAINTE'
lnIdVMaxInainte = 0
goExecutor.oSelecteaza2Value([select nvl(max(id_vanzare),0) as id from vanzari], @lnIdVMaxInainte)
DO urma WITH 'coresp INAINTE'
lnCorespVechi = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from vanzari_coresp where sters = 0 and ] + ;
[(id_vanzare_fact = ] + TRANSFORM(lnIdV) + [ or id_vanzare_aviz = ] + TRANSFORM(lnIdV) + [)], @lnCorespVechi)
STRTOFILE('INAINTE: id_vanzare=' + TRANSFORM(lnIdV) + ' cod=' + TRANSFORM(lnCod) + ' tip=' + TRANSFORM(lnTip) + ;
' id_fact=' + TRANSFORM(lnIdFactVechi) + ' serie=' + TRANSFORM(lcSerie) + ' numar=' + TRANSFORM(lnNumar) + ;
' rul_nesters=' + TRANSFORM(lnVrulInainte) + ' coresp_nesters=' + TRANSFORM(lnCorespVechi) + ;
' documente=' + TRANSFORM(lnDocVechi) + CHR(13) + CHR(10), gcErrLog, 1)
IF lnVrulInainte = 0
STRTOFILE('NOTA: candidatul nu are randuri RUL - asertiunea B6 (stoc neutru) e VIDA pentru el' + CHR(13) + CHR(10), gcErrLog, 1)
ENDIF
*!* --- S9-5: atasamentele documentului vechi (decizia 53) ---
*!* fara semanare proba ar fi vida: schema de test nu are niciun atasament legat prin ID_VANZARE
DO SeamanaAtasamente WITH lnIdV
lnAtasInainte = NumaraAtasamente(lnIdV, 0)
DO asserteaza WITH 'PRECONDITIE S9-5: documentul vechi are 2 atasamente nesterse', lnAtasInainte = 2, TRANSFORM(lnAtasInainte)
*!* --- S11: borderoul eFactura (2.1) ---
*!* semanat prin chiar procedurile de productie; fara el proba ar trece vida (niciunul dintre
*!* cele 39 de randuri FACT_BORDEROU_DETALII existente nu cade pe un candidat)
lnIdBorderou = SeamanaBorderou(lnIdV)
DO asserteaza WITH 'PRECONDITIE S11: borderoul semanat s-a creat', lnIdBorderou > 0, TRANSFORM(lnIdBorderou)
lnBordVechiInainte = NumaraBorderouDetalii(lnIdBorderou, lnIdV)
DO asserteaza WITH 'PRECONDITIE S11: randul de borderou sta pe documentul vechi', lnBordVechiInainte = 1, TRANSFORM(lnBordVechiInainte)
lnTotalBordInainte = CitesteTotalBorderou(lnIdBorderou)
STRTOFILE('S11: id_borderou=' + TRANSFORM(lnIdBorderou) + ' total_cu_tva citit din ' + ;
'FACT_VBORDEROU_DETALII INAINTE=' + TRANSFORM(lnTotalBordInainte) + CHR(13) + CHR(10), gcErrLog, 1)
*!* --- drumul lui do_editare_unificata, fara Show() ---
DO urma WITH 'IncarcaAntetFacturaEditare'
lnDiscRon = 0
lnDiscVal = 0
poDate = IncarcaAntetFacturaEditare(lnIdV, @lnDiscRon, @lnDiscVal)
DO asserteaza WITH 'antetul documentului s-a incarcat', VARTYPE(poDate) = 'O', VARTYPE(poDate)
IF VARTYPE(poDate) <> 'O'
RETURN
ENDIF
DO urma WITH 'IncarcaLiniiFacturaEditare'
IncarcaLiniiFacturaEditare(poDate, lnIdV)
DO asserteaza WITH 'liniile documentului s-au incarcat in crsfactura', USED('crsfactura') AND RECCOUNT('crsfactura') > 0, ;
TRANSFORM(IIF(USED('crsfactura'), RECCOUNT('crsfactura'), -1))
IF !USED('crsfactura') OR RECCOUNT('crsfactura') = 0
RETURN
ENDIF
DO urma WITH 'update_jtva_coloane / update_saft_taxtable'
update_jtva_coloane([JV], [jtva_coloane_temp])
update_saft_taxtable()
IF USED('jtva_coloane')
USE IN jtva_coloane
ENDIF
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
DO urma WITH 'CREATEOBJECT frm_facturare_articole2'
loForm = CREATEOBJECT('frm_facturare_articole2')
DO urma WITH 'do_calculeaza_totaluri'
loForm.ndiscfactron = lnDiscRon
loForm.ndiscfactval = lnDiscVal
loForm.do_calculeaza_totaluri()
poSnapshotEditare = CreeazaSnapshotEditare(poDate, loForm.ndiscfactron, loForm.ndiscfactval, lnIdV, lnIdFactVechi, lnCod, lnAn, lnLuna)
DO asserteaza WITH 'instantaneul de editare s-a creat', VARTYPE(poSnapshotEditare) = 'O', VARTYPE(poSnapshotEditare)
IF VARTYPE(poSnapshotEditare) <> 'O'
RETURN
ENDIF
*!* --- modificarea utilizatorului: o cantitate pe prima linie => ruta 1 (regenerare) ---
SELECT crsfactura
GO TOP
lnLiniiCrs = RECCOUNT('crsfactura')
lnCantVeche = cantitate
lnIdArtModificat = id_articol
lnCantNoua = lnCantVeche + 1
REPLACE cantitate WITH lnCantNoua IN crsfactura
loForm.do_calculeaza_totaluri()
STRTOFILE('modificare: id_articol=' + TRANSFORM(lnIdArtModificat) + ' cantitate ' + ;
TRANSFORM(lnCantVeche) + ' -> ' + TRANSFORM(lnCantNoua) + ' (linii crsfactura=' + ;
TRANSFORM(lnLiniiCrs) + ')' + CHR(13) + CHR(10), gcErrLog, 1)
DO asserteaza WITH 'ruta aleasa pentru modificarea de cantitate este 1 (regenerare)', ;
AlegeRutaScriereEditare(poSnapshotEditare, poDate, loForm.ndiscfactron, loForm.ndiscfactval, 'crsfactura') = 1, ;
TRANSFORM(AlegeRutaScriereEditare(poSnapshotEditare, poDate, loForm.ndiscfactron, loForm.ndiscfactval, 'crsfactura'))
*!* --- comutatorul care deschide ruta 1; in productie lipseste, deci ruta 1 ramane cu mesajul ---
DO urma WITH 'do_scrie_factura (SCRIE IN ORACLE)'
glRegenerareEditare = .T.
llRez = loForm.do_scrie_factura()
glRegenerareEditare = .F.
DO urma WITH 'do_scrie_factura a revenit'
DO asserteaza WITH 'B1 do_scrie_factura() a intors .T.', llRez, TRANSFORM(llRez)
STRTOFILE('ultimul mesaj prin mock: [' + gcMockUltimMesaj + ']' + CHR(13) + CHR(10), gcErrLog, 1)
*!* --- starea DUPA ---
lnSters = -1
goExecutor.oSelecteaza2Value([select sters from vanzari where id_vanzare = ] + TRANSFORM(lnIdV), @lnSters)
DO asserteaza WITH 'B2 documentul vechi are VANZARI.STERS = 1', lnSters = 1, TRANSFORM(lnSters)
*!* serie+numar NU identifica unic un document pe aceasta schema de test (exista duplicate reale) -
*!* documentul nou e cel cu id_vanzare peste maximul dinainte de apel
lnNr = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from vanzari where sters = 0 and id_vanzare > ] + TRANSFORM(lnIdVMaxInainte), @lnNr)
DO asserteaza WITH 'B3 exista exact UN document nou nesters (id_vanzare peste maximul dinainte)', lnNr = 1, TRANSFORM(lnNr)
lnIdVNou = 0
goExecutor.oSelecteaza2Value([select nvl(max(id_vanzare),0) as id from vanzari where sters = 0 and id_vanzare > ] + TRANSFORM(lnIdVMaxInainte), @lnIdVNou)
DO asserteaza WITH 'B4 poDate.nid_vanzare (parametru OUT) = id-ul documentului nou', ;
lnIdVNou > 0 AND poDate.nid_vanzare = lnIdVNou, TRANSFORM(poDate.nid_vanzare) + ' vs ' + TRANSFORM(lnIdVNou)
IF lnIdVNou <= 0
RETURN
ENDIF
lnLiniiNoi = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from vanzari_detalii where sters = 0 and id_vanzare = ] + TRANSFORM(lnIdVNou), @lnLiniiNoi)
DO asserteaza WITH 'B5a numarul de linii noi = Reccount(crsfactura)', lnLiniiNoi = lnLiniiCrs, ;
TRANSFORM(lnLiniiNoi) + ' vs ' + TRANSFORM(lnLiniiCrs)
lnCantNouaDb = -1
goExecutor.oSelecteaza2Value([select nvl(sum(cantitate),-1) as s from vanzari_detalii where sters = 0 and id_vanzare = ] + ;
TRANSFORM(lnIdVNou) + [ and id_articol = ] + TRANSFORM(lnIdArtModificat), @lnCantNouaDb)
DO asserteaza WITH 'B5b cantitatea modificata se regaseste pe linia noua', lnCantNouaDb = lnCantNoua, ;
TRANSFORM(lnCantNouaDb) + ' vs ' + TRANSFORM(lnCantNoua)
lnRulVechiNesters = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from rul where sters = 0 and an = ] + TRANSFORM(lnAn) + ;
[ and luna = ] + TRANSFORM(lnLuna) + [ and cod = ] + TRANSFORM(lnCod), @lnRulVechiNesters)
STRTOFILE('B6: rul nesters pe codul vechi INAINTE=' + TRANSFORM(lnVrulInainte) + ' DUPA=' + TRANSFORM(lnRulVechiNesters) + CHR(13) + CHR(10), gcErrLog, 1)
IF lnVrulInainte > 0
DO asserteaza WITH 'B6 randurile RUL ale documentului vechi sunt toate sters=1', lnRulVechiNesters = 0, TRANSFORM(lnRulVechiNesters)
ELSE
STRTOFILE('B6 VID (candidatul nu avea randuri RUL) - nu se asertioneaza' + CHR(13) + CHR(10), gcErrLog, 1)
ENDIF
lnCorespNou = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from vanzari_coresp where sters = 0 and ] + ;
[(id_vanzare_fact = ] + TRANSFORM(lnIdV) + [ or id_vanzare_aviz = ] + TRANSFORM(lnIdV) + [)], @lnCorespNou)
DO asserteaza WITH 'B7 VANZARI_CORESP ale documentului vechi sunt toate sters=1', lnCorespNou = 0, ;
TRANSFORM(lnCorespVechi) + ' -> ' + TRANSFORM(lnCorespNou)
lnSurse = -1
lnSurseFacturate = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from vanzari_coresp where sters = 0 and id_vanzare_fact = ] + TRANSFORM(lnIdVNou), @lnSurse)
goExecutor.oSelecteaza2Value([select count(*) as nr from vanzari where facturat = 1 and id_vanzare in ] + ;
[(select id_vanzare_aviz from vanzari_coresp where sters = 0 and id_vanzare_fact = ] + TRANSFORM(lnIdVNou) + [)], @lnSurseFacturate)
STRTOFILE('B8: surse legate de documentul nou=' + TRANSFORM(lnSurse) + ' dintre care facturat=1: ' + TRANSFORM(lnSurseFacturate) + CHR(13) + CHR(10), gcErrLog, 1)
IF lnSurse > 0
DO asserteaza WITH 'B8 toate sursele legate de documentul nou sunt marcate facturat = 1', lnSurseFacturate = lnSurse, ;
TRANSFORM(lnSurseFacturate) + ' vs ' + TRANSFORM(lnSurse)
DO asserteaza WITH 'B9 poDate.listaid nu e gol (documentul avea sursa)', !EMPTY(poDate.listaid), TRANSFORM(poDate.listaid)
ELSE
STRTOFILE('B8/B9 VIDE (documentul nu are surse in vanzari_coresp) - nu se asertioneaza' + CHR(13) + CHR(10), gcErrLog, 1)
ENDIF
lnIdFactNou = 0
goExecutor.oSelecteaza2Value([select id_fact from vanzari where id_vanzare = ] + TRANSFORM(lnIdVNou), @lnIdFactNou)
STRTOFILE('B10: ID_FACT vechi=' + TRANSFORM(lnIdFactVechi) + ' nou=' + TRANSFORM(lnIdFactNou) + ;
' (identic = ASTEPTAT azi, S9-7 cableaza ForteazaIdFactReemitere)' + CHR(13) + CHR(10), gcErrLog, 1)
DO asserteaza WITH 'B10 documentul nou pastreaza ID_FACT-ul vechi (identic - garantat de S9-7)', lnIdFactNou = lnIdFactVechi, ;
TRANSFORM(lnIdFactVechi) + ' -> ' + TRANSFORM(lnIdFactNou)
*!* S14: perechea de creare (id_util/dataora) trebuie transportata pe documentul nou, direct pe
*!* randul curent - nu doar reconstruibila prin lantul ID_FACT; iar perechea de modificare
*!* (id_utilm/dataoram) trebuie sa poarte utilizatorul si momentul reemiterii curente
lnIdUtilNou = -1
ldDataoraNou = {}
lnIdUtilmNou = -1
ldDataoramNou = {}
IF USED('v_aud_s94')
USE IN v_aud_s94
ENDIF
IF goExecutor.oExecuta([select id_util, dataora, nvl(id_utilm,-1) as id_utilm, dataoram from vanzari where id_vanzare = ] + TRANSFORM(lnIdVNou), 'v_aud_s94')
SELECT v_aud_s94
GO TOP
lnIdUtilNou = NVL(id_util, 0)
ldDataoraNou = NVL(dataora, {})
lnIdUtilmNou = id_utilm
ldDataoramNou = NVL(dataoram, {})
USE IN v_aud_s94
ENDIF
STRTOFILE('S14: id_util vechi=' + TRANSFORM(lnIdUtilVechi) + ' nou=' + TRANSFORM(lnIdUtilNou) + ;
' dataora vechi=' + TRANSFORM(ldDataoraVechi) + ' nou=' + TRANSFORM(ldDataoraNou) + ;
' id_utilm nou=' + TRANSFORM(lnIdUtilmNou) + ' dataoram nou=' + TRANSFORM(ldDataoramNou) + CHR(13) + CHR(10), gcErrLog, 1)
DO asserteaza WITH 'S14-1 documentul nou pastreaza ID_UTIL-ul creatiei originale', lnIdUtilNou = lnIdUtilVechi, ;
TRANSFORM(lnIdUtilVechi) + ' -> ' + TRANSFORM(lnIdUtilNou)
DO asserteaza WITH 'S14-2 documentul nou pastreaza DATAORA creatiei originale', ;
!EMPTY(ldDataoraNou) AND TTOC(ldDataoraNou) == TTOC(ldDataoraVechi), ;
TRANSFORM(ldDataoraVechi) + ' -> ' + TRANSFORM(ldDataoraNou)
DO asserteaza WITH 'S14-3 documentul nou are ID_UTILM = utilizatorul reemiterii', lnIdUtilmNou = gnIdUtil, ;
TRANSFORM(gnIdUtil) + ' vs ' + TRANSFORM(lnIdUtilmNou)
DO asserteaza WITH 'S14-4 documentul nou are DATAORAM completat (momentul reemiterii)', !EMPTY(ldDataoramNou), TRANSFORM(ldDataoramNou)
*!* ID_FACT pastrat (B10): id_doc nou = id_doc vechi, randul din DOCUMENTE se REFOLOSESTE, nu se sterge
lnDocNou = -1
lnStersNotaVeche = -1
ldDataIregNou = {}
IF USED('v_doc2_s94')
USE IN v_doc2_s94
ENDIF
IF goExecutor.oExecuta([select sters, dataireg from documente where id_doc = ] + TRANSFORM(lnIdFactNou), 'v_doc2_s94')
SELECT v_doc2_s94
lnDocNou = RECCOUNT('v_doc2_s94')
IF lnDocNou > 0
GO TOP
ldDataIregNou = NVL(dataireg, {})
ENDIF
USE IN v_doc2_s94
ENDIF
goExecutor.oSelecteaza2Value([select sters from documente where id_doc = ] + TRANSFORM(lnIdFactVechi), @lnStersNotaVeche)
STRTOFILE('nota contabila DUPA: id_doc nou=' + TRANSFORM(lnIdFactNou) + ' randuri=' + TRANSFORM(lnDocNou) + ;
' dataireg=' + TRANSFORM(ldDataIregNou) + ' (nota veche id_doc=' + TRANSFORM(lnIdFactVechi) + ;
' sters=' + TRANSFORM(lnStersNotaVeche) + ' dataireg=' + TRANSFORM(ldDataIregVechi) + ')' + CHR(13) + CHR(10), gcErrLog, 1)
DO asserteaza WITH 'B11a exista o nota contabila noua (ID_DOC = ID_FACT-ul nou)', lnDocNou = 1, TRANSFORM(lnDocNou)
IF lnDocVechi > 0
DO asserteaza WITH 'B11b nota contabila veche a fost REFOLOSITA, nu stearsa (sters = 0)', lnStersNotaVeche = 0, TRANSFORM(lnStersNotaVeche)
*!* fidelitate: dataireg reala a notei vechi e purtata pe documentul nou, nu inlocuita cu data_act
DO asserteaza WITH 'B11c dataireg a notei noi = dataireg a notei vechi (fidelitate pastrata)', ;
!EMPTY(ldDataIregNou) AND TTOD(ldDataIregNou) = TTOD(ldDataIregVechi), ;
TRANSFORM(ldDataIregVechi) + ' -> ' + TRANSFORM(ldDataIregNou)
ENDIF
*!* fidelitate: id_fdoc real al documentului vechi e purtat pe cel nou (vact_tot, nu DOCUMENTE)
lnIdFdocNou = -1
goExecutor.oSelecteaza2Value([select a.id_fdoc from ] + gcs + [.vact_tot a, vanzari v ] + ;
[where v.id_vanzare = ] + TRANSFORM(lnIdVNou) + [ and a.cod = v.cod and a.sters = 0 ] + ;
[and a.id_act = (select min(b.id_act) from ] + gcs + [.vact_tot b where b.cod = v.cod and b.sters = 0)], @lnIdFdocNou)
STRTOFILE('B13: id_fdoc vechi=' + TRANSFORM(lnIdFdocVechiMasurat) + ' nou=' + TRANSFORM(lnIdFdocNou) + CHR(13) + CHR(10), gcErrLog, 1)
IF lnIdFdocVechiMasurat > 0
DO asserteaza WITH 'B13 id_fdoc al documentului nou = cel al documentului vechi', ;
lnIdFdocNou = lnIdFdocVechiMasurat, TRANSFORM(lnIdFdocVechiMasurat) + ' -> ' + TRANSFORM(lnIdFdocNou)
ENDIF
lcSerieNou = ''
lnNumarNou = 0
goExecutor.oSelecteaza2Value([select serie_act from vanzari where id_vanzare = ] + TRANSFORM(lnIdVNou), @lcSerieNou)
goExecutor.oSelecteaza2Value([select numar_act from vanzari where id_vanzare = ] + TRANSFORM(lnIdVNou), @lnNumarNou)
DO asserteaza WITH 'B12 seria+numarul sunt aceleasi (nu s-au consumat numere SSS)', ;
ALLTRIM(lcSerieNou) == ALLTRIM(lcSerie) AND lnNumarNou = lnNumar, ;
TRANSFORM(lcSerie) + '/' + TRANSFORM(lnNumar) + ' -> ' + TRANSFORM(lcSerieNou) + '/' + TRANSFORM(lnNumarNou)
*!* --- S9-5: atasamentele (decizia 53 - se sterg, nu se remigreaza) ---
lnAtasNesterse = NumaraAtasamente(lnIdV, 0)
lnAtasSterse = NumaraAtasamente(lnIdV, 1)
DO asserteaza WITH 'B14 atasamentele documentului vechi sunt toate sters = 1', ;
lnAtasNesterse = 0 AND lnAtasSterse = lnAtasInainte, ;
'nesterse=' + TRANSFORM(lnAtasNesterse) + ' sterse=' + TRANSFORM(lnAtasSterse)
lnAtasNou = NumaraAtasamente(lnIdVNou, -1)
DO asserteaza WITH 'B15 documentul nou nu are niciun atasament (porneste curat)', lnAtasNou = 0, TRANSFORM(lnAtasNou)
*!* auditul stergerii, ca la VANZARI: id_utils + dataoras completate pe randurile sterse
lnAtasAudit = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from atasamente_vanzari where sters = 1 ] + ;
[and id_vanzare = ] + TRANSFORM(lnIdV) + [ and id_utils = ] + TRANSFORM(gnIdUtil) + [ and dataoras is not null], @lnAtasAudit)
DO asserteaza WITH 'B16 randurile sterse poarta id_utils si dataoras', lnAtasAudit = lnAtasInainte, ;
TRANSFORM(lnAtasAudit) + ' vs ' + TRANSFORM(lnAtasInainte)
*!* --- S11: randul de borderou s-a mutat pe documentul nou (2.1) ---
IF glControlNegativ
DO asserteaza WITH 'CN mock-ul a preluat MutaBorderouReemitere (apeluri din .vc2)', ;
gnMockMutaApeluri > 0, TRANSFORM(gnMockMutaApeluri)
ENDIF
lnBordVechi = NumaraBorderouDetalii(lnIdBorderou, lnIdV)
DO asserteaza WITH 'B-b1 niciun rand de borderou nu mai sta pe id_vanzare vechi', lnBordVechi = 0, TRANSFORM(lnBordVechi)
lnBordNou = NumaraBorderouDetalii(lnIdBorderou, lnIdVNou)
DO asserteaza WITH 'B-b2 randul de borderou sta pe id_vanzare nou', lnBordNou = 1, TRANSFORM(lnBordNou)
lnBordView = NumaraViewBorderou(lnIdBorderou)
DO asserteaza WITH 'B-b3 borderoul nu a pierdut randul (1 rand in FACT_VBORDEROU_DETALII)', ;
lnBordView = 1, TRANSFORM(lnBordView)
lnTotalBordDupa = CitesteTotalBorderou(lnIdBorderou)
lnTotalVanzNou = -1
goExecutor.oSelecteaza2Value([select nvl(total_cu_tva,-1) as t from vanzari where id_vanzare = ] + TRANSFORM(lnIdVNou), @lnTotalVanzNou)
STRTOFILE('B-b4: total in borderou INAINTE=' + TRANSFORM(lnTotalBordInainte) + ' DUPA=' + ;
TRANSFORM(lnTotalBordDupa) + ' | total_cu_tva al documentului nou=' + TRANSFORM(lnTotalVanzNou) + ;
CHR(13) + CHR(10), gcErrLog, 1)
DO asserteaza WITH 'B-b4 borderoul arata totalul documentului NOU, nu al celui sters', ;
ABS(lnTotalBordDupa - lnTotalVanzNou) < 0.005 AND ABS(lnTotalBordDupa - lnTotalBordInainte) >= 0.005, ;
TRANSFORM(lnTotalBordInainte) + ' -> ' + TRANSFORM(lnTotalBordDupa) + ' (vanzari nou: ' + TRANSFORM(lnTotalVanzNou) + ')'
STRTOFILE('BORDEROU SEMANAT NECURATAT: id=' + TRANSFORM(lnIdBorderou) + ;
' - se sterge cu curata_s11_borderou.prg' + CHR(13) + CHR(10), gcErrLog, 1)
STRTOFILE('CONSUMAT: id_vanzare vechi=' + TRANSFORM(lnIdV) + ' nou=' + TRANSFORM(lnIdVNou) + ;
' cod vechi=' + TRANSFORM(lnCod) + ' ID_FACT vechi=' + TRANSFORM(lnIdFactVechi) + ' nou=' + TRANSFORM(lnIdFactNou) + ;
' serie/numar=' + TRANSFORM(lcSerieNou) + '/' + TRANSFORM(lnNumarNou) + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
*==============================================================================================
* RULAREA 3 (S9-5) - atomicitatea atasamentelor. Forteaza esecul reemiterii DUPA stergere si
* verifica ca rollback-ul readuce atasamentele la sters = 0. Nu consuma documentul.
*==============================================================================================
PROCEDURE Rularea3
LOCAL lnIdV, lnCod, lnTip, lnAn, lnLuna, lnIdFactVechi, lnDiscRon, lnDiscVal, loForm
LOCAL lnAtasInainte, lnAtasDupa, lnSters, lnIdVMaxInainte, lnNoi, llRez, lnLungSerie
LOCAL lnIdBorderou, lnBordDupa
IF !AlegeCandidat(@lnIdV, @lnCod, @lnTip, @lnAn, @lnLuna, .T.)
RETURN
ENDIF
lnIdFactVechi = 0
goExecutor.oSelecteaza2Value([select id_fact from vanzari where id_vanzare = ] + TRANSFORM(lnIdV), @lnIdFactVechi)
lnIdBorderou = SeamanaBorderou(lnIdV)
DO asserteaza WITH 'PRECONDITIE C: borderoul semanat s-a creat', lnIdBorderou > 0, TRANSFORM(lnIdBorderou)
DO SeamanaAtasamente WITH lnIdV
lnAtasInainte = NumaraAtasamente(lnIdV, 0)
DO asserteaza WITH 'PRECONDITIE C: documentul are 2 atasamente nesterse', lnAtasInainte = 2, TRANSFORM(lnAtasInainte)
IF lnAtasInainte <> 2
RETURN
ENDIF
lnIdVMaxInainte = 0
goExecutor.oSelecteaza2Value([select nvl(max(id_vanzare),0) as id from vanzari], @lnIdVMaxInainte)
DO urma WITH 'R3 IncarcaAntetFacturaEditare'
lnDiscRon = 0
lnDiscVal = 0
poDate = IncarcaAntetFacturaEditare(lnIdV, @lnDiscRon, @lnDiscVal)
IF VARTYPE(poDate) <> 'O'
DO asserteaza WITH 'C0 antetul s-a incarcat', .F., VARTYPE(poDate)
RETURN
ENDIF
IncarcaLiniiFacturaEditare(poDate, lnIdV)
IF !USED('crsfactura') OR RECCOUNT('crsfactura') = 0
DO asserteaza WITH 'C0 liniile s-au incarcat', .F., '0'
RETURN
ENDIF
update_jtva_coloane([JV], [jtva_coloane_temp])
update_saft_taxtable()
IF USED('jtva_coloane')
USE IN jtva_coloane
ENDIF
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
loForm = CREATEOBJECT('frm_facturare_articole2')
loForm.ndiscfactron = lnDiscRon
loForm.ndiscfactval = lnDiscVal
loForm.do_calculeaza_totaluri()
poSnapshotEditare = CreeazaSnapshotEditare(poDate, loForm.ndiscfactron, loForm.ndiscfactval, lnIdV, lnIdFactVechi, lnCod, lnAn, lnLuna)
IF VARTYPE(poSnapshotEditare) <> 'O'
DO asserteaza WITH 'C0 instantaneul s-a creat', .F., VARTYPE(poSnapshotEditare)
RETURN
ENDIF
SELECT crsfactura
GO TOP
REPLACE cantitate WITH cantitate + 1 IN crsfactura
loForm.do_calculeaza_totaluri()
*!* esecul fortat: serie mai lunga decat coloana => eroare Oracle la scrierea antetului nou,
*!* adica DUPA stergerea documentului vechi si DUPA stergerea atasamentelor
lnLungSerie = 0
goExecutor.oSelecteaza2Value([select data_length from all_tab_columns where owner = '] + gcs + ;
[' and table_name = 'VANZARI' and column_name = 'SERIE_ACT'], @lnLungSerie)
DO asserteaza WITH 'C0 lungimea coloanei SERIE_ACT s-a citit', lnLungSerie > 0, TRANSFORM(lnLungSerie)
IF lnLungSerie <= 0
RETURN
ENDIF
poDate.serie_act = REPLICATE('Z', lnLungSerie + 5)
*!* fara ruta 1 nu s-ar intra deloc in blocul de regenerare, iar C2/C3 ar trece degeaba
DO asserteaza WITH 'C0b ruta aleasa este 1 (regenerare)', ;
AlegeRutaScriereEditare(poSnapshotEditare, poDate, loForm.ndiscfactron, loForm.ndiscfactval, 'crsfactura') = 1, ;
TRANSFORM(AlegeRutaScriereEditare(poSnapshotEditare, poDate, loForm.ndiscfactron, loForm.ndiscfactval, 'crsfactura'))
DO urma WITH 'R3 do_scrie_factura (asteptat ESEC)'
gcMockUltimMesaj = ''
glRegenerareEditare = .T.
llRez = loForm.do_scrie_factura()
glRegenerareEditare = .F.
DO urma WITH 'R3 do_scrie_factura a revenit'
DO asserteaza WITH 'C1 do_scrie_factura() a esuat, cum s-a fortat', !llRez, TRANSFORM(llRez)
*!* esecul trebuie sa fie AL SCRIERII, nu al stergerii - altfel blocul de atasamente nu a rulat
STRTOFILE('R3 ultimul mesaj prin mock: [' + gcMockUltimMesaj + ']' + CHR(13) + CHR(10), gcErrLog, 1)
DO asserteaza WITH 'C1b esecul e la scrierea documentului nou, nu la stergere/atasamente', ;
!('nu a putut fi sters' $ LOWER(gcMockUltimMesaj)) AND !('atasamentele documentului vechi' $ LOWER(gcMockUltimMesaj)), ;
gcMockUltimMesaj
lnSters = -1
goExecutor.oSelecteaza2Value([select sters from vanzari where id_vanzare = ] + TRANSFORM(lnIdV), @lnSters)
DO asserteaza WITH 'C2 rollback-ul a readus documentul vechi (sters = 0)', lnSters = 0, TRANSFORM(lnSters)
lnAtasDupa = NumaraAtasamente(lnIdV, 0)
DO asserteaza WITH 'C3 rollback-ul a readus si atasamentele (sters = 0)', lnAtasDupa = lnAtasInainte, ;
TRANSFORM(lnAtasDupa) + ' vs ' + TRANSFORM(lnAtasInainte)
lnNoi = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from vanzari where id_vanzare > ] + TRANSFORM(lnIdVMaxInainte), @lnNoi)
DO asserteaza WITH 'C4 niciun document nou nu a ramas in urma', lnNoi = 0, TRANSFORM(lnNoi)
*!* esecul cade INAINTE de mutarea borderoului (scrierea antetului nou), deci randul nu are voie
*!* sa se fi miscat - garda impotriva unei mutari scapate in afara tranzactiei
lnBordDupa = NumaraBorderouDetalii(lnIdBorderou, lnIdV)
DO asserteaza WITH 'C5 randul de borderou a ramas pe documentul vechi', lnBordDupa = 1, TRANSFORM(lnBordDupa)
*!* curatenie: atasamentele si borderoul semanate se sterg fizic, documentul ramane refolosibil
goExecutor.oExecuta([delete from ] + gcs + [.atasamente_vanzari where id_vanzare = ] + TRANSFORM(lnIdV))
goExecutor.oExecuta([COMMIT])
DO CurataBorderouSemanat WITH lnIdBorderou
STRTOFILE('R3: atasamentele semanate pe ' + TRANSFORM(lnIdV) + ' au fost sterse fizic; documentul NU a fost consumat' + ;
CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
*==============================================================================================
* RULAREA 5 (S11) - atomicitatea mutarii. Cheama MutaBorderouReemitere REALA sub tranzactie
* manuala si verifica pe al doilea handle ca nimic n-a scapat comis; rollback la final.
* Nu consuma documentul.
*==============================================================================================
PROCEDURE Rularea5
LOCAL lnIdV, lnCod, lnTip, lnAn, lnLuna, lnIdBorderou, lnH2, lnIdTinta
LOCAL llMutat, lnTranz, lnVechiH1, lnNouH1, lnVechiH2, lnNouH2
IF !AlegeCandidat(@lnIdV, @lnCod, @lnTip, @lnAn, @lnLuna, .T.)
RETURN
ENDIF
lnIdBorderou = SeamanaBorderou(lnIdV)
DO asserteaza WITH 'PRECONDITIE D: borderoul semanat s-a creat', lnIdBorderou > 0, TRANSFORM(lnIdBorderou)
IF lnIdBorderou <= 0
RETURN
ENDIF
*!* tinta = alt document real: FACT_BORDEROU_DETALII are FK pe VANZARI, un id inexistent ar pica
*!* pe constrangere si proba ar masura constrangerea, nu atomicitatea
lnIdTinta = 0
goExecutor.oSelecteaza2Value([select nvl(min(id_vanzare),0) as id from vanzari where id_vanzare <> ] + TRANSFORM(lnIdV), @lnIdTinta)
DO asserteaza WITH 'D0 exista un id_vanzare tinta real', lnIdTinta > 0, TRANSFORM(lnIdTinta)
IF lnIdTinta <= 0
DO CurataBorderouSemanat WITH lnIdBorderou
RETURN
ENDIF
SQLSetprop(0, "DispLogin", 3)
lnH2 = SQLSTRINGCONNECT("dsn=CENTRAL;Uid=MARIUSM_AUTO;Pwd=ROMFASTSOFT;")
DO asserteaza WITH 'D0b al doilea handle Oracle deschis', lnH2 > 0, TRANSFORM(lnH2)
IF lnH2 <= 0
DO CurataBorderouSemanat WITH lnIdBorderou
RETURN
ENDIF
SQLEXEC(gnHandle, "select * from dual", "v_dual_s11")
IF USED('v_dual_s11')
USE IN v_dual_s11
ENDIF
SQLSetprop(gnHandle, "Transactions", 2)
llMutat = MutaBorderouReemitere(lnIdV, lnIdTinta)
DO asserteaza WITH 'D1 MutaBorderouReemitere a intors .T. sub tranzactie manuala', llMutat, TRANSFORM(llMutat)
lnTranz = SQLGetprop(gnHandle, "Transactions")
DO asserteaza WITH 'D2 tranzactia manuala e inca deschisa dupa mutare (Transactions = 2)', lnTranz = 2, TRANSFORM(lnTranz)
lnNouH1 = NumaraBorderouDetalii(lnIdBorderou, lnIdTinta)
DO asserteaza WITH 'D3 in interiorul tranzactiei randul e pe id-ul tinta', lnNouH1 = 1, TRANSFORM(lnNouH1)
lnVechiH2 = NumaraDetaliiPeHandle(lnH2, lnIdBorderou, lnIdV)
lnNouH2 = NumaraDetaliiPeHandle(lnH2, lnIdBorderou, lnIdTinta)
DO asserteaza WITH 'D4 pe al doilea handle mutarea NU a scapat comisa (inca pe id-ul vechi)', ;
lnVechiH2 = 1 AND lnNouH2 = 0, 'vechi=' + TRANSFORM(lnVechiH2) + ' tinta=' + TRANSFORM(lnNouH2)
SQLRollback(gnHandle)
SQLSetprop(gnHandle, "Transactions", 1)
lnVechiH1 = NumaraBorderouDetalii(lnIdBorderou, lnIdV)
lnNouH1 = NumaraBorderouDetalii(lnIdBorderou, lnIdTinta)
DO asserteaza WITH 'D5 dupa rollback randul a revenit pe id_vanzare vechi', ;
lnVechiH1 = 1 AND lnNouH1 = 0, 'vechi=' + TRANSFORM(lnVechiH1) + ' tinta=' + TRANSFORM(lnNouH1)
SQLDISCONNECT(lnH2)
DO CurataBorderouSemanat WITH lnIdBorderou
STRTOFILE('rularea 5 NU a consumat documentul ' + TRANSFORM(lnIdV) + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
*==============================================================================================
* S11: semanarea borderoului (prin procedurile de productie), numararea si curatenia.
*==============================================================================================
FUNCTION SeamanaBorderou
LPARAMETERS tnIdVanzare
LOCAL lnIdPart, lnMaxInainte, lnId, llOk
lnIdPart = 0
goExecutor.oSelecteaza2Value([select id_part from vanzari where id_vanzare = ] + TRANSFORM(tnIdVanzare), @lnIdPart)
IF EMPTY(NVL(lnIdPart, 0))
STRTOFILE('SeamanaBorderou: documentul ' + TRANSFORM(tnIdVanzare) + ' nu are id_part' + CHR(13) + CHR(10), gcErrLog, 1)
RETURN 0
ENDIF
lnMaxInainte = 0
goExecutor.oSelecteaza2Value([select nvl(max(id),0) as id from ] + gcs + [.fact_borderou], @lnMaxInainte)
llOk = goExecutor.oExecuta([declare n number; begin ] + gcs + [.pack_fact_borderou.BorderouNou(] + ;
TRANSFORM(lnIdPart) + [, ] + TRANSFORM(gnIdUtil) + [, n); ] + gcs + ;
[.pack_fact_borderou.BorderouAdaugaFactura(n, ] + TRANSFORM(tnIdVanzare) + [); end;])
IF !llOk
STRTOFILE('SeamanaBorderou ESEC: ' + goExecutor.cEroare + CHR(13) + CHR(10), gcErrLog, 1)
goExecutor.oExecuta([ROLLBACK])
RETURN 0
ENDIF
goExecutor.oExecuta([COMMIT])
lnId = 0
goExecutor.oSelecteaza2Value([select nvl(max(id),0) as id from ] + gcs + [.fact_borderou where id > ] + TRANSFORM(lnMaxInainte), @lnId)
STRTOFILE('SeamanaBorderou: id_part=' + TRANSFORM(lnIdPart) + ' id_borderou=' + TRANSFORM(lnId) + ;
' pe id_vanzare=' + TRANSFORM(tnIdVanzare) + CHR(13) + CHR(10), gcErrLog, 1)
RETURN lnId
ENDFUNC
FUNCTION NumaraBorderouDetalii
LPARAMETERS tnIdBorderou, tnIdVanzare
LOCAL lnNr
lnNr = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from ] + gcs + [.fact_borderou_detalii where id_borderou = ] + ;
TRANSFORM(tnIdBorderou) + [ and id_vanzare = ] + TRANSFORM(tnIdVanzare), @lnNr)
RETURN lnNr
ENDFUNC
FUNCTION NumaraViewBorderou
LPARAMETERS tnIdBorderou
LOCAL lnNr
lnNr = -1
goExecutor.oSelecteaza2Value([select count(*) as nr from ] + gcs + [.fact_vborderou_detalii where id_borderou = ] + ;
TRANSFORM(tnIdBorderou), @lnNr)
RETURN lnNr
ENDFUNC
FUNCTION CitesteTotalBorderou
LPARAMETERS tnIdBorderou
LOCAL lnTot
lnTot = -1
goExecutor.oSelecteaza2Value([select nvl(sum(total_cu_tva),-1) as t from ] + gcs + ;
[.fact_vborderou_detalii where id_borderou = ] + TRANSFORM(tnIdBorderou), @lnTot)
RETURN lnTot
ENDFUNC
PROCEDURE CurataBorderouSemanat
LPARAMETERS tnIdBorderou
IF EMPTY(NVL(tnIdBorderou, 0))
RETURN
ENDIF
goExecutor.oExecuta([delete from ] + gcs + [.fact_borderou_detalii where id_borderou = ] + TRANSFORM(tnIdBorderou))
goExecutor.oExecuta([delete from ] + gcs + [.fact_borderou where id = ] + TRANSFORM(tnIdBorderou))
goExecutor.oExecuta([COMMIT])
STRTOFILE('borderoul semanat ' + TRANSFORM(tnIdBorderou) + ' a fost sters fizic' + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
PROCEDURE NumaraDetaliiPeHandle
LPARAMETERS tnHandle, tnIdBorderou, tnIdVanzare
LOCAL lnRez, lnVal
lnVal = -1
IF USED('v_h2_s11')
USE IN v_h2_s11
ENDIF
lnRez = SQLEXEC(tnHandle, "select count(*) as nr from fact_borderou_detalii where id_borderou = " + ;
TRANSFORM(tnIdBorderou) + " and id_vanzare = " + TRANSFORM(tnIdVanzare), "v_h2_s11")
IF lnRez > 0 AND USED('v_h2_s11')
SELECT v_h2_s11
GO TOP
lnVal = NVL(nr, -1)
USE IN v_h2_s11
ENDIF
RETURN lnVal
ENDPROC
*==============================================================================================
* S9-5: semanarea si numararea atasamentelor. tnSters = -1 numara toate randurile.
*==============================================================================================
PROCEDURE SeamanaAtasamente
LPARAMETERS tnIdVanzare
LOCAL lnExistente, llOk
lnExistente = NumaraAtasamente(tnIdVanzare, -1)
IF lnExistente > 0
STRTOFILE('SeamanaAtasamente: documentul ' + TRANSFORM(tnIdVanzare) + ' are deja ' + ;
TRANSFORM(lnExistente) + ' randuri - nu se mai seamana' + CHR(13) + CHR(10), gcErrLog, 1)
RETURN
ENDIF
llOk = goExecutor.oExecuta([begin insert into ] + gcs + [.atasamente_vanzari ] + ;
[(id_vanzare, tip, format, document, id_util) values (] + TRANSFORM(tnIdVanzare) + ;
[, 1, 'A4', utl_raw.cast_to_raw('proba S9-5 factura'), ] + TRANSFORM(gnIdUtil) + [); ] + ;
[insert into ] + gcs + [.atasamente_vanzari ] + ;
[(id_vanzare, tip, format, document, id_util) values (] + TRANSFORM(tnIdVanzare) + ;
[, 5, 'A4', utl_raw.cast_to_raw('proba S9-5 aviz'), ] + TRANSFORM(gnIdUtil) + [); end;])
IF llOk
goExecutor.oExecuta([COMMIT])
ENDIF
STRTOFILE('SeamanaAtasamente pe id_vanzare=' + TRANSFORM(tnIdVanzare) + ': ' + ;
IIF(llOk, 'OK', 'ESEC ' + goExecutor.cEroare) + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
FUNCTION NumaraAtasamente
LPARAMETERS tnIdVanzare, tnSters
LOCAL lnNr, lcFiltru
lnNr = -1
lcFiltru = IIF(tnSters < 0, '', [ and sters = ] + TRANSFORM(tnSters))
goExecutor.oSelecteaza2Value([select count(*) as nr from ] + gcs + [.atasamente_vanzari where id_vanzare = ] + ;
TRANSFORM(tnIdVanzare) + lcFiltru, @lnNr)
RETURN lnNr
ENDFUNC
*==============================================================================================
* Alegerea candidatului: STERS=0, perioada activa, randuri in vact_tot, fara referinte/urmasi.
* tlDoarOtherwise = .T. exclude tipurile cu ramura proprie in do_scrie_factura (proforma, 4,
* 3/21/25/28/42/47) - raman doar cele care cad pe Otherwise.
*==============================================================================================
PROCEDURE AlegeCandidat
LPARAMETERS tnIdV, tnCod, tnTip, tnAn, tnLuna, tlDoarOtherwise
LOCAL lcSql, lcExclusi, lnOk, lnGasit, lnIdFactCand
*!* 1111/1112: articolul 315554536 nu are gestiune - reemiterea pica pe FACT-007, inainte de
*!* orice asertiune S9/S11 (conditie de date, nu regresie)
lcExclusi = [1047,1048,1055,1111,1112,1113,1130]
lcSql = [select v.id_vanzare, v.cod, v.tip, v.data_act, v.id_fact from vanzari v where v.sters = 0 ] + ;
[ and extract(year from v.data_act) = ] + TRANSFORM(gnAn) + ;
[ and extract(month from v.data_act) = ] + TRANSFORM(gnLuna) + ;
[ and nvl(v.eproforma,0) = 0 ] + ;
[ and v.id_vanzare not in (] + lcExclusi + [) ] + ;
[ and exists (select 1 from ] + gcs + [.vact_tot a where a.sters = 0 and a.an = ] + TRANSFORM(gnAn) + ;
[ and a.luna = ] + TRANSFORM(gnLuna) + [ and a.cod = v.cod) ]
IF tlDoarOtherwise
*!* linii reale cu cantitate > 0 - un document degenerat (cantitate 0) nu probeaza reemiterea
*!* total > 0: pe MARIUSM_AUTO exista ~40 de documente reziduale (total_cu_tva = 0,
*!* id_articol 4294507490, nr_incasare fara lista de incasare) pe care scrie_factura2 pica cu
*!* parametru vid - nu probeaza nici reemiterea, nici asertiunile pe sume
lcSql = lcSql + [ and v.tip not in (4,3,21,25,28,42,47,44,45,46,51) ] + ;
[ and nvl(v.total_cu_tva,0) > 0 ] + ;
[ and exists (select 1 from vanzari_detalii d where d.sters = 0 and d.id_vanzare = v.id_vanzare ] + ;
[ and nvl(d.cantitate,0) > 0) ]
ENDIF
lcSql = lcSql + [order by v.id_vanzare]
IF USED('v_cand_s94')
USE IN v_cand_s94
ENDIF
lnOk = goExecutor.oExecuta(lcSql, 'v_cand_s94')
DO asserteaza WITH 'interogarea de candidati a reusit', lnOk, TRANSFORM(lnOk)
IF !lnOk
RETURN .F.
ENDIF
lnGasit = 0
SELECT v_cand_s94
SCAN
*!* valorile se citesc INAINTE de garzi - ReferinteDocumenteNota/DocumentAreUrmasi/EsteInEFactura
*!* isi deschid propriile cursoare si schimba zona de lucru curenta
tnIdV = id_vanzare
tnCod = cod
tnTip = tip
tnAn = YEAR(data_act)
tnLuna = MONTH(data_act)
lnIdFactCand = NVL(id_fact, 0)
IF !ReferinteDocumenteNota(tnAn, tnLuna, tnCod) AND !DocumentAreUrmasi(tnIdV) AND !EsteInEFactura(lnIdFactCand)
lnGasit = 1
EXIT
ENDIF
ENDSCAN
USE IN v_cand_s94
DO asserteaza WITH 'exista un candidat eligibil', lnGasit = 1, TRANSFORM(lnGasit)
IF lnGasit = 0
RETURN .F.
ENDIF
STRTOFILE('candidat ales: id_vanzare=' + TRANSFORM(tnIdV) + ' cod=' + TRANSFORM(tnCod) + ;
' tip=' + TRANSFORM(tnTip) + ' an/luna=' + TRANSFORM(tnAn) + '/' + TRANSFORM(tnLuna) + CHR(13) + CHR(10), gcErrLog, 1)
RETURN .T.
ENDPROC
PROCEDURE CitesteStersPeHandle
LPARAMETERS tnHandle, tnIdVanzare
LOCAL lnRez, lnVal
lnVal = -1
IF USED('v_h2_s94')
USE IN v_h2_s94
ENDIF
lnRez = SQLEXEC(tnHandle, "select sters from vanzari where id_vanzare = " + TRANSFORM(tnIdVanzare), "v_h2_s94")
IF lnRez > 0 AND USED('v_h2_s94')
SELECT v_h2_s94
IF RECCOUNT('v_h2_s94') = 1
GO TOP
lnVal = NVL(sters, -1)
ENDIF
USE IN v_h2_s94
ENDIF
RETURN lnVal
ENDPROC
PROCEDURE urma
LPARAMETERS tcPas
STRTOFILE('URMA ' + TTOC(DATETIME()) + ' ' + m.tcPas + CHR(13) + CHR(10), gcErrLog, 1)
ENDPROC
PROCEDURE asserteaza
LPARAMETERS tcNume, tlConditie, tcValoare
IF m.tlConditie
gnPass = gnPass + 1
STRTOFILE('PASS ' + m.tcNume + CHR(13) + CHR(10), gcErrLog, 1)
ELSE
gnFail = gnFail + 1
STRTOFILE('FAIL ' + m.tcNume + ' (valoare: ' + TRANSFORM(m.tcValoare) + ')' + CHR(13) + CHR(10), gcErrLog, 1)
ENDIF
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