ROAFACTURARE 2.11.15 (r18015): programe/ofacturare_editare.prg, programe/ofacturare_stoc.prg. docs: conventia de encoding .sc2/.vc2 corectata la cp1250; cercetarile trans-proiect mutate din ROAFACTURARE in docs/cercetare (r18014); actualizari reguli_lucru, oracle_export, flux-editare-vfp-text, scripturi-migrare-db, flux-modificare-stergere-nota-jurnal, todos. .gitignore: watchdog_out si PNG-urile din rularile headless (r18008). Text FoxBin2Prg regenerat: clase/comun.vc2, ferestre/frm_import_note_facturi_clienti.sc2, ferestre/frm_initializare_facturi_balanta.sc2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AV7dQbTLAqvrtQbH7zxXxw
11 KiB
Flux: modificare/stergere nota in Registrul Jurnal
Comportament CORECT (nu bug): la modificarea unei note din Registrul Jurnal, documentul
original nu se suprascrie. Se marcheaza sters = 1 pe randurile vechi (ACT/RUL/RUL_OBINV),
apoi se scrie un document NOU cu alt cod, pastrand acelasi id_fact/id_factd. Ambele operatii
ruleaza intr-o tranzactie manuala unica (commit sau rollback pe amandoua).
Unde
afisjurcom.do_modifica-COMUN\clase\comun.vc2:2222-2562. Deschide tranzactia manuala (Thisform.do_deschide_tranzactie(), linia 2448), apoioscrie_in_fisiere(2,...)= STERGE (linia 2451), apoioscrie_in_fisiere(0,...)= SCRIE (linia 2479), apoipack_contafin.finalizeaza_modificare_nota(...)(2484-2486), apoiThisform.do_inchide_tranzactie(...)(linia 2535) - commit daca tot ce a rulat inainte a reusit, rollback altfel.do_deschide_tranzactie/do_inchide_tranzactie(_frmbase,COMUN\clase\_frm_base.vc2:252,279; varianta identica ca procedura globala inCOMUN\programe\oproceduri_rulaje.prg:287,303):SQLSetProp(gnHandle,'Transactions',2)la deschidere,SQLCOMMIT/SQLROLLBACK+SQLSetProp(...,'Transactions',1)la inchidere.oscrie_in_fisiere.prg(COMUN\programe\oscrie_in_fisiere.prg):tnScrie_Sterge0=scriere, 2=stergere. Apeleaza server-sidepack_contafin.init_scriere_act_rul_local+final_scriere_act_rul_local->finalizeaza_scriere_act_rul, care ruleazaSCRIE_IN_ACT(scriere) sauSTERGE_DIN_ACT(stergere) dinPACK_CONTAFIN.pck.PACK_CONTAFIN.STERGE_DIN_ACT(COMUN\docs\PACK_CONTAFIN.pck:1815-1859):UPDATE ACT SET STERS = 1 ... WHERE COD = tnCod- marcheaza vechiul document, pecod-ul vechi.PACK_CONTAFIN.SCRIE_IN_ACT(PACK_CONTAFIN.pck:630-901):LN_COD := pack_contafin.GET_COD()(linia 648) aloca uncodnou;UPDATE ACT_TEMP SET COD = LN_COD, ...(linia 897) il scrie pe noul document -ID_FACTnu e atins, ramane cel din documentul original.PACK_CONTAFIN.finalizeaza_modificare_nota(PACK_CONTAFIN.pck:8601-8651): aloca din noulnCodNou := pack_contafin.get_cod()si actualizeaza pe codul nouvanzari(pack_facturare.actualizeaza_vanzari) siatasamente_vanzari.nom_lucrarise actualizeaza DOAR pentruid_set IN (31003,31004,31005,31011)(repuneid_fact), nu general.gest_inventarNU se leaga decod-ul nou - se identifica dupadataora_validat + an + luna(cazulid_set = 90101, note de inventariere).
Atentie: nu e valabil la fel pentru stergerea simpla
afisjurcom.do_sterge (comun.vc2:2565-2724) ofera doua optiuni (xmenu, linia 2625):
- Stergere document (
lnOptiune = 1): DOAROSCRIE_IN_FISIERE(2,...)+finalizeaza_stergere_nota- marcheaza
sters = 1, NU se creeaza document nou.
- marcheaza
- Anulare document (
lnOptiune = 2): STERGE (linia 2698) + SCRIE (linia 2709, cu sumele puse pe 0) - creeaza si document nou, la fel ca la modificare - dar aici cele doua apeluri NU sunt invelite intr-o tranzactie manuala comuna (nu aparedo_deschide_tranzactie/do_inchide_tranzactieindo_sterge); fiecareOSCRIE_IN_FISIEREisi gestioneaza singur commit-ul (vezitlModificare/llManualTransactionsinoscrie_in_fisiere.prg:111-165).
Ramura noua: editare factura de vanzare (VANZARI/VANZARI_DETALII)
Cand documentul modificat prin frm_modific2024 are un rand corespunzator in VANZARI, clasa
adauga o pagina noua in pageframe-ul de rulaje, PAGE3 "Articole factura"
(COMUN\clase\omodificari.vc2:8707), cu un grid legat pe cursorul tvd (structura view-ului
VVANZARI_ARTICOLE). Pe orice alt document (nota fara factura) formularul ramane neschimbat -
pageframe-ul are PageCount = 2, ca azi.
Ramura e activa doar cand COMUN\programe\ofacturare_editare.prg e incarcat in SET PROCEDURE
(verificat prin "OFACTURARE_EDITARE" $ Upper(Set("Procedure"))) - inregistrat la pornire de toate
trei aplicatiile care folosesc frm_modific2024: ROAFACTURARE\Programe\roafacturare.prg:214,
ROACONT\Programe\roacont.prg:212, ROAGEST\Programe\roagest.prg:260.
Doua puncte de intrare
frm_facturi.do_editare_factura(COMUN\clase\ofacturare_comun.vc2:3715-3872), actiune noua pe formularul de facturi din ROAFACTURARE. Refuza editarea daca documentul e sters, e proforma, nu e din luna curenta (:3742-3755), are referinte de incasari/plati (ReferinteDocumenteNota,:3758) sau a fost trimis in eFactura (EsteInEFactura, inofacturare_editare.prg,:3764). Inainte deCreateobject([frm_modific2024])incarcacrsArticoleFacturacuIncarcaArticoleFactura(:3793), ca gridul din PAGE3 sa se lege o singura data pe cursorul deja plin.afisjurcom.do_modifica(COMUN\clase\comun.vc2:2222-2567) - acelasi punct folosit pentru orice nota din Registrul Jurnal, neschimbat pentru documentele care nu sunt facturi de vanzare. Inainte deCreateobject,PregatesteArticoleFacturaEditare('tact')(:2436, inofacturare_editare.prg) cauta randul dinVANZARIcorespunzator notei (pe combinatiilecod/nract/serie_act/dataactdintact) si, daca il gaseste, pre-incarca articolele. Pe acest punct de intrare nu se verifica garda eFactura si nici cea de referinte de incasari/plati - doar restrictia de luna curenta, deja existenta pentru orice nota (:2265-2268). Diferenta e intentionata: garda de referinte protejeaza incasarile legate prinid_factla operatia care sterge efectiv factura; pe editarea de sume din ROAFACTURARE se aplica pentru ca stergerea si rescrierea notei sunt parte din acelasi pas, dar pe editarea generica de note din Registrul Jurnal (care poate sa nu priveasca deloc o factura) nu se aplica.
Daca apelantul nu a putut pregati articolele dinainte, frm_modific2024.Show reface legatura prin
IncarcaVanzareDinNota ca fallback si decide acolo daca arata PAGE3
(omodificari.vc2:14769-14794).
Scrierea, in aceeasi tranzactie manuala
La buton = 1 (Terminat), pasul nou se adauga la coada secventei existente de
stergere+scriere+realiniere, in aceeasi tranzactie manuala unica, identic pe ambele puncte de
intrare (ofacturare_comun.vc2:3828-3830, comun.vc2:2491-2493):
do_deschide_tranzactie()
oscrie_in_fisiere(2,...) -- sterge nota veche (ACT/RUL)
oscrie_in_fisiere(0,...) -- scrie nota noua, cod nou
pack_contafin.finalizeaza_modificare_nota(...) -- realiniaza VANZARI.COD (actualizeaza_vanzari)
ScrieArticoleFacturaEditate(tvanz.id_vanzare) -- NOU
do_inchide_tranzactie(...)
Agatarea ruleaza doar cand tvanz e deschis cu exact un rand (documentul are factura asociata).
VANZARI.ID_FACT nu e atins de niciun pas al secventei - ramane cel alocat la emiterea initiala a
facturii, la fel ca la orice alta nota (vezi "Implicatii practice"); doar VANZARI.COD se
realiniaza pe codul nou al notei. Tot ce se leaga prin id_fact (ANAF_EFACTURA, DOCUMENTE,
ACT.id_factd/id_factc) sau prin ID_VANZARE supravietuieste neschimbat unei reeditari; doar ce
ar tine minte cod-ul vechi il pierde.
pack_facturare.actualizeaza_vanzari, apelata din finalizeaza_modificare_nota, face
UPDATE VANZARI_DETALII SET STERS = 0 pe tot documentul, fara nicio garda pe linie - reseteaza si
liniile sterse la o editare anterioara. De aceea ScrieArticoleFacturaEditate ruleaza DUPA
finalizeaza_modificare_nota, nu inauntrul ei: scrierea liniilor trebuie sa vina dupa acest reset,
ca sa-l corecteze, nu inaintea lui.
ScrieArticoleFacturaEditate (COMUN\programe\ofacturare_editare.prg:468-555):
- marcheaza
sters = 1pe tot documentul dinVANZARI_DETALII(:489-491); - invie si actualizeaza liniile pastrate din
tvd(cantitate, pret, pret_cu_tva -pret_achizitiese omite, ramane valoarea persistata) (:497-506); - insereaza liniile noi (
id_vanzare_det = 0), faraid_vanzare_detexplicit - il genereaza trigger-ulTRG_VANZARI_DET_BEFOINS(:518-535); - apeleaza
pack_facturare.recalculeaza_totaluri_vanzari(id_vanzare, discount)(:544-548), cu discountul luat dintvanz.discount;NULLpastreaza valoarea curenta dinVANZARIin loc s-o zeroeze.
O linie stearsa de utilizator la o editare ramane stearsa si dupa reeditari ulterioare - fiecare
salvare reface pasii 1-2 pe starea curenta din tvd, deci resetul din actualizeaza_vanzari e
mereu corectat inainte sa ajunga vizibil.
pack_facturare.recalculeaza_totaluri_vanzari (script de migrare
ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql) recalculeaza din VANZARI_DETALII - liniile proprii
si, separat, liniile din seturi agregate din VANZARI_SETURI - coloanele discount,
discount_tva, valoare_achizitie, total_fara_tva, total_tva, total_cu_tva, valval,
tvaval, totval, id_valuta, curs, multiplicator, cu acelasi calcul per-linie ca la emitere
(calculeaza_total_fara_tva_fact/calculeaza_total_tva_fact). Coloanele de incasare
(serie_incasat/nr_incasat/suma_incasat/tip_incasat) nu sunt atinse.
View-ul VVANZARI_ARTICOLE (script de migrare ff_2026_08_09_02_COMUN_VVANZARI_ARTICOLE.sql)
expune direct VANZARI_DETALII, cu id_vanzare_set si pret_achizitie printre coloanele proprii
ale tabelei, plus denumire/codmat/nume_gestiune/nume_val din join-uri - sursa cursorului tvd.
Editarea in grid
Gridul pgfArticole.PAGE3.grdArticoleFactura (omodificari.vc2:12320-...) e legat pe tvd. Linia
provenita dintr-un set (id_vanzare_set <> 0) e needitabila (cantitate, pret, pret_cu_tva) si
apare intr-o culoare distincta in grid (DynamicForeColor); coloana pret_achizitie e editabila
doar pe liniile noi (id_vanzare_set = 0 AND id_vanzare_det = 0), doar-afisare pe restul
(:16526-16552). Stergerea unei linii e logica - cmdStergeArticol.Click comuta sters pe randul
curent din tvd, ramane vizibila grizata pana la salvare (:16508-16517). Adaugarea reutilizeaza
dialogul frm_articol_factura de la compunerea facturii (:16497-16505).
Inainte de salvare (inainte_de_do_termin, :14329-14386, activa doar cand
ofacturare_editare.prg e incarcat si tvd exista), pentru fiecare linie activa din tvd: opreste
salvarea daca are cantitate <= 0, pret nul sau nu are articol asociat; cere confirmare daca o linie
noua are pretul de achizitie 0, respectiv daca toate liniile facturii au fost sterse.
Implicatii practice
- Codul (
cod) unui document din Registrul Jurnal NU e stabil dupa modificare/anulare - se schimba la fiecare editare. Cod hardcodat sau retinut dintr-o executare anterioara devine invalid. - Regasirea documentului editat se face dupa
id_fact(sau alt marcaj stabil), niciodata dupacod. - Randurile
sters = 1ramase inACT/RUL/RUL_OBINVdupa o modificare sunt normale (istoric), nu date corupte sau duplicate de curatat. - Editarea unei facturi de vanzare (document cu rand in
VANZARI) reface si liniile si totalurile denormalizate dinVANZARI/VANZARI_DETALII, in aceeasi tranzactie cu nota - vezi ramura de mai sus. - Documentele care nu sunt facturi de vanzare nu sunt atinse de aceasta ramura - pagina de articole
nu apare si scrierea in
VANZARI_DETALIInu se declanseaza (garda:Reccount('tvanz') = 1).