Files
roafacturare/docs/cercetare/canal_cont_venit_fara_politica.md
2026-09-09 22:19:22 +03:00

37 KiB

Exista un canal fara politica de pret catre ACT_TEMP.SCC? (proiect #13)

Cercetare read-only. Continua cont_venit_articol_fara_politica.md, nota_contabila_fara_politica.md, coresp_cont_venchelt.md, verif_baza_vie_cont_venit.md.

Mandat schimbat pe parcurs — vezi sectiunea imediat de mai jos. Sectiunile de la "Verdict, in cinci randuri" incolo sunt cercetarea rundei cu mandatul vechi ("gaseste un canal ocolitor, nu se atinge pack_facturare") si raman ca input de proiectare (harta intrarilor spre SCD/SCC, DDL, ce face V_CONT) — nu mai sunt raspunsul principal.

HANDOFF (predare de context, nu sarcina noua): o a treia sarcina a fost primita de la team-lead dupa livrarea proiectarii de mai jos — verificarea celor 37 de linii de comanda cu articol nemembru al politicii lor (proiectul #13, decizia 32). Nu a fost inceputa — sesiunea a evaluat contextul consumat pana la acel punct ca fiind aproape de pragul de predare (lectura extinsa de rapoarte mari + export Oracle in aceasta sesiune) si a predat inainte de a deschide o interogare noua, conform Regula zero. Livrabilul cerut pentru acea sarcina e alt fisier, docs\cercetare\linii_comanda_articol_nemembru.md — neinceput, nescris. Nimic din sesiunea curenta nu e intr-o stare periculoasa: doar SELECT-uri Oracle rulate (toate terminate), niciun fisier de cod atins, niciun proces/tranzactie ramas deschis. Urmatorul agent poate porni curat pe sarcina celor 37 de linii, cu contextul din mesajul team-lead-ului (re-confirma cifra, extrage cele 37 de linii cu id_comanda/id_articol/id_pol/data/stare facturare, verifica daca vreuna s-a facturat fara eroare, cauza daca se poate citi din audit, si validarea pe cod a conditiei FACT-024 aplicata pe forma lor).


Proiectarea parametrului de cont contabil (mandat nou, Marius 10.08.2026)

Marius a autorizat explicit modificarea punctuala a pack_facturare ("poți să adaugi parametrul contul contabil la contabilizeaza_articol") — decizia 27-bis e relaxata. Aceasta e o proiectare, nu o implementare — niciun fisier de cod nu a fost atins. Sursa Oracle: D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql (17217 linii, verificat wc -l); toate liniile citate mai jos sunt din acest fisier, citite direct in aceasta runda (nu preluate din rapoarte anterioare).

Verdict proiectare, in sase randuri

Fezabil, cu o precizare importanta fata de formularea lui Marius: contabilizeaza_articol primeste azi un singur parametru, detalii_articol VANZARI_DETALII_TEMP%ROWTYPE — un rand intreg, nu o lista de scalari. Deci "parametrul de cont" nu intra ca parametru nou pe contabilizeaza_articol insasi (asta ar fi cosmetic, fara efect, pentru ca cei 3 apelanti interni ii dau deja randul intreg dintr-un TABLE OF VANZARI_DETALII_TEMP%ROWTYPE) — intra pe drumul real: o coloana noua pe VANZARI_DETALII_TEMP, populata printr-un parametru nou pe adauga_articol_factura (procedura chemata direct din VFP), pe care contabilizeaza_articol o citeste automat prin detalii_articol.<coloana>, fara nicio modificare la scrie_factura2, scrie_factura_avize_retur sau scrie_aviz_retur. Efectul practic e exact ce a cerut Marius — un cont de venit calculat de VFP ajunge in ACT_TEMP.SCC fara politica — doar mecanica de livrare e alta decat "parametru pe contabilizeaza_articol" literal. Restul (SCD, CU_TVA, IN_VALUTA, EXPLICATIE, ID_VENCHELT, ID_SECTIE, descarca_gestiune o singura data, FACT-024 ocolit doar pe ramura noua) au surse identificate mai jos, cu 2 hardcodari explicite care cer confirmarea lui Marius (SCD='4111', CU_TVA=1).

1. Lantul real de apel — de ce parametrul trebuie sa intre pe adauga_articol_factura, nu pe contabilizeaza_articol

ff_...:7173  FUNCTION contabilizeaza_articol(detalii_articol VANZARI_DETALII_TEMP%ROWTYPE) RETURN NUMBER IS

Singurul parametru. Apelata de exact 3 locuri, toate interne pachetului, toate ii dau un element dintr-un array populat integral din tabel:

ff_...:6039-6040  TYPE tab_detalii_type IS TABLE OF vanzari_detalii_temp%ROWTYPE;
                  tab_detalii tab_detalii_type;
ff_...:6063       SELECT * BULK COLLECT INTO tab_detalii FROM VANZARI_DETALII_TEMP;
ff_...:6141       V_INCASAT_CALCUL := V_INCASAT_CALCUL + pack_facturare.contabilizeaza_articol(tab_detalii(i));   -- scrie_factura2
ff_...:6858       pack_facturare.contabilizeaza_articol(tab_detalii(i));   -- scrie_factura_avize_retur
ff_...:7140       pack_facturare.contabilizeaza_articol(tab_detalii(i));   -- scrie_aviz_retur

SELECT * BULK COLLECT (nu o lista explicita de coloane) inseamna: orice coloana noua adaugata pe VANZARI_DETALII_TEMP ajunge automat in tab_detalii(i) si deci in detalii_articol in contabilizeaza_articol, fara sa atingi aceste 3 proceduri. Asta e drumul cu cea mai mica suprafata de risc posibila — nu exista un drum mai mic care sa duca un cont calculat de VFP pana in contabilizeaza_articol.

Intrarea reala din VFP e adauga_articol_factura (nu contabilizeaza_articol):

ff_...:4989-5015  PROCEDURE adauga_articol_factura(V_ID_TEMP             IN NUMBER,
                                                    V_ID_ARTICOL          IN NUMBER,
                                                    ... (23 parametri) ...
                                                    V_ID_UTIL             IN NUMBER,
                                                    V_TAXCODE             IN NUMBER DEFAULT NULL,
                                                    V_LOT                 IN VARCHAR2 DEFAULT NULL) IS

Precedent direct pentru "adauga parametru nou la coada, cu DEFAULT NULL": V_TAXCODE si V_LOT sunt deja exact asta — doi parametri adaugati ulterior, la finalul listei, cu DEFAULT NULL, fara sa oblige la rescrierea apelantilor existenti. Propunerea de mai jos repeta acelasi tipar, nu inventeaza unul nou.

Apelantul VFP confirmat (singurul gasit in sursa, dublat identic in doua locuri din aceeasi clasa — vezi "Ce nu s-a putut stabili"):

COMUN\clase\ofacturare.vc2:14069-14091  (si identic la :18089-18114)
lcSql = lcSql + [pack_facturare.adauga_articol_factura(] + Alltrim(Str(poArt.id_temp)) + [,] + ;
    ... (pozitional, 26 de argumente) ... + ;
    NVL(ALLTRIM(STR(poArt.taxcode)),[NULL]) + ;
    [,'] + OracleSpecialCharacters(Alltrim(Nvl(poArt.lot,[]))) + ['] + ;
    [);]

Apel pozitional, se opreste la V_LOT (ultimul parametru existent azi). Oracle permite ca un apel pozitional sa se opreasca inainte de parametri opționali de la coada — deci un parametru nou dupa V_LOT nu afecteaza acest apel existent (ramane identic, echivalent cu "trimite NULL" pe noul parametru).

2. Schema propusa

Coloana noua: VANZARI_DETALII_TEMP.CONT_VENIT VARCHAR2(4) NULL (fara NOT NULL, fara CHECK — acelasi tipar ca ACT_TEMP.SCC, vezi DDL mai jos). Recomandat, dar nu strict necesar pentru mecanismul de nota (doar pentru trasabilitate/raportare ulterioara): aceeasi coloana pe VANZARI_DETALII, plus adaugarea ei in INSERT /*+ APPEND */ INTO VANZARI_DETALII (...) SELECT ... FROM VANZARI_DETALII_TEMP din scrie_in_vanzari (citat in nota_contabila_fara_politica.md sectiunea 4 ca avand lista explicita de coloane — linia exacta nu a fost re-verificata in aceasta runda, vezi "Ce nu s-a putut stabili"). Fara acest pas secundar, nota contabila tot se scrie corect — doar VANZARI_DETALII nu ar pastra, dupa fapt, cu ce cont s-a facturat linia.

Parametru nou pe adauga_articol_factura, la coada, dupa V_LOT:

V_CONT_VENIT IN VARCHAR2 DEFAULT NULL

Plumbing identic cu V_CONT/V_CONT2 (ff_...:5004,5035-5037,5238,5268 — acelasi tipar de "copiaza daca nu e sentinela/gol, altfel NULL"), adaugat langa INSERT INTO VANZARI_DETALII_TEMP (ff_...:5222-5282): o coloana in plus in lista, o valoare in plus in VALUES.

Niciun rand de cod nou in scrie_factura2 / scrie_factura_avize_retur / scrie_aviz_retur — confirmat la sectiunea 1, SELECT * + %ROWTYPE absoarbe coloana automat.

3. Ramura noua in contabilizeaza_articol

Corpul complet citit ff_...:7173-7547. Structura propusa: un IF detalii_articol.cont_venit IS NOT NULL THEN <ramura noua> ELSE <tot codul de azi, neschimbat> END IF; care infasoara inclusiv blocul FACT-024, plasat imediat dupa declaratiile locale (inainte de ff_...:7278). Cand parametrul e NULL (toti apelantii de azi, nemodificati), executia cade in ELSE si comportamentul e identic bit-cu-bit cu azi.

Continutul ramurii noi (doar pentru "articol simplu" — articolele compuse, V_COMPUS=1, raman in afara scopului, ca azi):

Camp Sursa in ramura noua Argumentatie
SCC detalii_articol.cont_venit Chiar parametrul primit — asta e intreg scopul modificarii.
SCD hardcodat '4111' pentru cazul "factura" (ramurile aviz raman '418'/'461', deja hardcodate azi la ff_...:7415,7420, independent de politica) Hardcodare explicita, de confirmat cu Marius. Azi, pentru factura normala, V_SCD := crs_rand_articol.scd (ff_...:7409) — vine din NOTE_CONTABILE.SCD. Pe baza vie (verif_baza_vie_cont_venit.md tabel sectiunea 4), toate cele 7 note de vanzari active au SCD='4111' (contul de clienti, standard pentru vanzare pe credit) — zero exceptii masurate. Decizia 31 (nu generaliza de pe datele din Dev) se aplica la numere, nu la structura contabila — 4111 = clienti e conventie standard de plan de conturi, nu un artefact al datelor de test, dar tot ramane o presupunere care trebuie confirmata explicit, nu deja "descoperita".
ASCD PACK_FACTURARE.GetAnaliticByGrupUtilizatori(pack_facturare.nid_util, V_SCD) Exact fallback-ul deja folosit necondiționat pentru ramurile de aviz azi (ff_...:7416-7417,7421-7422) — functioneaza fara cursor, deja verificat ca nu depinde de politica (coresp_cont_venchelt.md sectiunea 7).
ASCC PACK_FACTURARE.GetAnaliticByGrupUtilizatori(pack_facturare.nid_util, V_SCC) Acelasi tipar ca V_ASCC de azi (ff_...:7426-7428), care oricum e NVL(crs_rand_articol.ascc, GetAnaliticByGrupUtilizatori(...)) — fallback-ul e calea normala, nu exceptia.
EXPLICATIE detalii_articol.explicatia (coloana EXPLICATIA din VANZARI_DETALII_TEMP, populata de V_EXPLICATIE — parametru deja existent pe adauga_articol_factura, ff_...:4992,5227,5257) Mai buna decat sursa de azi, nu doar un fallback — azi crs_rand_articol.explicatie vine dintr-un sablon static configurat pe nota; textul introdus de utilizator la adaugarea articolului e deja disponibil pe rand, fara politica.
ID_VENCHELT pack_facturare.nid_venchelt Acelasi fallback de sesiune pe care cursorul de azi il foloseste oricum ca prioritate (NVL(pack_facturare.nid_venchelt, NVL(A.ID_VENCHELT, C.ID_VENCHELT)), ff_...:7244-7245) — poate ramane NULL daca variabila de sesiune nu e setata, exact ca azi in acelasi caz.
ID_SECTIE pack_facturare.nid_sectie_stoc Acelasi tipar (ff_...:7246).
IN_VALUTA pack_facturare.nin_valuta Nu e o presupunere noua — e valoarea pe care cursorul de azi o substituie deja peste D.IN_VALUTA intr-un caz analog (ff_...:7254-7260, cand A.ID_POL = pack_facturare.nid_politica_stoc AND pack_facturare.nin_valuta = 1). Fiindca fara politica nu exista D.IN_VALUTA de citit, se foloseste direct flagul de document — acelasi flag pe care codul existent il trateaza deja ca sursa de incredere.
CU_TVA hardcodat 1 Hardcodare explicita, de confirmat cu Marius. CU_TVA (parametrul V_CU_TVA al scrie_nota, ff_...:12347) controleaza daca se scrie separat o linie de TVA (ff_...:12537-12558, pack_facturare.scrie_tva(...)) — nu trebuie confundat cu V_PRET_ARE_TVA (mapat pe detalii_articol.pret_cu_tva, deja disponibil independent de politica, controleaza doar interpretarea pretului). Pe baza vie, toate cele 7 note de vanzari active au CU_TVA=1 (verif_baza_vie_cont_venit.md sectiunea 4) — nicio nota de vanzare reala cu CU_TVA=0. Semantic, 1 = comportamentul standard pentru o vanzare taxabila (TVA scrisa separat, necesar pentru raportarea de TVA); 0 n-are niciun exemplu real observat. Daca cota TVA a articolului e 0% (scutit), scrie_tva scrie oricum o linie cu suma 0 — inofensiv, nu gresit, dar de confirmat ca e acceptabil.

Apeluri, o singura data fiecare (nu in bucla — nu exista cursor in aceasta ramura):

  1. pack_facturare.scrie_nota(...) — aceiasi parametri ca la ff_...:7443-7467, cu valorile de mai sus in locul celor din crs_rand_articol; restul (cantitate, pret, discount_unitar, pret_cu_tva, id_valuta, curs/multiplicator, id_ctr, proc_tvav, id_jtva_coloana, taxcode) vin din detalii_articol, exact ca azi — independente de politica.
  2. pack_facturare.descarca_gestiune(...) — aceeasi garda ca azi (pack_facturare.nscadere_stoc=1 AND detalii_articol.id_gestiune<>-1000 AND detalii_articol.in_stoc=1, ff_...:7473-7475), cu crs_rand_articol.id_sectie/.id_venchelt inlocuite de pack_facturare.nid_sectie_stoc/.nid_venchelt direct (fara cursor). Ruleaza exact o data, prin constructie — nu exista WHILE cursor%FOUND LOOP in aceasta ramura, deci defectul de "set multi-rand" (punctul urmator) nu poate aparea aici, fara sa fi fost nevoie sa se repare nimic pe ramura veche.
  3. Discount (ff_...:7501-7518), aceeasi garda (discount_unitar<>0 AND ndiscount_evidentiat=1), cu V_ASCD si V_CU_TVA calculate mai sus in loc de cele din cursor.
  4. RETURN V_INCASAT_CALCUL; — identic.

4. FACT-024 — ocolit doar pe ramura noua, garda neschimbata pe ramura veche

Blocul (ff_...:7278-7302) ramane litera cu litera identic in ELSE. Nu se slabeste nimic — o linie fara politica si fara cont_venit continua sa primeasca FACT-024 exact ca azi. Bypass-ul e strict conditionat de faptul ca VFP a trimis explicit un cont (cont_venit IS NOT NULL), nu de absenta politicii in sine.

5. Bug-ul de set multi-rand — nemostenit, netratat

Documentat deja (nota_contabila_fara_politica.md, verif_baza_vie_cont_venit.md sectiunea 6.1): cursor_articol face LEFT JOIN NOTE_CONTABILE D ON C.ID_SET = D.ID_SET fara ROWNUM/agregare, iar bucla scrie venitul si descarca gestiunea o data per rand din set. Ramura noua nu are cursor deloc — rezolva structural aceeasi clasa de bug, dar nu e propusa ca reparatie a ramurii vechi; ramane un defect separat, de tratat separat, cum a cerut explicit team-lead-ul.

6. Suprafata de regresie

  • contabilizeaza_articol: 3 apelanti, toti interni pack_facturare (scrie_factura2, scrie_factura_avize_retur, scrie_aviz_retur) — zero schimbari la niciunul (sectiunea 1).
  • adauga_articol_factura: un singur apelant confirmat in sursa citita, COMUN\clase\ofacturare.vc2:14069-14091, duplicat identic la :18089-18114 in aceeasi clasa (posibil doua metode gemene, nu doua clase — neconfirmat, vezi mai jos). Apel pozitional, se opreste la V_LOT — neafectat de un parametru nou dupa V_LOT cu DEFAULT NULL, pe acelasi tipar deja folosit de V_TAXCODE/V_LOT insele.
  • Restul suitei (ROAGEST, ROAAUTO, ROAACNPRO, ROAIMOB): pe baza cercetarilor anterioare (nota_contabila_fara_politica.md sectiunea 4, coresp_cont_venchelt.md sectiunea 9b), aceste produse folosesc adauga_articol_factura_deviz/_stoc (proceduri separate, semnaturi diferite, neatinse de aceasta propunere) sau pack_acn.salveaza_regdoc (alt pachet complet). O cautare directa, in aceasta runda, pentru apeluri catre adauga_articol_factura( (fara _deviz/_stoc) in COMUN-urile celorlalte produse nu s-a terminat in timp util (comanda de fond nu a raspuns) — vezi "Ce nu s-a putut stabili". Pe baza dovezilor deja existente (nimeni altcineva nu are un flux documentat prin adauga_articol_factura simplu), riscul asteptat e zero, dar nu e demonstrat exhaustiv pentru toata suita in aceasta runda.
  • Teste minime recomandate: (a) factura normala cu politica, parametru NULL — verifica ACT identic cu azi (regresie); (b) articol fara politica, cont_venit populat — un singur rand ACT, SCC=valoarea data, SCD='4111', linie TVA scrisa separat; (c) articol negestionabil (id_gestiune=-1000) cu cont_venit populat — descarca_gestiune NU ruleaza; (d) discount pe linie cu cont_venit populat; (e) document in valuta (nin_valuta=1) cu cont_venit populat — IN_VALUTA=1 pe nota, SUMA_VAL completat; (f) linie fara politica si fara cont_venit — FACT-024 tot apare (regresie negativa, garda nu s-a slabit).

7. Alternativa mai mica — nu exista una reala

Propunerea de mai sus e deja varianta minimala: un singur parametru VARCHAR2(4) DEFAULT NULL, zero schimbare de comportament cand e NULL, zero atingere a celor 3 apelanti interni. O varianta "doar un flag care opreste FACT-024, fara sa transporte contul" tot ar avea nevoie ca SCC sa vina de undeva — nu reduce suprafata, doar muta numele. Nu recomand separarea in doi parametri (flag + cont) — complexitate in plus fara beneficiu; un singur camp nenul e semnalul suficient.

Ce nu s-a putut stabili in aceasta runda, si de ce

  • Daca ofacturare.vc2:14069-14091 si :18089-18114 sunt doua metode/clase distincte sau o duplicare literala a aceleiasi metode — nu am identificat clasele-container ale celor doua blocuri (ar necesita indexul de simboluri vfp_symbols.ps1, nefolosit in aceasta runda din lipsa de timp). Nu schimba verdictul (ambele se opresc la V_LOT), dar conteaza pentru a sti cate locuri VFP trebuie atinse ca sa se foloseasca efectiv noul parametru dupa ce va exista in Oracle.
  • Daca alte produse (ROAGEST/ROAAUTO/ROAACNPRO/ROAIMOB) apeleaza adauga_articol_factura simplu undeva neexaminat — comanda de cautare pe COMUN-urile celorlalte produse a ramas fara raspuns in timp util in aceasta sesiune; de re-rulat separat inainte de implementare.
  • Linia exacta a INSERT ... INTO VANZARI_DETALII ... SELECT ... FROM VANZARI_DETALII_TEMP din scrie_in_vanzari — citata doar din raportul anterior (nota_contabila_fara_politica.md), nu re-verificata pe fisierul curent in aceasta runda; necesara doar daca se decide sa se persiste si CONT_VENIT pe VANZARI_DETALII (pasul optional de la sectiunea 2).
  • Comportamentul scrie_tva cu cota 0% (linie scutita) cand CU_TVA e hardcodat la 1 — nu am citit corpul scrie_tva in aceasta runda pentru a confirma ca o suma 0 nu produce vreun efect secundar (ex. impact pe nproc_tva_max/nid_jtva_coloana la ff_...:12538-12541, care se actualizeaza necondiționat de valoarea sumei).
  • Confirmarea explicita a lui Marius pe cele doua hardcodari (SCD='4111', CU_TVA=1) — sunt presupuneri argumentate din date reale si din tiparul de cod existent, nu descoperiri; raman decizii de proiectare deschise.

Verdict runda anterioara (canal ocolitor, mandat vechi — pastrat ca input de proiectare)

DA, exista un canal real, deja cablat si deja folosit in productie pentru categoria de document "facturi emise" — complet independent de pack_facturare si de politica de pret. E cursorul VFP generic actactan/tact -> oscrie_in_fisiere.prg (INSERT generic in ACT_TEMP din campurile oricarui cursor VFP) -> pack_contafin.SCRIE_IN_ACT/STERGE_DIN_ACT (nu pack_facturare!). Cel mai relevant: fluxul de editare a facturii emise, ofacturare_comun.vc2:3796-3821 (proiectul #6 insusi), foloseste exact acest canal ca sa lase utilizatorul sa editeze SCD/ASCD/SCC/ASCC direct pe randul notei prin frm_modific2024 (omodificari.vc2, fisier nerestrictionat), apoi rescrie ACT_TEMP cu valorile din cursorul VFP editat. Limitarea majora: canalul e cablat pe editarea unei note deja scrise (sterge + rescrie), nu pe emiterea unei facturi noi — emiterea trece azi exclusiv prin pack_facturare.scrie_factura2 -> contabilizeaza_articol, care nu are nicio ramura alternativa (confirmat in rundele anterioare, FACT-024). Pistele 1, 2, 4, 5 din cerere sunt toate NU — niciuna nu ofera un canal catre SCC. DDL-ul ACT_TEMP nu blocheaza nimic din asta: SCD/SCC sunt VARCHAR2(4) NULL, fara CHECK.

Sursa principala pentru citatele Oracle: D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql (17217 linii — confirmat wc -l). Fisierul din docs\ nu mai exista, cum a semnalat cererea.


Pistele cerute, in ordine

1. V_CONT IN VARCHAR2 (parametru adauga_articol_factura) — NU e canal pentru SCC

Confirmat pe cod, nu doar preluat din raportul anterior (a carui concluzie pe acest punct era deja corecta): V_CONT e contul de gestiune/stoc (clasa 3xx), nu de venit. E scris ca atare in VANZARI_DETALII_TEMP.CONT (adauga_articol_factura, semnatura la ff_...:4989-5015 V_CONT IN VARCHAR2, folosire la :5044-5046 V_CONT2 := V_CONT, INSERT la :5277). Niciodata folosit ca SCD/SCC — contabilizeaza_articol isi ia V_SCC exclusiv din cursor_articol (D.SCC, lantul CRM_POLITICI_PRET_ART -> CRM_POLITICI_PRETURI -> CRM_NOTE_VANZARI -> NOTE_CONTABILE, ff_...:7248-7253,7259-7260), fara nicio ramura care sa citeasca V_CONT. V_CONT alimenteaza doar descarca_gestiune (contul de iesire din gestiune, SCC pe nota de stoc, nu de venit), nu nota de venit.

2. Variabile de sesiune pack_facturare — NU exista setter pentru cont

Am listat toate variabilele publice de pachet cu prefix nid_ din specificatia pack_facturare (ff_...:72-211, citat exhaustiv, cautare grep -n "^ nid_"):

nid_tipnir, nid_tipbon, nid_tipfactura, nid_tipaviz, nid_act, nid_serie, nid_fdoc, nid_part,
nid_part_rez, nid_lucrare, nid_sectie_stoc, nid_gestiune_sursa, nid_responsabil, nid_ordl, nid_set,
nid_util, nid_moneda_nationala, nid_fact, nid_factc, nid_partc, nid_jtva_coloana, nid_comanda,
nid_valuta, nid_politica_stoc, nid_sucursala, nid_venchelt, nid_vanzare, nid_beneficiar

Niciuna tipata pe un cont (VARCHAR2(4)/cod de cont) — toate sunt FK-uri numerice (%TYPE pe alte tabele: ID_SECTIE, ID_VENCHELT, ID_POL, etc.). Cautare directa nid_scc/nid_scd/nid_cont in tot fisierul: zero rezultate. nid_venchelt (folosit ca fallback la ID_VENCHELT in cursor_articol, ff_...:7244-7245, deja documentat in coresp_cont_venchelt.md sectiunea 7) e o clasificare dimensionala (NOM_VENIT_CHELTUIELI.ID_VENCHELT%TYPE), nu un cont — nu am gasit consumator care sa-l foloseasca drept SCC. Cautare separata PROCEDURE SET_ in tot pachetul: zero rezultate — nu exista niciun setter public de tip SET_... pentru cont. Concluzie: NU.

3. ACT_TEMP scris direct din VFP — DA, canal real, dar pe fluxul de editare, nu de emitere

Confirmat de COMUN\docs\oracle_export.md:64-65: "Pachetul central de scriere a documentelor — clientul VFP populeaza tabelele temporare ACT_TEMP/RUL_TEMP (prin oscrie_in_fisiere-ul din COMUN), apoi pachetul distribuie". Mecanismul e generic si complet independent de pack_facturare:

Mecanismul (COMUN\programe\oscrie_in_fisiere.prg):

  • sql_temp_insert('actactan','ACT_TEMP') (oscrie_in_fisiere.prg:127) face, pentru fiecare rand al oricarui cursor VFP numit actactan, un INSERT INTO ACT_TEMP (<coloanele care exista si in cursor si in tabel>) VALUES (...) construit dinamic din user_tab_columns (oscrie_in_fisiere.prg:190-280) — orice camp SCD/ASCD/SCC/ASCC prezent in cursorul VFP ajunge direct in ACT_TEMP, indiferent de valoare, fara nicio validare de cont.
  • Scrierea efectiva in ACT se face prin pack_contafin.init_scriere_act_rul_local + final_scriere_act_rul_local -> SCRIE_IN_ACT/STERGE_DIN_ACT (oscrie_in_fisiere.prg:121-147) — pack_contafin, nu pack_facturare. Confirmat si in COMUN\docs\flux-modificare-stergere-nota-jurnal.md:20-28.

Cine populeaza actactan cu valori calculate/editate de VFP — cele doua cazuri gasite, ambele active in productie:

(a) Registrul Jurnal — editare/stergere manuala de nota, orice document, generic (COMUN\clase\comun.vc2, clasa afisjurcom):

  • do_modifica (comun.vc2:2222-2562): incarca nota existenta (Select * From v_act Into Cursor actactan, comun.vc2:2363), instantiaza frm_modific2024 (comun.vc2:2439, omodificari.vc2:6375) — formular in care utilizatorul poate edita direct scd/ascd/scc/ascc pe fiecare rand al notei (grid legat pe tact, verificare prin verific_analitic/do_verifica, tipar prezent si in omodificari.vc2:1714-1788 — comentat azi, dar acelasi tipar activ e in frm_modific2024, vezi mai jos (b)). Dupa editare: oscrie_in_fisiere(2,...) = sterge nota veche (comun.vc2:2454), apoi oscrie_in_fisiere(0,...) = scrie nota noua cu valorile din cursorul editat (comun.vc2:2482), apoi pack_contafin.finalizeaza_modificare_nota(...) (comun.vc2:2484-2486). Niciun apel catre pack_facturare in acest flux.
  • Documentat integral, cu aceleasi citate, in COMUN\docs\flux-modificare-stergere-nota-jurnal.md.
  • E generic pe orice document din ACT (nu doar facturi) — daca o factura emisa are deja o nota, poate fi editata de aici.

(b) Editarea facturii emise — acelasi mecanism, scop specific "facturi emise" (proiectul #6 insusi), COMUN\clase\ofacturare_comun.vc2:3769-3838 (functia do_editare_factura, citita integral, nu modificata):

ofacturare_comun.vc2:3769   If IncarcaCursoareModificareNota(lnCod, pnAn, pnLuna, .F.)      && ofacturare_editare.prg
...
ofacturare_comun.vc2:3787   Select a.*, Iif(Nvl(id_jtva_coloana,0)=0,0,1) As cu_Tva From tact a Into Cursor tact Readwrite
...
ofacturare_comun.vc2:3796   Omodif = Createobject([frm_modific2024], lnIdSet)
ofacturare_comun.vc2:3797   Omodif.Show()
ofacturare_comun.vc2:3799   If buton = 1
ofacturare_comun.vc2:3800     If Thisform.do_deschide_tranzactie()
ofacturare_comun.vc2:3801       Select actactan
ofacturare_comun.vc2:3802       lnSucces = OSCRIE_IN_FISIERE(2,.T.,.T.)          && sterge nota veche
ofacturare_comun.vc2:3803       If lnSucces > 0
...
ofacturare_comun.vc2:3807         Select tact
ofacturare_comun.vc2:3808         Replace id_jtva_coloana With Null, proc_tva With 0 For cu_Tva = 0
ofacturare_comun.vc2:3809         Select * From tact Into Cursor actactan Readwrite   && re-materializeaza tact (inclusiv orice SCD/SCC editat) in actactan
ofacturare_comun.vc2:3810         Replace All id_util With gnIdUtil, sters With 0
...
ofacturare_comun.vc2:3821         lnSucces = OSCRIE_IN_FISIERE(0,.T.,.T.)          && scrie nota noua, direct din actactan, in ACT_TEMP
ofacturare_comun.vc2:3823       If lnSucces > 0
ofacturare_comun.vc2:3824         lcSql = [begin pack_contafin.finalizeaza_modificare_nota(...); end;]
ofacturare_comun.vc2:3828       If lnSucces > 0 And "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) And Used('tvanz')...
ofacturare_comun.vc2:3829         lnSucces = Iif(ScrieArticoleFacturaEditate(tvanz.id_vanzare), 1, -1)   && scrie si VANZARI_DETALII

IncarcaCursoareModificareNota (COMUN\programe\ofacturare_editare.prg:32-71) incarca nota existenta a facturii (vact_tot -> v_act -> actactan -> tact, toate READWRITE) inainte de a arata frm_modific2024. Linia :3809 rescrie actactan direct din tact — orice valoare aflata pe tact.scd/tact.scc in acel moment (editata manual prin frm_modific2024, sau setata programatic de orice cod VFP inainte de linia 3809) devine noua nota, scrisa in ACT_TEMP prin OSCRIE_IN_FISIERE(0,...) la linia 3821 — fara niciun apel pack_facturare, fara politica de pret. pack_contafin.finalizeaza_modificare_nota (linia 3824) doar re-leaga cod-ul nou de VANZARI; ScrieArticoleFacturaEditate (linia 3829) scrie separat VANZARI_DETALII.

Aceasta e dovada cea mai puternica posibila pentru intrebarea pusa: canalul nu e teoretic — e exact mecanismul pe care proiectul #6 il foloseste azi ca sa permita editarea contului unei facturi deja emise, complet in afara pack_facturare.

Limitarea reala: mecanismul opereaza pe o nota deja existenta (sterge randul vechi din ACT, scrie unul nou cu acelasi id_fact) — presupune ca factura a fost deja scrisa o data (prin pack_facturare, cu politica). Nu e (azi) un canal pentru emiterea initiala a unei facturi noi cu un articol fara politica — scrie_factura2 -> contabilizeaza_articol (calea de emitere) nu are nicio ramura care sa ocoleasca politica si nu apeleaza acest mecanism.

Alte doua confirmari ale aceluiasi tipar, tot pentru categoria "facturi":

  • COMUN\ferestre\frm_initializare_facturi_balanta.sc2:458 — CREATE CURSOR actactan (id_set I, an N(4), luna N(2), Dataact D, datascad D, dataireg D, serie_act C(20), nract N(20), proc_tva N(5,2), id_jtva_coloana I NULL, scd C(4), ascd C(4), scc C(4), ascc C(4), ...) — cursor creat de la zero in VFP, cu scd/scc campuri simple, editabile liber, fara nicio derivare Oracle. Foloseste tot frm_modific2024 (:1806) pentru editare/validare inainte de scriere.
  • COMUN\ferestre\frm_import_note_facturi_clienti.sc2:667,815,898,911 — acelasi tipar (actactan/tact editabil + frm_modific2024), pentru import manual de note pe facturi de clienti.

Ambele sunt scenarii de initializare/import (sold de deschidere, import de note), nu de facturare curenta — dar confirma ca ACT_TEMP pentru categoria "facturi" se scrie deja, in mod curent, direct din cursoare VFP construite de la zero, fara pack_facturare.

4. ID_VENCHELT / CRM_NOTE_VANZARI — NU e canal alternativ catre SCC

Deja stabilit exhaustiv in coresp_cont_venchelt.md sectiunea 7: ID_VENCHELT e o dimensiune (NOM_VENIT_CHELTUIELI.ID_VENCHELT), citita cu fallback pe nid_venchelt (ff_...:7244-7245), dar nu participa la calculul SCC — V_SCC vine exclusiv din cursor_articol.D.SCC. Nu exista camp de tip cont pe VANZARI/VANZARI_DETALII — reconfirmat aici prin cautare grep -inE "SCC|CONT_VENIT" in blocurile CREATE/ALTER TABLE VANZARI din ff_... (fara rezultate suplimentare fata de ce era deja stabilit).

5. GetAnaliticByGrupUtilizatori — doar analitic, nu cont sintetic

Confirmat deja in coresp_cont_venchelt.md sectiunea 7: functia da fallback pentru ASCD/ASCC (analiticul), nu pentru SCD/SCC (contul sintetic). Nu exista o functie analoaga pentru cont — cautare GetSinteticBy/GetContBy in tot ff_...: zero rezultate.


Lista exhaustiva a intrarilor catre SCD/SCC in ACT_TEMP, pe/langa fluxul de facturare

Sursa: ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql + fisierele VFP citate.

  1. pack_facturare.contabilizeaza_articol -> scrie_nota (ff_...:7218-7556 / 12338-12570, INSERT INTO ACT_TEMP la :12458-12544) — calea principala de emitere. SCD/SCC vin din cursor_articol (D.SCD, D.SCC, lantul politicii). Blocheaza cu FACT-024 (:7275-7311) daca articolul nu e in politica — fara fallback (deja stabilit in nota_contabila_fara_politica.md).
  2. Ramurile speciale din scrie_factura2 (transfer subunitati ntip IN (23,25,30,41), custodie ntip IN (42,47), rata id_rata<>0) — tot contabilizeaza_articol, acelasi punct 1.
  3. scrie_factura_avize_retur (ff_...:6273-6666, apel la :6867) si scrie_aviz_retur (ff_...:7094-7180, apel la :7149) — tot contabilizeaza_articol.
  4. descarca_gestiune (ff_...:7476-7498, apelata din interiorul buclei cursor_articol) — scrie o a doua nota, de iesire din gestiune (SCD/SCC = conturi de stoc, din V_CONT/ poArticol.Cont, nu din politica) — parte a fluxului de facturare, dar nu e nota de venit.
  5. Discount pe linie (ff_...:7501-7518) — scrie o nota separata (vazuta pe date live ca id_nota=2, SCD=667/SCC=4111, verif_baza_vie_cont_venit.md sectiunea 4) — tot in interiorul cursor_articol, deci tot dependenta de politica pentru a ajunge acolo.
  6. oscrie_vanzare_din_stoc (COMUN\programe\ofacturare_stoc.prg:104-450) — flux ROAGEST "vanzare din stoc". Apeleaza pack_facturare.adauga_articol_factura_stoc per articol (:357-378) apoi oscrie_in_fisiere(0,.F.,.T.) (:392). Neverificat complet: codul citit nu arata explicit unde/cum se populeaza actactan cu SCD/SCC inainte de linia 392 in acest flux particular (cursorul ACTACTAN e doar citit la :253-289 pentru alte campuri, nu am gasit punctul de scriere in fisierul citit) — posibil populat de o procedura anterioara neexaminata. Marcat ca zona neinchisa, vezi "Ce nu s-a putut stabili".
  7. Registrul Jurnal — editare/stergere manuala (COMUN\clase\comun.vc2:2222-2724, clasa afisjurcom) — canalul confirmat la pista 3(a). Genereic, orice document din ACT.
  8. Editare factura emisa (COMUN\clase\ofacturare_comun.vc2:3769-3838, proiectul #6) — canalul confirmat la pista 3(b), specific "facturi emise".
  9. frm_initializare_facturi_balanta.sc2 si frm_import_note_facturi_clienti.sc2 — canalul confirmat la pista 3, scop initializare/import pe categoria "facturi".
  10. eFactura import (COMUN\clase\anaf_efactura.vc2:12241,13087-13102,13244-13325) — acelasi tipar generic (actactan/tact + frm_modific2024 + oscrie_in_fisiere), dar pentru facturi de achizitie importate din XML ANAF, nu facturi emise — mentionat pentru completitudine, nu aplicabil direct la #13.
  11. ointroduceri.vc2/ointroduceri.prg (NIR, BON, RETUR, intrare din gestiune valorica) si oschimbare_pret.prg, oproceduri_rulaje.prg, reglari_denominare2005.prg — acelasi canal generic actactan/oscrie_in_fisiere, dar pentru alte categorii de document (gestiune, nu vanzare/factura). Mentionate pentru completitudinea listei de consumatori ai canalului, nu aplicabile la #13.

Niciuna dintre intrarile 1-6 (fluxul de emitere efectiv) nu are o ramura care sa ocoleasca politica. Intrarile 7-11 folosesc toate acelasi canal generic (punctul 3), dar niciuna nu e cablata pe fluxul de emitere — toate opereaza pe note deja existente sau pe alte categorii de document.


DDL ACT_TEMP (interogat 10.08.2026, schema MARIUSM_AUTO, ROA_CENTRAL)

Coloana Tip Null
SCD VARCHAR2(4) Y
ASCD VARCHAR2(4) Y
SCC VARCHAR2(4) Y
ASCC VARCHAR2(4) Y
COD, NRACT, SUMA, PERECHED, PERECHEC, SUMA_VAL, CURS, NEIMPOZAB, NNIR, ID_UTIL, ID_UTILS, ID_RESPONSABIL, ID_VENCHELT, ID_SECTIE, ID_SET, ID_FACT, ID_PARTD, ID_PARTC, ID_FDOC, ID_LUCRARE, ID_GESTIN, ID_GESTOUT, ID_VALUTA, PROC_TVA, STERS, ID_FACTD, ID_FACTC, VALIDAT, TVA_INCASARE numeric N (29 coloane NOT NULL, restul optionale)

Restul coloanelor (52 in total) sunt fie NUMBER (majoritatea NOT NULL), fie DATE/VARCHAR2 opționale (DATAIREG, EXPLICATIA, DATASCAD, EXPLICATIA4/5, ID_SUCURSALA, ID_ACT, ID_CTR, ID_JTVA_COLOANA, SERIE_ACT, ID_UTILV, DATAORAV, TAXCODE, PAYMENTCODE).

Constrangeri: 29 CHECK constraints (SYS_C0014966...SYS_C0014994) — corespund exact coloanelor NOT NULL de mai sus (Oracle genereaza CHECK (coloana IS NOT NULL) pentru NOT NULL declarat fara nume). Niciun constraint pe SCD/SCC (nici NOT NULL, nici CHECK de format, nici FK catre un plan de conturi). Nicio cheie primara/unica — normal pentru un tabel _TEMP de staging. Concluzie: schema nu blocheaza in niciun fel o valoare SCC calculata de VFP, oricare ar fi ea, inclusiv NULL.


Ce nu s-a putut stabilit si de ce

  • Punctul exact unde ACTACTAN primeste SCD/SCC in fluxul oscrie_vanzare_din_stoc (ofacturare_stoc.prg, intrarea 6 de mai sus) — codul citit (:104-450) nu arata sursa; ar necesita urmarirea completa a apelantului (initializeaza_vanzare_din_stoc) si a modulului care populeaza ACTACTAN inainte de acest punct (posibil pack_facturare.adauga_articol_factura_stoc intoarce un ref cursor legat automat de goExecutor pe numele actactan, dar nu am gasit apelul explicit). Nu schimba verdictul (oricum ar fi tot pack_facturare, deci tot politica), dar ramane o zona neinchisa complet.
  • Daca discountul pe linie (SCD=667/SCC=4111) are vreo cale alternativa in afara cursor_articol — nu verificat aici, presupus dependent de politica la fel ca restul buclei.
  • Comportamentul practic al frm_modific2024 cu privire la validarea contului tastat manual (daca exista vreo verificare verific_cont/plan de conturi la salvare, sau accepta orice text de 4 caractere) — nu urmarit pana la capat in omodificari.vc2; relevant doar daca se propune reutilizarea canalului 3(b)/3(a) pentru scriere programatica (fara interactiune UI), caz in care ar trebui verificat daca frm_modific2024 insusi impune vreo validare care ar bloca o scriere automata.
  • Daca fluxul de emitere (scrie_factura2) ar putea, teoretic, sa scrie intai o factura "goala" de nota (sau cu o nota tehnica minimala) si apoi sa foloseasca imediat, in aceeasi tranzactie logica, mecanismul de la pista 3(b) pentru a corecta SCC-ul — nu explorat aici (ar fi o propunere de design, in afara scopului acestei cercetari read-only); mentionat doar ca directie posibila care reiese direct din ce s-a gasit.
  • Nu am cautat/citit pack_contafin.SCRIE_IN_ACT/STERGE_DIN_ACT in PACK_CONTAFIN.pck pentru a confirma ca acestea, la randul lor, nu re-deriva SCC din altceva — presupunerea (bazata pe oracle_export.md si pe flux-modificare-stergere-nota-jurnal.md, care descriu deja aceste proceduri drept "distribuie ce a scris clientul", nu "recalculeaza") e ca fac un simplu INSERT INTO ACT SELECT * FROM ACT_TEMP-tip transfer, nu o derivare noua — dar nu am deschis personal codul lor in aceasta runda.