docs: cercetarile trans-proiect din ROAFACTURARE trec in COMUN
Paisprezece rapoarte care nu erau ale ROAFACTURARE traiau in docs\cercetare\ al acelui proiect: valuta si curs in ofacturare, TVA calculat vs salvat plus denormalizarea VANZARI, inventarul consumatorilor VANZARI din toata suita ROA, integrarile de contracte/politici/nomenclator (#10, #11, #12), watchdog-ul VFP de testare, proiectarea Oracle a scrierii din S5 si view-ul VVANZARI_ARTICOLE. Motivul mutarii, nu doar al pastrarii: planurile #10, #11 si #12 sunt amanate, iar indexul lor spune explicit ca se reiau din aceste rapoarte - deci sunt punct de plecare, nu istoric. Iar tinta lor e COMUN plus ROAPRETURI/ROACONTRACTE. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
This commit is contained in:
220
docs/cercetare/rec_consumatori_vanzari.md
Normal file
220
docs/cercetare/rec_consumatori_vanzari.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# Inventar consumatori `VANZARI.AVIZE`/`CURS`/`ID_VALUTA`/`MULTIPLICATOR` in suita ROA
|
||||
|
||||
Cercetare STRICT de citire (fara modificari de cod, fara DDL, fara conexiuni DB, fara rulare de
|
||||
conversii noi `vcx2txt.ps1`/`git_sync.ps1`) — masoara riscul de comportament schimbat dupa
|
||||
corectiile S4 (AVIZE, WHERE lipsa) si S8/curs (garda `nin_valuta`) aplicate in `PACK_FACTURARE`
|
||||
(vezi `rec_s4_aplicare.md`). Executata cu 3 subagenti in paralel: (a) ROAFACTURARE+COMUN, (b) cele
|
||||
8 produse cu cache text deja generat, (c) restul suitei (~56 directoare).
|
||||
|
||||
## RISC REAL
|
||||
|
||||
**1. Referinta la aviz dispare de pe factura retiparita (tip=4).**
|
||||
`COMUN\programe\oproceduri_facturare.prg` (`listeaza_formular`, ~:1125/:1189/:1265) si dublura ei
|
||||
`COMUN\clase\ofacturare_comun.vc2` (`frm_facturi.do_listeaza_formular`, ~:4103/:4204) — cod
|
||||
partajat, prezent in tot ecosistemul ROA*. Construiesc `crsFacturaListare` din `FACT_VFACTURI2`
|
||||
(coloana `altele` = alias pentru `vanzari.avize` cand `tip in (4,24,8,9)`), apoi
|
||||
`poDate.descriere = Alltrim(altele)` specific pentru `tip=4` ("factura din aviz"). `poDate.descriere`
|
||||
ajunge pe formularul tiparit ca referinta "nr. aviz" (layout exact in `.frx`, neconvertit — vezi
|
||||
gap mai jos). **Ce se schimba**: la retiparirea/relistarea unei facturi `tip=4` mai vechi, unde
|
||||
`vanzari.avize` era populat gresit inainte (smearat de UPDATE-ul fara WHERE) si acum e gol pentru
|
||||
majoritatea facturilor, referinta la aviz dispare vizibil de pe document. E in calea de reprint,
|
||||
nu de emitere — deci afecteaza utilizatorul la orice reeditare/retiparire ulterioara corectiei.
|
||||
|
||||
**2. Nota "Curs: X RON/valuta" pe factura electronica/PDF, generata fara verificare `in_valuta`.**
|
||||
`xmlefactura.prg` (COMUN partajat, cod identic — verificat prin hash — in ROAEFACTURA, ROASITFIN,
|
||||
ROACONIMPORT, ROAPRINT, ROAPRODUCTIE, ROACONT/OUTPUT, si prezent si in ROAFACTURARE/COMUN):
|
||||
```
|
||||
IF !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
|
||||
lcTextAditional = ... + "Curs: " + ALLTRIM(STR(loDate.curs,10,4)) + " RON/" + ... loDate.cValuta ...
|
||||
ENDIF
|
||||
```
|
||||
Conditia verifica doar `curs` nenul, nu si `loDate.in_valuta` (spre deosebire de blocul de cateva
|
||||
linii mai jos, `DocumentCurrencyCode`, care testeaza corect `in_valuta=1`). Inainte, facturile in
|
||||
LEI aveau deja `curs` populat gresit (bug), deci nota aparea eronat, dar cu o valoare "plauzibila".
|
||||
**Ce se schimba**: dupa corectie, `curs=1` pe facturile in lei — `!EMPTY(1)` tot trece, deci nota
|
||||
tot apare, dar acum arata constant `"Curs: 1.0000 RON/"` cu sufix de valuta gol (`id_valuta=0`).
|
||||
Vizibil pe fiecare factura/aviz in lei exportata ca e-factura sau tiparita, in toate produsele de
|
||||
mai sus.
|
||||
|
||||
## RISC POSIBIL
|
||||
|
||||
3. **`ofacturare_comun.vc2:4156-4157`** (si dublura `oproceduri_facturare.prg:1225-1226`): dupa
|
||||
blocul `If poDate.in_valuta = 1 ... Else ... Endif`, `poDate.Curs`/`poDate.multiplicator` sunt
|
||||
suprascrise necondiționat din valorile citite din view. Calculul de discount e corect protejat
|
||||
de `in_valuta=1`, dar nu s-a putut confirma daca FRX-ul (neconvertit) afiseaza aceste campuri
|
||||
necondiționat de `in_valuta`. De verificat in layout-ul tiparit.
|
||||
4. **`vizualizare_facturi2` (`oproceduri_facturare.prg:431-479`)**: grid-ul de cautare/listare
|
||||
facturi expune coloanele `altele`, `curs`, `multiplicator`, `valuta`, `id_valuta`, `nume_val`
|
||||
direct din `FACT_VFACTURI2`. Nu s-a putut confirma legarea la `ControlSource` in `.scx`
|
||||
(neconvertit) — daca vreuna e legata vizibil intr-un grid, utilizatorii ar vedea coloane
|
||||
goale/"1" unde inainte vedeau valori (gresite).
|
||||
5. **ROAACNPRO** `Programe\proceduri_acnpro.prg:1180-1229`, `calcul_penalitati` (calea activa):
|
||||
`Select v.Curs, v.id_Valuta ... left join vnom_valute vl on v.id_valuta = vl.id_valuta From
|
||||
vanzari v`, afisat probabil intr-un grid de review inainte de generarea facturilor de
|
||||
penalizare. Calculul numeric al penalitatii NU foloseste `curs` (confirmat), deci fara risc de
|
||||
calcul; ramane risc de **afisare**: `id_valuta=0` ar putea sa nu se potriveasca in
|
||||
`left join vnom_valute` (tabela de valute proprie ACNPRO, distincta de `NOM_VALUTE`), lasand
|
||||
coloana `valuta` goala. Nu s-a putut confirma daca `vnom_valute` are un rand pentru
|
||||
`id_valuta=0` (spre deosebire de `NOM_VALUTE`, unde existenta randului `id_valuta=0` a fost deja
|
||||
confirmata in `rec_s4_aplicare.md`, punctul 3 din sectiunea S8/curs — deci pentru view-urile
|
||||
`FACT_VFACTURI*` din COMUN acest risc e deja exclus, ramane specific tabelei proprii ACNPRO).
|
||||
6. **ROAAUTO** `Programe\oproceduri_devize.prg:1486-1532`, `relisteaza_factura_deviz`: citeste
|
||||
`curs`/`multiplicator`/`altele` din `fact_vfacturi` la reafisarea unei facturi, dar cursorul se
|
||||
inchide imediat fara ca valorile sa fie propagate mai departe — risc redus, de reverificat doar
|
||||
daca un apelant viitor se bazeaza pe acelasi cursor.
|
||||
7. **`CONTAFIN2ORA\VFP2ORA\Programe\acn.prg:~1247-1319`** (unealta de migrare, nu produs curent de
|
||||
vanzare): scrie direct `curs`/`id_valuta`/`multiplicator` in `INSERT INTO VANZARI` +
|
||||
`MERGE INTO VANZARI_CURSURI`, cu propria regula de zero-ing independenta de `PACK_FACTURARE` —
|
||||
probabil neafectata functional, dar merita o verificare separata daca unealta mai e folosita
|
||||
activ.
|
||||
|
||||
## FARA RISC (rezumat, nu enumerate)
|
||||
|
||||
- **ROAFACTURARE+COMUN**: restul celor ~930 potriviri brute pentru `AVIZE`/`CURS`/`ID_VALUTA`/
|
||||
`MULTIPLICATOR`/`ALTELE` — module NIR/import, balante/parteneri/compensari, salarii, curs
|
||||
valutar BNR, sau citiri deja corect protejate de `in_valuta`/`tip_valuta`
|
||||
(`ofacturare.prg::listeaza_ofacturare` la emitere, `ofacturare_stoc.prg`, `anaf_efactura.prg` cu
|
||||
`decode(in_valuta,1,curs,1)`, `makexmlfacturaelectronica.prg` cu garda `mmoneda<>"RON"`). Niciun
|
||||
hit `.avize` (acces direct de camp) in afara celor doua raportate mai sus.
|
||||
- **ROACONT**: `Programe\saft_d406.prg` (declaratia fiscala D406, `oSalesInvoices`) — foloseste
|
||||
`DECODE(v.in_valuta, 0, 0, ...)` explicit, output SAF-T neschimbat de corectie. Restul hit-urilor
|
||||
pe tabele proprii (`ireg_parteneri`, `act`, `rul`) sau text necorelat.
|
||||
- **ROAACNPRO** (restul), **ROACONTRACTE**, **ROAGEST**, **ROAIMOB**, **ROAREGISTRATURA**,
|
||||
**ROASTART**: zero hit relevant legat de `VANZARI` in afara COMUN (verificat, nu doar negasit).
|
||||
- **~40 de produse din restul suitei** (ROAEFACTURA si variante, ROASITFIN, ROAPRINT,
|
||||
ROACONIMPORT, ROAPRODUCTIE, ROAHOTEL si variante, ROASAL, ROAMANAGER, ROADECL, ROAPRETURI,
|
||||
ROABAZA, ROAAPROV, ROADEVIZE, etc.): hit-uri pe "AVIZE" = conceptul de business "aviz de
|
||||
expeditie" (tip document), nu coloana; hit-uri "CURS"/"ID_VALUTA" pe alte tabele proprii sau in
|
||||
`oDateFactura` (populate de apelant, protejate de `in_valuta`). `COMUNROA` (depozitul central)
|
||||
contine doar scripturi de deployment, fara logica de facturare.
|
||||
|
||||
## Rezumat acoperire
|
||||
|
||||
- **ROAFACTURARE + COMUN local**: acoperire completa `.prg` + `.vc2`/`.sc2` via `vfp_symbols.ps1
|
||||
-CodeOnly` (index deja construit). **Gap**: 207 `.frx` si 30 `.mnx` fara `.fr2`/`.mn2` in cache —
|
||||
layout-ul efectiv tiparit (unde `poDate.descriere`/`Curs`/`cValuta` chiar apar pe hartie) nu e
|
||||
verificabil fara conversie (interzisa in acest task). Riscurile REAL #1/#2 si POSIBIL #3/#4
|
||||
depind partial de acest layout.
|
||||
- **8 produse cu cache text existent** (ROAACNPRO, ROAAUTO, ROACONT, ROACONTRACTE, ROAGEST,
|
||||
ROAIMOB, ROAREGISTRATURA, ROASTART): acoperire completa `.prg` + `.vc2`/`.sc2` via
|
||||
`vfp_symbols.ps1 -CodeOnly`. **Gap**: proprietati/metadata (`ControlSource` de grid legat direct
|
||||
de o coloana, fara linie de cod explicita) nu apar in `-CodeOnly` — dar un asemenea caz s-ar
|
||||
clasifica oricum FARA RISC (simpla afisare).
|
||||
- **Restul suitei** (~56 directoare, inclusiv `COMUNROA`): acoperire **doar** pe fisierele `.prg`
|
||||
(text simplu, nu necesita conversie); zero cache text pentru `.vcx`/`.scx` — **niciun cod din
|
||||
clase/formulare compilate al acestor produse nu a fost verificat**, conform interdictiei de a
|
||||
genera cache nou. ~35 produse identificate ca in afara domeniului (unelte/infrastructura: SSH,
|
||||
server, telefonie, criptare, declaratii D1xx/D3xx/D406 etc.) fara nicio potrivire pe termenii
|
||||
cautati.
|
||||
- Nicio conexiune la baza de date folosita; cifrele despre distributia datelor (ex. randul
|
||||
`id_valuta=0` din `NOM_VALUTE`) sunt preluate din `rec_s4_aplicare.md`, deja documentate.
|
||||
|
||||
## Concluzie
|
||||
|
||||
Doua locuri cu **risc real** confirmat, ambele in codul COMUN partajat (deci efect cross-project):
|
||||
disparitia referintei la aviz de pe facturile `tip=4` retiparite, si textul "Curs: 1.0000 RON/"
|
||||
afisat gresit pe nota facturii electronice/PDF pentru facturile in lei. Restul e risc posibil,
|
||||
dependent de layout-uri `.frx`/`.scx` neconvertite (gap de acoperire cunoscut, nu absenta de risc).
|
||||
Nu s-a gasit niciun consumator cu risc real de **calcul** (sume/discounturi) — toate caile de
|
||||
calcul verificate sunt deja protejate corect de `in_valuta`.
|
||||
|
||||
---
|
||||
|
||||
## Corectie aplicata — riscul REAL #2 (nota "Curs:" din `xmlefactura.prg`)
|
||||
|
||||
Modificare de cod, ceruta explicit de team-lead dupa livrarea inventarului de mai sus. Domeniu:
|
||||
**doar** `D:\ROA\ROAFACTURARE\COMUN\programe\xmlefactura.prg`. Nicio alta copie din suita nu a
|
||||
fost atinsa.
|
||||
|
||||
### Ce s-a schimbat
|
||||
|
||||
Linia 374 (acum singura diferenta fata de fisierul dinainte de editare):
|
||||
```diff
|
||||
- IF !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
|
||||
+ IF loDate.in_valuta = 1 AND !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
|
||||
lcTextAditional = m.lcTextAditional + Iif(!Empty(m.lcTextAditional), ' # ', '') + "Curs: " + ...
|
||||
ENDIF
|
||||
```
|
||||
Garda adaugata (`loDate.in_valuta = 1 AND`) e preluata **identic** din modelul deja corect din
|
||||
acelasi fisier, la 9 linii mai jos (acum `:385`, era `:384`): `If loDate.in_valuta = 1` /
|
||||
`oinvoice.lastchild.Text = m.mmoneda`, folosit pentru `DocumentCurrencyCode`. Nicio forma noua
|
||||
inventata. Fara comentarii adaugate (regula 2, rezolvari de erori). Diff complet:
|
||||
`D:\ROA\ROAFACTURARE\docs\diff_xmlefactura_garda_valuta.patch`.
|
||||
|
||||
### Verificare pe cazuri (dupa modificare)
|
||||
|
||||
1. **Factura in lei (`in_valuta=0`), `curs=1`** (comportamentul nou, generalizat, al facturilor in
|
||||
lei dupa corectia `PACK_FACTURARE`): inainte, `!EMPTY(NVL(1,0))=.T.` -> nota aparea cu
|
||||
`"Curs: 1.0000 RON/"` (valuta goala). Acum, `loDate.in_valuta = 1` e `.F.` -> intreg `AND`-ul e
|
||||
fals -> nota NU se mai adauga. **Singurul caz care isi schimba comportamentul** (cel vizat).
|
||||
2. **Factura in valuta reala (`in_valuta=1`)**, curs populat normal: `loDate.in_valuta = 1` e
|
||||
`.T.`, restul conditiei neschimbat -> nota apare identic ca inainte. Neschimbat.
|
||||
3. **Factura veche cu `curs` NULL** (orice `in_valuta`): `NVL(NULL,0)=0` -> `!EMPTY(0)=.F.` ->
|
||||
conditia era deja falsa inainte de garda si ramane falsa (garda adaugata doar restrange in plus
|
||||
cazul `in_valuta=0`, nu schimba nimic pe ramura `curs` NULL). Neschimbat.
|
||||
|
||||
Confirmat: doar cazul 1 (facturi in lei cu `curs` efectiv nenul) isi schimba comportamentul, exact
|
||||
riscul identificat.
|
||||
|
||||
### Verificare encoding (byte-level)
|
||||
|
||||
Fisierul contine octeti cp1252 `>=0x80` (`0xEE` = "î", la liniile 1203 si 1330 — "puteti încarca
|
||||
prin SPV"), deci risc de corupere la scriere cu tool care nu pastreaza octetii nativ. Editare
|
||||
facuta cu `perl` in mod raw (`s/.../.../ `), nu cu Edit/Write:
|
||||
- Backup pre-editare: `xmlefactura.prg.pre_runda.bak` (md5 `e800c71bd08e6c472b6fe912437f37f8`,
|
||||
62093 octeti).
|
||||
- Dupa editare: md5 `c9c9f4774346b2e62bfe9c12ea02dfb3`, 62118 octeti (+25 = exact lungimea
|
||||
textului `loDate.in_valuta = 1 AND ` inserat).
|
||||
- Comparatie linie-cu-linie (raw bytes) intre backup si fisierul editat: **1364 linii in ambele,
|
||||
o singura linie diferita (374)** — restul fisierului byte-identic.
|
||||
- Octetii `0xEE` de la liniile 1203/1330 confirmati neschimbati dupa editare.
|
||||
- Scanare pentru markeri de corupere (`EF BF BD` = U+FFFD reincodat): zero potriviri.
|
||||
|
||||
Encoding intact, nicio corupere.
|
||||
|
||||
### Copii identice/asemanatoare in suita — corectie fata de raportul initial
|
||||
|
||||
Raportul initial (sectiunea RISC REAL #2) afirma ca fisierul e "identic prin hash" in ROAEFACTURA,
|
||||
ROASITFIN, ROACONIMPORT, ROAPRINT, ROAPRODUCTIE si ROACONT/OUTPUT — verificare hash directa acum
|
||||
(md5 pe tot arborele `D:\ROA`, exclus `DATABASE`) arata ca afirmatia era **partial gresita**: doar
|
||||
`ROACONIMPORT` si `ROAPRINT` sunt byte-identice intre ele; restul au fiecare continut propriu,
|
||||
divergent de `ROAFACTURARE`. Ce e adevarat si ramane valabil: **toate contin acelasi tipar de cod
|
||||
vulnerabil** (linia cu conditia fara garda pe `in_valuta`), verificat cu grep, o singura aparitie
|
||||
in fiecare fisier.
|
||||
|
||||
**Grup A — fisier byte-identic cu `ROAFACTURARE/COMUN` INAINTE de editarea de azi**
|
||||
(md5 `e800c71bd08e6c472b6fe912437f37f8`, deci acelasi patch de o linie de la `:374` se aplica
|
||||
identic, byte cu byte, in toate):
|
||||
`ROAACNPRO`, `ROAAUTO`, `ROACONT`, `ROACONTRACTE`, `ROADEF`, `ROAGEST`, `ROAIMOB`,
|
||||
`ROAREGISTRATURA`, `ROARES`, `ROASTART` — cale `D:\ROA\<PRODUS>\COMUN\programe\xmlefactura.prg`.
|
||||
(In plus, acelasi hash apare si in foldere de backup istoric fara relevanta:
|
||||
`_backup_comun_conflicts\*`, `_backup_roaimob_comun_conflict\*` — nu sunt copii vii.)
|
||||
|
||||
**Grup B — fisier divergent (alt continut/alte linii in rest), dar cu ACELASI tipar vulnerabil**
|
||||
(conditie identica textual, gasita o singura data per fisier, doar la alt numar de linie):
|
||||
| Produs | Cale | md5 | Linia conditiei |
|
||||
|---|---|---|---|
|
||||
| OUTPUT/ROACONT | `D:\ROA\OUTPUT\ROACONT\COMUN\programe\xmlefactura.prg` | `504dc24e771f6d66e4f028d1347671a8` | 350 |
|
||||
| ROACONIMPORT | `D:\ROA\ROACONIMPORT\COMUN\programe\xmlefactura.prg` | `fa1e389839109ae46da1ef815e102259` | 356 |
|
||||
| ROAEFACTURA | `D:\ROA\ROAEFACTURA\COMUN\programe\xmlefactura.prg` | `200442ad86e180c2484c96367ac9514a` | 356 |
|
||||
| ROAPRINT | `D:\ROA\ROAPRINT\COMUN\programe\xmlefactura.prg` | `fa1e389839109ae46da1ef815e102259` | 356 |
|
||||
| ROAPRODUCTIE | `D:\ROA\ROAPRODUCTIE\COMUN\programe\xmlefactura.prg` | `b71c1d9284d8ee78d02429b04c968a35` | 326 |
|
||||
| ROASITFIN | `D:\ROA\ROASITFIN\COMUN\programe\xmlefactura.prg` | `47bb2e49770713b396e855e8af0ae2ea` | 356 |
|
||||
|
||||
**Grup C — NU are acest bloc de cod deloc** (verificat, nu doar negasit — nu construiesc nota de
|
||||
curs valutar in e-factura): `ROADECL`, `ROAMANAGER`, `ROAPRETURI`, `ROASAL`. Fara risc, fara
|
||||
propagare necesara.
|
||||
|
||||
**Fisierul modificat azi**: doar `D:\ROA\ROAFACTURARE\COMUN\programe\xmlefactura.prg` (md5 nou
|
||||
`c9c9f4774346b2e62bfe9c12ea02dfb3`). Toate celelalte 16 cai listate mai sus (Grup A + Grup B)
|
||||
raman NEATINSE, cu bug-ul inca prezent — propagarea e decizie de proces a lui Marius, nu s-a facut
|
||||
aici.
|
||||
|
||||
### Livrabile
|
||||
|
||||
- Modificare: `D:\ROA\ROAFACTURARE\COMUN\programe\xmlefactura.prg` (linia 374, +garda `in_valuta`).
|
||||
- Patch de review: `D:\ROA\ROAFACTURARE\docs\diff_xmlefactura_garda_valuta.patch`.
|
||||
- Backup pre-editare (ramas pe disc, netracked): `xmlefactura.prg.pre_runda.bak` in acelasi folder.
|
||||
- Aceasta sectiune.
|
||||
|
||||
Fara commit git/svn — asteapta aprobarea patch-ului.
|
||||
Reference in New Issue
Block a user