Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
20 KiB
Cercetare: editare factura emisa (netrimisa inca in eFactura)
Sursa: cache text .??2 (deja la zi, negenerate acum) + .prg din working copy
D:\ROA\ROAFACTURARE. Cod Oracle (pachete PACK_FACTURARE, PACK_CONTAFIN, PACK_DOCUMENTE)
NU e in working copy — doar apelurile RPC din VFP sunt vizibile; corpul PL/SQL trebuie cautat
in schema Oracle, nu exista local.
1. Fluxul de EMITERE factura
Punct de intrare (meniu -> procedura generica factureaza), COMUN\programe\oproceduri_facturare.prg:
facturare_contracte(:130-134) ->factureaza(2/6/52)— pe baza de contractfacturare_comenzi(:140) ->factureaza(3)— pe baza de comandafacturare_avize(:145) ->factureaza(4)— pe baza de avizemitere_aviz_clienti/_debitori/_custodie/_transfer(:203-275) ->factureaza(tip)cu tip-uri diverse pentru avize (comanda/lista preturi/contract/lucrare/NIR/retur)copiere_factura(:152) ->factureaza(toFactura.Tip, toFactura)— copiere/modificare-inainte-de-emitere (nu e "editare dupa emitere", e o factura noua pornita din datele alteia)
factureaza (COMUN\programe\ofacturare.prg:90) delegheaza imediat la factureaza2 (acelasi fisier,
:170+; bucla mare pana ~:850). Pasi, in ordine:
- Formular date antet:
frm_date_factura/frm_date_aviz/frm_date_aviz_lucrare(alegere dupatnTip,ofacturare.prg:220-226) — culege client, data, delegat, ruta, incasare etc. in obiectulpoDate. - Alocare numar document:
poGeneratorNumere.verifica_numar(...)/.dezaloca_numar(...)(:250-260) — numerotare seriala pe tip document, alocata/deblocata aici. - Populare cursor articole, ramificat dupa
tnTip(vezi punctul 6 mai jos) — cheama diversepack_facturare.cursor_*(preturi/contract/comanda/avize/gestiune/lucrare/retur/aviz_nir) —:266-308. - Formular articole:
frm_facturare_articole/frm_facturare_articole2/frm_avizare_lucrare(COMUN\clase\ofacturare.vc2) — user editeaza cantitati/preturi/explicatii inainte de scriere efectiva. - Scriere efectiva — metoda
do_scrie_facturaa formularului de articole (COMUN\clase\ofacturare.vc2:14067-14360, dublata identic infrm_facturare_articole2la:18090-18370):pack_facturare.scrie_proforma(...)(:14071) — doar dacapoDate.eProforma=1: scrie doar in VANZARI, explicit comentat in cod "nu si in contabilitate" (:14070).pack_facturare.scrie_factura_avize(...)(:14103) — candpoDate.Tip = 4(facturare din aviz).pack_facturare.scrie_factura2(...)(:14130, :14158) — comenzi (tip 3/21/25/28/42/47) sau alte tipuri ("otherwise": lista de preturi etc.).- Toate aceste RPC-uri scriu in VANZARI si intorc un cursor de verificare (
lcCursorVerificare) cu liniile de nota contabila propuse: coloaneid_act, ascd, ascc (asociat cont debit/credit), id_partd, id_partc, dataactt, datairegt, datascadt, suma(:14184-14206). - Daca exista randuri in cursorul de verificare (adica nu e proforma), se afiseaza
Do Form verificare(:14189) — utilizatorul poate corecta clientul (id_partd/id_partc) sau explicatiile (ascd/ascc) inainte de a confirma nota. pack_facturare.finalizeaza_scriere_verificare(...)(:14247, si variantascrie_factura_avize_returla :14219/:14282 pentru retur-uri) — aici se scriu efectiv notele contabile si rulajele in Oracle, folosind eventualele corectii din formularul de verificare (pcSirDifAcont,pcSirDifPart).
- Alte efecte laterale:
- Incasare/bon fiscal:
poGeneratorNumere.verifica_numar(16, poDate.nr_incasare)(:503),listeaza_bon_fiscal(...)(:528) — chitanta/incasare asociata facturii, dacapoDate.incasat <> 0. - Listare:
listeaza_ofacturare()(:535). - Stoc: pentru facturare directa din stoc exista un flux paralel,
oscrie_vanzare_din_stoc(COMUN\programe\ofacturare_stoc.prg:318-412) — apeleazapack_facturare.initializeaza_date_factura,adauga_articol_factura_stoc,scrie_in_vanzari, si la finalupdate vanzari set id_fact = pack_contafin.get_idFact() where id_vanzare = ?(:412) — leaga VANZARI de identificatorul notei contabile (id_fact).
- Incasare/bon fiscal:
2. Fluxul de EDITARE factura existenta
Formular: frm_facturi (lista facturi emise), clasa COMUN\clase\ofacturare_comun.vc2.
frm_facturi.do_modifica—ofacturare_comun.vc2:4382-4482.- Verifica intai daca factura e deja in
anaf_efactura(vezi punct 5) si dacasters=0; altfel blocheaza editarea (:4476-4478, mesaj "Nu puteti face modificari pe inregistrarile sterse sau facturile trimise in eFactura!"). - Deschide
frm_modifica_factura(:4433) si la confirmare (gnButon=1) executapack_facturare.modifica_date_factura(...)(:4443-4460) cu parametrii:id_vanzare, id_ruta, id_delegat, id_agent, id_masina, dataora_exp, id_facturare, listare_detaliata, text_aditional, tip_saft, efactura, data_act, data_scad, numar_act, serie_act.
- Verifica intai daca factura e deja in
- Formular
frm_modifica_factura(ofacturare_comun.vc2:5096-5608) — campurile editabile efectiv expuse in UI sunt: ruta, delegat, agent, masina, data/ora expeditie, tip facturare (id_facturare), listare detaliata, text aditional, tip SAFT, si (conditionat denumar_actnenul) data act/scadenta/numar act/serie act — veziInit(:5570-5584) si handlerelechkDataAct/chkNrAct/chkSerieAct(:5592-5606). NU exista pe formular campuri pentru client, data facturii, seria/numarul facturii sau articole/preturi — acestea nu pot fi schimbate prin acest flux de editare. - Confirmat: editarea NU atinge notele contabile si rulajele.
modifica_date_facturaprimeste doar campurile enumerate mai sus (metadate document/logistica), nu recalculeaza sume, nu scrie in tabelele de note (vezi punct 3) si nu apeleaza vreun echivalentPACK_CONTAFIN. Nicio referinta lapack_contafinindo_modifica. - Editarea explicatiei unui articol de pe factura:
frm_modifica_articol_factura(ofacturare_comun.vc2:5023-5095, apelat dinfrm_facturi.do_modifica_explicatie:4484-4501) — apeleaza doarpack_facturare.modifica_explicatie_articol(id_vanzare_det, ...)(:5067) — schimba doar textul explicatiei, nu cantitatea/pretul/cont-ul. Nici aici nu se ating notele contabile.
3. Tabelele de note contabile si rulaje
Nu exista schema DBC/DDL in working copy (tabelele sunt Oracle, VFP le vede via view-uri gcs.v...). Din
codul de stergere (ofacturare_comun.vc2:4573-4614) rezulta 3 seturi de date, toate filtrate pe
an, luna, cod (cod = vanzari.cod, identificatorul facturii):
| View interogat (VFP) | Cursor local | Camp cheie randuri | Rol |
|---|---|---|---|
gcs.vact_tot |
actactan / cursor v_act |
id_act (+ id_set, id_fact, id_factd, id_factc) |
Note contabile (randuri debit/credit) |
gcs.vrul_tot |
rul_temp / cursor v_rul |
id_rul |
Rulaje |
gcs.vrul_obinv_tot |
rul_temp_obinv / cursor v_rul_obinv |
id_rul_obinv |
Rulaje obiecte de inventar |
Cheia de legatura factura -> nota: VANZARI.id_fact — populat la emitere prin
pack_contafin.get_idFact() (COMUN\programe\ofacturare_stoc.prg:412) sau intors ca parametru OUT din
scrie_factura2/finalizeaza_scriere_verificare (?@poDate.nid_vanzare e id_vanzare, nu id_fact — id_fact
pare populat separat de pachetul Oracle). Pe partea de nota, actul (ACT) are coloanele id_fact/id_factd/
id_factc folosite de pack_documente.ReferinteDocumenteNota/ReferinteDocument
(COMUN\programe\odocumente.prg:8-46) pentru a detecta referinte incrucisate intre documente (facturi ce se
storneaza/compenseaza reciproc).
Camp de provenienta pentru regenerare: nu exista un camp explicit gen sursa_id_vanzare pe ACT/RUL vizibil
in cod VFP; legatura se face prin cod (numarul facturii) + an + luna — vezi filtrul identic in
do_sterge (:4573,4587,4599). Asta e mecanismul deja folosit pentru "sterge tot ce apartine facturii X":
select pe vact_tot/vrul_tot/vrul_obinv_tot where cod = <cod factura> and an=... and luna=..., apoi
sterge. E si "reteta" pentru un eventual regenereaza = sterge + refa, cu observatia ca id-urile
(id_act, id_set, id_fact, id_factd) trebuie citite inainte de stergere daca se doreste refacere
identica (linia 4642-4647 le extrage din actactan inainte de a apela stergerea).
4. Operatie existenta de STORNARE / STERGERE factura (cheie pentru "regenereaza")
Da — frm_facturi.do_sterge (COMUN\clase\ofacturare_comun.vc2:4503-4719) e exact mecanismul
"sterge nota + rulaje asociate unei facturi":
- Blocheaza daca luna e inchisa (
glLunaInchisa, :4518-4520) sau daca factura e deja stearsa (:4531-4534) sau daca nu e din luna curenta (:4543-4546). - Cale proforma:
pack_facturare.sterge_proforma(?pnIdVanzare, ?gnIdUtil)(:4550) — nu are note, deci stergere simpla din VANZARI. - Cale factura/aviz reala:
- Verifica blocaj de referinte:
ReferinteDocumenteNota(pnAn, pnLuna, lnCod)(:4565,COMUN\programe\odocumente.prg:8, cheamapack_documente.ReferinteDocumenteNota) — daca documentul e referentiat de incasari/plati, blocheaza stergerea (:4567 mesaj "Documentul are referinte..."). - Interogheaza
vact_tot/vrul_tot/vrul_obinv_tot(vezi punct 3) ca sa afle daca exista note/rulaje de sters (llRul). - Daca exista randuri in
actactan, deschide formularulverificare(:4620-4624) pentru confirmare vizuala a ce se sterge, apoi porneste tranzactie explicita (SQLSetprop(...,"Transactions",2), :4625) si:- fie ruleaza
OSCRIE_IN_FISIERE(2,.F.,llRul)+pack_contafin.finalizeaza_stergere_nota(luna, an, NULL, id_set, cod, id_fact, id_factd, id_util)(:4642-4653) — varianta cu rulaje/fisiere multiple, - fie apeleaza direct
pack_facturare.sterge_factura(?pnIdVanzare, ?gnLuna, ?gnAn, ?gnIdUtil)(:4689) daca nu exista note/rulaje de tratat special.
- fie ruleaza
- Commit/rollback explicit, apoi revine pe tranzactie automata.
- Verifica blocaj de referinte:
Asta confirma ca infrastructura "sterge + reface" exista deja pe partea de stergere completa
(sterge_factura + finalizeaza_stergere_nota); un flux de "regenerare la editare" ar putea reutiliza aceste
doua RPC-uri Oracle inainte de a re-emite (echivalentul pasilor de la punctul 1, pasul 5) — dar acest
lant nu exista azi cablat din formularul de editare (do_modifica).
5. anaf_efactura.id_fact — verificare "a fost deja trimisa in eFactura"
- Citire/test:
COMUN\clase\ofacturare_comun.vc2:4428-4432, infrm_facturi.do_modifica:(lcSql = [select count(*) as lneFactura from anaf_efactura where id_fact = ] + ALLTRIM(STR(poRec.id_fact)) llSucces = goExecutor.oSelecteaza2Value(m.lcSql, @pneFactura) If poRec.sters = 0 AND NVL(m.pnEFactura,0) = 0 ... permite editarea ... Else amessagebox("Nu puteti face modificari pe inregistrarile sterse sau facturile trimise in eFactura!", 48, "Atentie")pnEFactura/pneFacturasunt aceeasi variabila — VFP e case-insensitive.) - Expresia de test: exista cel putin un rand in
ANAF_EFACTURAcuid_fact = VANZARI.id_facta facturii curente => considerata "trimisa" => editare blocata. - Scriere:
VANZARI.id_factinsusi e populat la emitere (pack_contafin.get_idFact(),COMUN\programe\ofacturare_stoc.prg:412, echivalent probabil si inscrie_factura2/finalizeaza_scriere_verificarepe partea Oracle, nevizibil in VFP).ANAF_EFACTURA.id_facte populat:- la import de factura de achizitie (nu de emitere):
UpdateEFacturaIdFact(COMUN\programe\import_efactura.prg:229) —update anaf_efactura set id_fact = ?pnIdFact where id = ?pnId and NVL(id_fact,0)=0. - manual din formular:
frm_import_efactura.importmodifica(anaf_efactura.vc2:12930) —UPDATE crsFacturi SET id_fact = m.pnIdFact WHERE id = m.lnIdEfactura. IPOTEZA: pentru facturile emise (nu achizitie), populareaanaf_efactura.id_factla trimitere se face probabil in clasa serverAnafeFacturaServer/ANAFeFactura(COMUN\programe\anaf_efactura.prg, ex.UpdateDbFactura:2018-2155) sau in Oracle la generarea XML — nu am gasit un UPDATE explicit VFP care leagaid_factla momentul trimiterii unei facturi emise; ar trebui verificat separat (posibil in PL/SQL).
- la import de factura de achizitie (nu de emitere):
6. Cele 4 tipuri de sursa — ramificare si diferente
Ramificarea e pe VANZARI.tip (camp numeric), vazuta in doua locuri, cu acelasi grupaj:
ofacturare.prg:266-308 (populare cursor articole la pornirea emiterii) si
ofacturare.vc2:14067-14174 (do_scrie_factura, alegerea RPC-ului de scriere):
| Sursa | tip (exemple) |
Cursor populare articole | RPC scriere |
|---|---|---|---|
| Lista de preturi | 1,5,7,10,22,23,29,45 (si 48/49 varianta cursor_articole_k) |
pack_facturare.cursor_preturi(...) |
scrie_factura2 (ramura "otherwise") |
| Contract | 2,6,26,52 | pack_facturare.cursor_contract(...) |
scrie_factura2 (ramura "otherwise") |
| Comanda | 3,21,25,28,42,47 | pack_facturare.cursor_comanda(...) |
scrie_factura2 (ramura explicita Inlist(poDate.Tip,3,21,25,28,42,47), cu intrebare "Doriti sa se inchida comanda?" :14122) |
| Aviz | 4 | pack_facturare.cursor_avize(...) |
scrie_factura_avize (ramura poDate.Tip = 4, cu intrebare "Doriti sa se inregistreze si avizul de retur?" :14091) |
| (alte, mentionate de completitudine) | 27 (lucrare), 30 (aviz din NIR), 41 (transfer gestiune), 8/9/24 (retur) | cursor_lucrare/cursor_aviz_nir/cursor_gestiune/cursor_retur |
variante scrie_factura_avize_retur/scrie_proforma |
Ce difera intre ele ca note contabile/rulaje: apelul final e mereu
pack_facturare.finalizeaza_scriere_verificare(...) (sau scrie_factura_avize_retur pentru retururi) —
adica acelasi punct final scrie notele, insa RPC-ul de scriere in VANZARI difera (scrie_factura_avize vs
scrie_factura2), iar la comanda/aviz apar intrebari suplimentare de inchidere document sursa (comanda
inchisa / aviz retur generat) care produc efecte laterale suplimentare pe langa nota standard. Diferentele
fine intre scrie_factura2 si scrie_factura_avize (ce conturi/rulaje difera intern) sunt in PL/SQL, deci
nu sunt vizibile in working copy.
7. Blocaje deja existente la editare
- Sters:
poRec.sters = 0obligatoriu (ofacturare_comun.vc2:4432). - Trimis in eFactura:
anaf_efacturaare rand cu acelasiid_fact(punct 5), acelasi test la:4428-4432. - Luna inchisa — nu e verificat in
do_modifica(doar indo_sterge, :4518-4520,If glLunaInchisa Return). Deci editarea (schimbare ruta/delegat/etc.) nu e blocata de luna inchisa, doar stergerea. IPOTEZA/ observatie pentru discutie: daca se adauga regenerare de note la editare, ar trebui adaugat si acest test. - Nu e din luna curenta — verificat doar la stergere (:4543-4546:
(pnAn*12)+pnLuna <> (gnAn*12)+gnLuna), nu la editare. - Referinte incasari/plati — verificat doar la stergere (
ReferinteDocumenteNota, :4565-4569), nu la editare. - Are chitanta/incasare — nu am gasit un blocaj explicit la editare; la stergere, verificarea de mai
sus (
ReferinteDocumenteNota) acopera implicit si incasarile asociate (comentariul dinodocumente.prg:5-6mentioneaza "id_fact ... pe id_factd sau id_factc").
8. Numerotare si documente legate — ce se poate schimba la editare
- Client: NU se poate schimba din
frm_modifica_factura(formularul nu are control pentru client/partener; vezi punct 2). Singurul loc unde apare o restrictie explicita despre client e in fluxul de verificare la emitere (nu la editare):ofacturare.vc2:14198-14201— daca diferenta de partener ar afecta un cont "41*",amessagebox("Nu puteti modifica clientul!",48,"Atentie") / Return .F.— asta e in timpul emiterii (formularulverificare), nu in editarea ulterioara. - Data facturii / seria / numarul facturii: NU sunt pe formularul de editare. Campurile editabile
data_act/numar_act/serie_act(:4444-4458) sunt pentru "act" (document justificativ atasat, cu checkbox-uri de activarechkDataAct/chkNrAct/chkSerieAct), NU seria/numarul facturii insesi — acelea se aloca ireversibil la emitere prinpoGeneratorNumere(punct 1, pasul 2). - Articole: nu se pot modifica cantitati/preturi din fluxul de editare a facturii — doar explicatia unui
articol (
frm_modifica_articol_factura, punct 2). - Aviz consumat / comanda / contract — flag "facturat": Exista camp
facturatpeCOMENZI(folosit in UI:ct_comenzi.actualizeaza_grid1colora randurile cufacturat=1,COMUN\clase\ocomenzi.vc2:1144; verificariloRec.facturat=1indo_modifica/do_stergeale comenzii, :1806, :2065 — blocheaza modificarea/stergerea comenzii deja facturate; filtru rapidfacturat=1/facturat=0in criterii, :2178). Marcareafacturat=1se face insa pe partea Oracle (pack_facturare.scrie_factura2etc.), nu am gasit unUPDATE comenzi SET facturatdirect in VFP — deci nu e vizibil in working copy exact unde se scrie flagul, doar ca e citit/verificat pe partea VFP. Nu am gasit camp echivalentfacturatpe AVIZE sau CONTRACTE in codul cercetat (posibil alt nume de camp sau tot pe partea Oracle) — IPOTEZA/necesita cautare suplimentara daca devine relevant.
Rezumat concluzii cheie
- Emiterea (
COMUN\programe\ofacturare.prg:90->factureaza2) scrie in VANZARI viapack_facturare.scrie_proforma/scrie_factura_avize/scrie_factura2, apoi (daca nu e proforma) afiseaza formularulverificarecu liniile de nota propuse si finalizeaza notele/rulajele prinpack_facturare.finalizeaza_scriere_verificare(COMUN\clase\ofacturare.vc2:14247, variante retur la :14219/:14282). Ramificarea pe cele 4 surse (lista preturi/contract/comanda/aviz) e peVANZARI.tip, vezi tabel la punctul 6. - Editarea existenta (
frm_facturi.do_modifica,COMUN\clase\ofacturare_comun.vc2:4382-4482, viapack_facturare.modifica_date_factura) atinge DOAR metadate logistice (ruta/delegat/agent/masina/ dataora_exp/tip_facturare/listare_detaliata/text_aditional/tip_saft/data-numar act) — confirmat: nu atinge notele contabile/rulajele si nu recalculeaza sume. Nu se pot schimba client, data/serie/numar factura sau articole. - Notele contabile si rulajele stau in view-urile Oracle
vact_tot/vrul_tot/vrul_obinv_tot(cheiid_act/id_rul/id_rul_obinv), legate de factura princod+an+luna(identic filtru folosit si la stergere) si prinVANZARI.id_fact(populat depack_contafin.get_idFact()). - Exista deja un flux complet de stergere-cu-note:
frm_facturi.do_sterge(ofacturare_comun.vc2:4503-4719) — folosestepack_facturare.sterge_factura+pack_contafin.finalizeaza_stergere_nota, cu verificare de referinte (ReferinteDocumenteNota) si confirmare vizuala (formularulverificare). Aceasta e infrastructura direct reutilizabila pentru un "regenereaza = sterge + refa" al notelor/rulajelor la editare. anaf_efactura.id_fact: testul de blocare editare eselect count(*) from anaf_efactura where id_fact = <vanzari.id_fact_curent>(ofacturare_comun.vc2:4428-4432) — daca exista rand, factura e considerata trimisa si editarea e refuzata. Punctul exact unde se scrieanaf_efactura.id_factla trimiterea unei facturi emise nu e vizibil in VFP (ipoteza: pe partea Oracle/XML) — cel gasit in VFP e doar pentru facturi de achizitie importate.- Blocaje actuale: editarea verifica doar
sters=0sinetrimisa in eFactura; NU verifica luna inchisa, NU verifica "luna curenta", NU verifica referinte incasari/plati — aceste 3 verificari exista doar pe fluxul de stergere, nu si pe cel de editare (do_stergevsdo_modifica,ofacturare_comun.vc2:4503vs:4382). - Cod PL/SQL Oracle (
PACK_FACTURARE,PACK_CONTAFIN,PACK_DOCUMENTE) nu e in working copy — doar semnaturile RPC apelate din VFP sunt vizibile local.