* 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