# TRANSA 2 (L4) — inchidere conditii de intrare — verificare Oracle Data: 27.07.2026. Conexiune: `MARIUSM_AUTO@ROA_CENTRAL` (schema dev), read-only, doar SELECT. Fisiere sursa salvate: `docs/local/view_anaf_vefactura_primit.sql`, `docs/local/view_anaf_vefactura_trimis.sql`. ## VERDICT GENERAL - **A — INCHISA.** Definitiile curente extrase din `USER_VIEWS.TEXT`. - **B — INCHISA PARTIAL.** Mecanismul e confirmat pe date, dar NU dintr-o factura venita real din import eFactura (nu exista in schema dev). Demonstrat pe cel mai apropiat caz din `jc2007`. - **C — INCHISA, cu recomandare concreta.** Forma subselectului unic e mai jos. - **D — INCHISA.** Sonda recomandata: `user_tab_columns`. **CONTRAZICE PLANUL (cel mai important gasit):** lista canonica de 10 coloane din plan (`TI21T, TI11T, TI19T, TI09T, TI24T, TI20T, XX21TIT, XX11TIT, XX19TIT, XX9TIT`) **nu compileaza direct pe `JC2007`**. `TI19T` si `TI09T` NU exista ca si coloane pe tabela — vezi B mai jos. --- ## A. Definitiile curente ale view-urilor Extrase din `USER_VIEWS.TEXT` (nu din arhiva CLAR), salvate integral in: - `docs/local/view_anaf_vefactura_primit.sql` - `docs/local/view_anaf_vefactura_trimis.sql` Confirmari: - `anaf_vefactura_primit.jtotctva` = subselect corelat pe `jc2007 j` + `left join nom_parteneri p`, cheie de potrivire an/luna/dataact + `REGEXP_SUBSTR(a.xnumar_act, '\d+[^[:digit:]]*$') LIKE '%'||TO_CHAR(j.nract)||'%'` + `REGEXP_REPLACE(p.cod_fiscal,'[^[:digit:]]','') = a.cod_fiscal_emitent`. Exact cum descrie planul. - `anaf_vefactura_trimis.jtotctva` = acelasi tipar dar pe **`jv2007`** (nu `jc2007`), cheie pe `cod_fiscal_beneficiar`, filtru `a.factura_emisa = 1`. Confirma ca planul are dreptate sa puna `jtva_ti = 0` constant la trimis: la vanzari nu exista familia `TI*`/`XX*TIT` (verificat — acele coloane sunt specifice achizitiilor, nu apar in `jv2007`, nu a fost nevoie sa fie recalculate). **Views DETALIU** — exista amandoua, construite peste view-urile de baza prin `id_efactura`/`id`: - `ANAF_VEFACTURA_PRIMIT_DETALIU` (VALID) — `SELECT f.* (coloane specifice), d.* FROM anaf_vefactura_primit f JOIN anaf_efactura_detalii d ON f.id = d.id_efactura`. - `ANAF_VEFACTURA_TRIMIS_DETALIU` (VALID) — identic, pe `anaf_vefactura_trimis`. - Bonus gasit: exista si `ANAF_VEFACTURA_EMIS_DETALIU`, dar e **INVALID** azi (preexistent, nelegat de L4 — de semnalat, nu de reparat aici). Important pentru scriptul de migrare: niciuna din cele doua DETALIU nu selecteaza `jtotctva` sau orice coloana noua din view-ul de baza (`f.*` explicit enumerat, fara `jtotctva`/`jtva_ti`) — deci adaugarea `jtva_ti` in view-urile de baza **nu le afecteaza structural**, doar le invalideaza temporar (dependinta VFP) pana la recompilare automata pe urmatoarea referire. Se pastreaza verificarea de obiecte invalide ceruta de plan la finalul scriptului. --- ## B. Trasare cap-coada — CONTRAZICE PLANUL pe lista de coloane ### Ce s-a confirmat - `ProcentTva2IdJtva` (gasita real in `COMUN\programe\oproceduri_comune.prg:5836`, NU in `anaf_efactura.vc2` cum spune planul — functia e apelata acolo la `:12093`/`:12636`, dar **definita** in `oproceduri_comune.prg`) confirma exact id-urile din plan pentru taxare inversa pe JC: 21%->216, 11%->218, 19%->141, 9%->145 (`:5864-5871`). - `oproceduri_decont.prg:8670` (citat corect de plan) e o expresie SQL, dar **din view-ul `VJC2025`**, nu direct pe `jc2007`. Am extras `USER_VIEWS.TEXT` pentru `VJC2025`: acolo `ti19t` si `ti09t` sunt ALIASURI calculate — `SUM(a.ti19bct + a.ti19bvt + a.ti19bft) as ti19t`, `SUM(a.ti09bvt + a.ti09bft) as ti09t` — NU coloane fizice. ### Verificare directa pe `JC2007` (`USER_TAB_COLUMNS`) Din cele 10 coloane canonice din plan, gasite pe tabela **8/10**: | Coloana plan | Exista pe JC2007? | |---|---| | TI21T, TI11T, TI24T, TI20T | DA (coloane simple) | | XX21TIT, XX11TIT, XX19TIT, XX9TIT | DA (coloane simple) | | **TI19T** | **NU** — pe tabela exista in schimb `TI19BCT`, `TI19BVT`, `TI19BFT` (3 subcoloane) | | **TI09T** | **NU** — pe tabela exista in schimb `TI09BVT`, `TI09BFT` (2 subcoloane, fara varianta `BC`) | Un `create or replace view` care scrie `nvl(j.TI19T,0)+nvl(j.TI09T,0)` direct pe `jc2007 j` **nu compileaza** — `ORA-00904`. Lista corecta de termeni pentru `jc2007` (13 termeni, nu 10): ``` NVL(j.TI21T,0)+NVL(j.TI11T,0)+NVL(j.TI24T,0)+NVL(j.TI20T,0) + NVL(j.TI19BCT,0)+NVL(j.TI19BVT,0)+NVL(j.TI19BFT,0) + NVL(j.TI09BVT,0)+NVL(j.TI09BFT,0) + NVL(j.XX21TIT,0)+NVL(j.XX11TIT,0)+NVL(j.XX19TIT,0)+NVL(j.XX9TIT,0) ``` ### Factura reala cu taxare inversa — NU exista una venita din import eFactura in schema dev - `anaf_efactura` (schema `MARIUSM_AUTO`): 487 randuri primite, doar **8** au `id_fact` completat (legatura catre `jc2007`/`act`). Niciunul dintre acele 8 `id_fact` se suprapune cu vreun rand din `jc2007` care are coloane `TI*`/`XX*TIT` nenule (31 randuri in toata schema, toate din test/demo, ani 2007-2022, fara `id_fact` legat de `anaf_efactura`). Interogarea de join explicit (`jc2007 j JOIN anaf_efactura a ON a.id_fact = j.id_fact WHERE a.factura_emisa=0 AND `) a intors **0 randuri**. - Cele 6 randuri din `anaf_vefactura_primit` cu `id_fact` legat au `total_cu_tva = jtotctva` (diferenta 0) — niciuna dintre ele nu e taxare inversa, deci nu demonstreaza mecanismul. **Cel mai apropiat caz gasit** (nu vine din eFactura, e din `jc2007` direct — demonstreaza doar aritmetica pe care view-ul o va aplica): ``` an=2022 luna=4 dataact=30-APR-22 nract=222 id_part=614 id_fact=8007136 ti19bft=19 totctva=119 ``` Daca acest rand ar fi venit dintr-un import eFactura cu linie `AE` (TVA XML = 0), XML-ul ar fi avut `total_cu_tva = 100` (119 - 19 taxare inversa), in timp ce `jtotctva` (= `SUM(totctva)`) tot ar da `119`. Cu view-ul curent: `diferenta = total_cu_tva - jtotctva = 100 - 119 = -19` (fals pozitiv, exact cat e TVA de taxare inversa). Cu `jtva_ti` adaugat: `diferenta = total_cu_tva - (jtotctva - jtva_ti) = 100 - (119 - 19) = 0`. Mecanismul se confirma numeric, dar **pe un caz sintetic, nu pe o factura reala din import eFactura** — schema dev nu are asa ceva. De consemnat in nota de release: verificare finala pe date reale ramane de facut la prima factura de taxare inversa importata dupa aplicarea scriptului (sau pe schema de productie/testare cu date reale, daca exista acces). --- ## C. Verdict performanta — forma subselectului unic Confirmat: `jtotctva` e deja un subselect scalar corelat cu `REGEXP_SUBSTR`/`REGEXP_REPLACE` in `WHERE`, neindexabil. Recomandare: `CROSS APPLY` (Oracle 12c+, disponibil pe 19c) in loc de doi subselecti scalari separati — un singur scan per rand din urma, ambele sume calculate odata: ```sql SELECT ..., jt.jtotctva, jt.jtva_ti FROM anaf_efactura a CROSS APPLY ( SELECT SUM(j.totctva) AS jtotctva, SUM(NVL(j.TI21T,0)+NVL(j.TI11T,0)+NVL(j.TI24T,0)+NVL(j.TI20T,0) +NVL(j.TI19BCT,0)+NVL(j.TI19BVT,0)+NVL(j.TI19BFT,0) +NVL(j.TI09BVT,0)+NVL(j.TI09BFT,0) +NVL(j.XX21TIT,0)+NVL(j.XX11TIT,0)+NVL(j.XX19TIT,0)+NVL(j.XX9TIT,0)) AS jtva_ti FROM jc2007 j LEFT JOIN nom_parteneri p ON j.id_part = p.id_part WHERE j.an = EXTRACT(YEAR FROM a.xdata_act) AND j.luna = EXTRACT(MONTH FROM a.xdata_act) AND j.dataact = a.xdata_act AND REGEXP_SUBSTR(a.xnumar_act, '\d+[^[:digit:]]*$') LIKE '%' || TO_CHAR(j.nract) || '%' AND REGEXP_REPLACE(p.cod_fiscal, '[^[:digit:]]', '') = a.cod_fiscal_emitent ) jt WHERE a.factura_emisa = 0 ``` Motiv pentru `CROSS APPLY` (nu doi subselecti separati): pastreaza exact semantica actuala — fiind un `SUM(...)` fara `GROUP BY`, subquery-ul `APPLY` intoarce mereu exact un rand (NULL pe ambele sume cand nu exista potrivire), identic cu comportamentul scalar-subquery de azi. Nu necesita restructurarea restului view-ului (multe coloane scalare + `detalii` tip `M`/CLOB, imposibil de pus curat intr-un `GROUP BY` la nivel de view fara alte modificari). Nu e scriptul de migrare final — doar forma recomandata, de validat de cine scrie scriptul. Pe `anaf_vefactura_trimis`: `jtva_ti` ramane `0` constant (fara subselect), deci nu exista cost suplimentar acolo — planul are dreptate aici, nimic de schimbat. --- ## D. Sonda de coloana Confirmat azi (inainte de migrare): ```sql SELECT jtva_ti FROM anaf_vefactura_primit WHERE 1=2; -- ORA-00904: "JTVA_TI": invalid identifier ``` **Recomandare: `USER_TAB_COLUMNS`**, nu `TRY` pe `SELECT`: ```sql SELECT COUNT(*) FROM user_tab_columns WHERE table_name = 'ANAF_VEFACTURA_PRIMIT' AND column_name = 'JTVA_TI'; ``` Motive: - Confirmat ca views apar normal in `USER_TAB_COLUMNS` (40 coloane gasite pentru `ANAF_VEFACTURA_PRIMIT`), deci interogarea functioneaza identic pe view ca pe tabela. - E o interogare de dictionar, fara sa declanseze parsarea/executia interogarii principale — in VFP nu necesita un bloc `TRY/CATCH` in jurul unui `SELECT` care ar putea arunca o eroare ANAF pe conexiunea Oracle reala (goExecutor), doar un `SELECT ... FROM user_tab_columns`, mai usor de facut robust si de logat separat daca lipseste catalogul. - Cost neglijabil (interogare pe dictionar, nu pe date), rulata o singura data la deschiderea ferestrei, nu per rand. --- ## Alte observatii utile pentru cine scrie scriptul de migrare - `TI09` nu are deloc varianta `BC` (doar `BV`/`BF`) — asimetric fata de `TI19` care are toate 3 (`BC`/`BV`/`BF`). Nu e o eroare, tabela chiar arata asa; scriptul trebuie sa scrie exact `TI09BVT + TI09BFT` (2 termeni), nu 3. - `XX9TIT`/`XX9TIB` (fara zero la 9) sunt corecte, exista pe tabela — confirmat, la fel cum zice planul. - `ANAF_VEFACTURA_EMIS_DETALIU` e INVALID in schema dev azi, independent de L4 — de mentionat catre echipa daca cineva verifica obiecte invalide global, ca sa nu fie confundat cu o stricare produsa de scriptul L4.