Files
roacont/docs/handoff_transa2_conditii.md
Marius Mutu 7cd7d57708 Transa 1 ANAF TVA: changelog 2.11.67, plan corectat pe date, handoff-uri de verificare
Plan corectat in patru puncte confirmate pe Oracle:
- lista de coloane de taxare inversa are 13 termeni, nu 10 (TI19T/TI09T nu exista pe jc2007;
  expresia din oproceduri_decont.prg:8670 e scrisa peste view-ul VJC2025, cu aliasuri calculate)
- tva_incasare nu exista pe jc2007/jv2007; interogarea transei 3 merge pe VJC2025/VJV2025
- kill-switch-ul nu se face in Optiuni_FIRMA/PROGRAM.dbf, ci pe modelul RC_ANAF_VERIF_SELECTIE
  (INI + optiuni Oracle + intrare de meniu)
- oExecute deschide dialog de reconectare cu QUIT pe conexiune cazuta; apelul din transa 3 trebuie
  sa dezactiveze explicit reconectarea

SVN r17910/r17911.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 00:50:26 +03:00

9.8 KiB

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 compileazaORA-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 <TI nenul>) 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:

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):

SELECT jtva_ti FROM anaf_vefactura_primit WHERE 1=2;
-- ORA-00904: "JTVA_TI": invalid identifier

Recomandare: USER_TAB_COLUMNS, nu TRY pe SELECT:

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.