# 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.`, **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 ELSE 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 () 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.