# Linii de comanda cu articol nemembru al politicii de pret — verificare facturare Status: FINALIZAT. ## Verdict **DA — s-a facturat cel putin o linie fara ca FACT-024 sa se declanseze.** Comanda `497`, linia `4294507522` (VOUCHER DISCOUNT) / politica `7` (DISCOUNT), a fost facturata cu succes in factura `ID_VANZARE=1028` (serie `SSS`, numar `535`, `FACTURAT=1`, `DATA_FACTURAT=2026-03-20`), desi articolul **nu e membru** al politicii 7 in `CRM_POLITICI_PRET_ART` la data acestei cercetari (10.08.2026). **Decizia 32 se REDESCHIDE partial**: nu pentru ca ar exista o cale de cod care ocoleste verificarea (codul chiar cheama `contabilizeaza_articol` pentru acest tip de vanzare, cf. punctul 3), ci pentru ca datele arata ca membru-ul politicii **s-a schimbat dupa facturare** — vezi punctul 4. Pentru celelalte 34 de linii cu acelasi articol/politica (35 in total cu `CANTITATE<0`), **nu exista nicio factura, nici macar stearsa** — la ele fisura ramane doar o stare inconsistenta nefacturata (vezi punctul 1). Observatie structurala separata de cea de mai sus: **inca 2 linii** (comenzile 114 si 115, alt articol, alta politica) au `CANTITATE>0`, adica **nefacturate inca deloc** — pentru acestea afirmatia "ar trebui sa cada la facturare" e neverificata pentru ca nu au fost niciodata trecute prin `contabilizeaza_articol`. ## 1. S-a facturat vreuna din ele fara eroare? Interogare: pentru fiecare din cele 37 linii `COMENZI_ELEMENTE` cu `ID_POL NOT NULL` si articol nemembru in `CRM_POLITICI_PRET_ART`, am cautat linii `VANZARI_DETALII` (prin `VANZARI.ID_COMANDA`) cu acelasi `ID_ARTICOL`+`ID_POL`, **inclusiv cele sterse** (ca sa nu ratez o factura anulata): ```sql select ce.id_comanda_element, ce.id_comanda, ce.id_articol, ce.id_pol, ce.cantitate, (select count(*) from vanzari v join vanzari_detalii vd on vd.id_vanzare=v.id_vanzare where v.id_comanda = ce.id_comanda and vd.id_articol=ce.id_articol and vd.id_pol=ce.id_pol) as nr_total_incl_sters from comenzi_elemente ce where ce.id_pol is not null and ce.cantitate < 0 and not exists (select 1 from crm_politici_pret_art cppa where cppa.id_pol = ce.id_pol and cppa.id_articol = ce.id_articol); ``` Rezultat: **doar comanda 497** are potriviri (2 linii `VANZARI_DETALII`, id 1494 si 1495, ambele `STERS=0`, `CANTITATE=-1` fiecare, apartinand facturii `ID_VANZARE=1028`). Toate celelalte 34 de comenzi (349, 351, 352, 359, 360, 377, 388, 404, 412, 417, 429, 443, 447, 450, 451, 453, 455, 456, 457, 466, 471, 475, 486, 500, 501) au **0 potriviri**, inclusiv sters. **Interpretare structurala a mecanismului** (cititul codului, nu presupunere): singurul loc care insereaza randuri cu `CANTITATE<0` in `COMENZI_ELEMENTE` e procedura `inchide_comanda` (`ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql:5769-5820`): ```sql INSERT INTO COMENZI_ELEMENTE (... CANTITATE ...) SELECT ..., NVL(C.CANTITATE, 0) + NVL(B.CANTITATE, 0) - A.CANTITATE AS CANTITATE, ... FROM COMENZI_ELEMENTE A LEFT JOIN (... FROM VANZARI_DETALII_TEMP ...) B ON ... -- lotul curent de facturare LEFT JOIN (... FROM VANZARI JOIN VANZARI_DETALII ...) C ON ... -- deja facturat anterior WHERE A.ID_COMANDA = :comanda AND SIGN(A.CANTITATE) * A.CANTITATE > SIGN(A.CANTITATE) * (NVL(C.CANTITATE, 0) + NVL(B.CANTITATE, 0)); ``` Asta insemna ca randul negativ **nu dovedeste singur ca linia a fost facturata** — el reprezinta *diferenta ramasa* fata de cantitatea comandata, la momentul **inchiderii** comenzii, chiar daca `B` (lotul curent) si `C` (facturat anterior) sunt amandoua 0. O comanda inchisa fara sa i se factureze o anumita linie tot primeste un rand `CANTITATE = -A.CANTITATE`. De-asta 34 din 35 de linii "negative" nu au nicio factura in spate: comenzile respective au fost **inchise** (probabil manual, ca "restanta anulata"), nu facturate pe acea linie. **Zero cazuri in date pentru acestea nu demonstreaza ca nu se poate factura — demonstreaza doar ca nu s-a intamplat.** Pentru comanda 497 insa, potrivirea cu 2 linii reale, active, `FACTURAT=1` in `VANZARI_DETALII` e dovada directa (nu inferenta) ca acea combinatie articol/politica **a ajuns** intr-o factura emisa. ## 2. Reconfirmarea cifrei si lista liniilor Cifra **37** se reconfirma exact (nu 6868/nemembru cum sugera masuratoarea anterioara — aceea era alt numitor; numitorul corect pentru linii cu `ID_POL NOT NULL` e **7108**, nu 6868): ```sql select count(*) from comenzi_elemente ce where ce.id_pol is not null; -- 7108 select count(*) from comenzi_elemente ce where ce.id_pol is not null and not exists (select 1 from crm_politici_pret_art cppa where cppa.id_pol = ce.id_pol and cppa.id_articol = ce.id_articol); -- 37 ``` Compozitie (verificata, `select sign(cantitate), count(*) ... group by sign(cantitate)`): - **35 linii** cu `CANTITATE=-1`: acelasi articol/politica in toate — `ID_ARTICOL=4294507522` ("VOUCHER DISCOUNT"), `ID_POL=7` ("DISCOUNT"). Comenzi: 349(x2), 351, 352(x2), 359, 360(x2), 377, 388, 404, 412(x2), 417, 429, 443, 447, 450, 451, 453, 455, 456, 457, 466, 471(x2), 475(x2), 486(x2), 497(x2), 500, 501(x2). - **2 linii** cu `CANTITATE=+10` (nefacturate inca, nicio urma de consum): - comanda 114, `ID_ARTICOL=4294507508` ("CAFEA TEST - PRODUS TEST PENTRU IMPORT WEB"), `ID_POL=2` ("LISTA 2"), data comanda 2025-09-10, `COMENZI.STERS` neverificat suplimentar dar randul e prezent activ. - comanda 115, `ID_ARTICOL=4171144217` ("CAFEA 1"), `ID_POL=2`. **Anomalie separata**: `COMENZI` nu contine niciun rand cu `ID_COMANDA=115` — antetul comenzii lipseste, doar linia de element a supravietuit. NEDETERMINABIL DIN DATE de ce (nu exista audit/istoric pe `COMENZI`); posibil date de test/import, dat fiind ca articolul insusi e "CAFEA TEST ... PENTRU IMPORT WEB" pe cealalta linie similara. Toate cele 37 de linii au `COMENZI_ELEMENTE.STERS=0` (nicio linie de comanda marcata stearsa). Stare de facturare per linie: singura cu urma reala de facturare e comanda 497 (vezi punctul 1); restul de 36 sunt **nefacturate** pe aceasta combinatie articol/politica. ## 3. Verificare cod FACT-024 (`contabilizeaza_articol`) Blocul citat in brief (`ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql:7278-7302`) e identic cu ce ruleaza in productie — verificat direct in codul compilat, nu doar in scriptul istoric (fisierul `.sql` e un istoric cumulativ cu **doua definitii** ale `contabilizeaza_articol` in text, la linia 746 si la 7173; doar a doua e cea vie): ```sql select owner, line from all_source where name='PACK_FACTURARE' and type='PACKAGE BODY' and text like '%FACT-024%'; ``` confirma acelasi text de eroare in schema `MARIUSM_AUTO` (Dev). Verificarea foloseste view-ul `VCRM_POLITICI_PRET_ART`: ```sql SELECT COMPUS, ID_POL_ART INTO ... FROM VCRM_POLITICI_PRET_ART WHERE ID_ARTICOL = detalii_articol.id_articol AND ID_POL = detalii_articol.id_pol; EXCEPTION WHEN NO_DATA_FOUND THEN ... RAISE_APPLICATION_ERROR(-20000, ... '(FACT-024)'); ``` Am verificat textul view-ului (`user_views`): `VCRM_POLITICI_PRET_ART` are `CRM_POLITICI_PRET_ART PA` ca tabel-sursa (driving table) al tuturor `LEFT JOIN`-urilor, fara niciun `WHERE` care sa filtreze `PA` (nu exista coloana `STERS` pe `CRM_POLITICI_PRET_ART`). Deci view-ul are exact acelasi set de perechi `(ID_POL, ID_ARTICOL)` ca tabelul de baza — verificarea mea prin `NOT EXISTS` pe `CRM_POLITICI_PRET_ART` e echivalenta cu ce evalueaza codul. **Concluzie: pentru toate cele 37 de linii, `SELECT ... INTO` ar da `NO_DATA_FOUND` -> `FACT-024`, daca ar trece prin `contabilizeaza_articol` ACUM, cu starea curenta a `CRM_POLITICI_PRET_ART`.** Apelul e neconditionat pentru facturi standard: am cautat toate apelurile `pack_facturare.contabilizeaza_articol(tab_detalii(i))` in codul **compilat** (`all_source`, schema `MARIUSM_AUTO`) — 6 aparitii, linii 4877, 4901, 5594, 5618, 5876, 5900. Linia 4901 e in procedura `scrie_factura2` (facturarea principala), in ramura `ELSE` a unui `CASE pack_facturare.ntip` care exclude doar transferurile intre subunitati (23,25,30,41), avizele de custodie (42,47) si facturile cu rate (2,6,52 cu `id_rata<>0`) — **tip 3 (tipul facturii 1028) cade in ELSE, deci `contabilizeaza_articol` chiar s-a executat pentru acea linie.** Prin urmare, pentru comanda 497: fie (a) la data facturarii (20.03.2026) articolul 4294507522 CHIAR era membru al politicii 7 si a fost scos ulterior din `CRM_POLITICI_PRET_ART`, fie (b) verificarea a fost ocolita altfel. Nu am gasit dovada de tip (b) — vezi punctul 4. ## 4. Cauza `CRM_POLITICI_PRET_ART` **nu are coloana `STERS`** si nu exista niciun tabel de istoric/audit pentru ea (`select table_name from user_tables where table_name like '%POLITICI%' or ... '%AUDIT%'` — doar tabelele de configurare curenta, niciunul de istoric). Stergerile din aceasta tabela sunt deci **fizice, fara urma**. Nu pot reconstitui direct daca perechea (politica 7, articol 4294507522) a existat la 20.03.2026. Coloanele de audit disponibile pe randurile facturii/comenzii **nu arata nicio editare ulterioara**: `VANZARI.ID_UTILS`/`DATAORAS` si `VANZARI_DETALII.ID_UTILS`/`DATAORAS` (1494, 1495) sunt toate NULL — niciun `UPDATE` standard nu a atins aceste randuri dupa creare. Deci nu exista dovada ca linia de factura ar fi fost modificata ulterior prin fluxul nou de "editare factura emisa" (adaugat recent in proiect, cf. changelog 2.11.15) — desi asta nu exclude o editare care ar fi ocolit acele coloane de audit, doar ca nu am gasit dovada ei. Indiciu indirect, dar nu concludent: articolul 4294507522 e denumit **"VOUCHER DISCOUNT"**, iar politica 7 e **"DISCOUNT"** — o pereche generica folosita ca linie de discount pe **35 de comenzi diferite**, nu un caz izolat. Reutilizarea masiva a exact aceleiasi perechi sustine ipoteza unei **modificari de catalog** (articolul-voucher scos ulterior din lista politicii DISCOUNT ca decizie de business/curatare), mai degraba decat 35 de erori de introducere independente. **Aceasta ramane insa o inferenta din tipar, nu o dovada directa — se marcheaza NEDETERMINABIL DIN DATE strict pe cauza si data exacta a schimbarii.** ## Ce am incercat si ce a esuat - Doua incercari de a delega cautarea codului sursa VFP/PL-SQL unui subagent `Explore` au esuat cu raspunsuri goale/neinformative ("Nimic nou.", "No new input to act on.") — fara nicio dovada ca ar fi rulat vreo cautare. Am renuntat la delegare si am facut cautarile direct cu Grep si Read. - Interogarea `all_source` fara `owner=` a intors linii duplicate/interclasate (schema `ACN` are de asemenea un `PACK_FACTURARE`) — a trebuit filtrat explicit pe `owner='MARIUSM_AUTO'` pentru rezultate coerente. - Un `prompt '---text---'` intre doua instructiuni SQL in acelasi fisier `.sql` a produs iesire amestecata (headerul s-a lipit de urmatoarea instructiune) — am renuntat la `prompt` si am rulat interogarile in fisiere separate. ## Date tehnice folosite - Conexiune: `MARIUSM_AUTO/ROMFASTSOFT@ROA_CENTRAL` (Dev), via `D:\ROA\instantclient_19_18\sqlplus.exe`, fisiere `.sql` ASCII in scratchpad, niciun `INSERT`/`UPDATE`/`DDL` rulat. - Cod verificat: `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql` (text istoric cumulativ) si pachetul compilat `MARIUSM_AUTO.PACK_FACTURARE` (`all_source`, sursa de adevar pentru ce ruleaza efectiv).