Files
comun/docs/cercetare/import_roris_roaacnpro.md
Marius Mutu 09ddeabb1c 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
2026-08-11 22:31:53 +03:00

211 lines
12 KiB
Markdown

# Anatomia butonului "Import Roris & Contracte" (ROAACNPRO)
Cercetare read-only in `D:\ROA\ROAACNPRO`, ca model pentru un buton generic
"importa articole din sursa" intr-un formular de facturare unificat in ROAFACTURARE.
Nicio editare de fisiere, niciun `git_sync.ps1`/`txt2vcx.ps1`, niciun commit — doar investigatie.
## 1. Localizare
**Concluzie**: Butonul e `cmdImport` (clasa `cmd_executa`) pe formularul `frm_factura`, definit in
`Clase\oacnpro.vc2`. Nu are `Click` propriu — mosteneste `Click` din clasa de baza a butoanelor,
care ruleaza metoda numita in proprietatea `caction`; `cmdImport` nu suprascrie `caction`, deci
ramane valoarea implicita `do_executa` mostenita de la clasa `cmd_executa`
(`COMUN\clase\cmd_butoane.vc2:474`). Codul efectiv e in `PROCEDURE do_executa` a formularului
`frm_factura`.
**Dovezi**:
- `Clase\oacnpro.vc2:6894-6905` — definirea controlului:
```
ADD OBJECT 'cmdImport' AS cmd_executa WITH ... Caption = "\<Import Roris & Contracte", ... Left = 597, Top = 65, Width = 169
```
- `COMUN\clase\cmd_butoane.vc2:474` — `caction = do_executa` (mostenit de `cmd_executa`).
- `COMUN\clase\_cmd_base.vc2:120-159` — `PROCEDURE Click` a clasei de baza: construieste
`lcCommand = [this.Parent.] + lcAction + ...` si il executa cu macro (`&lcCommand`).
- `Clase\oacnpro.vc2:7814-7836` — `PROCEDURE do_executa` a lui `frm_factura` (clasa incepe la
`oacnpro.vc2:6398 DEFINE CLASS frm_factura`, se termina la `8383`).
## 2. Preconditii
**Concluzie**: Butonul e activ doar daca (a) factura nu e inca salvata (`llFacturaEditabila`) si
(b) tipul facturii (`poDate.cTip`, ales din `cboTip`) e unul din
`TRANZIT, CHEIAJ, CHIRII, APA, PENALITATI`. In plus, la Click, `do_executa` verifica separat ca a
fost ales clientul.
**Dovezi**:
- `Clase\oacnpro.vc2:8117-8145`:
```
llFacturaEditabila = !This.lFacturaSalvata
llRorisSauContracte = INLIST(poDate.cTip, 'TRANZIT', 'CHEIAJ', 'CHIRII', 'APA', 'PENALITATI') && butonul import RORIS&Contracte este activ doar pentru RORIS sau contracte
...
.cmdImport.Enabled = m.llFacturaEditabila and m.llRorisSauContracte
```
- `Clase\oacnpro.vc2:7820-7823`:
```
IF EMPTY(NVL(this.nIdClient,0))
AMESSAGEBOX('Alegeti clientul!',0+48,_screen.Caption)
RETURN
ENDIF
```
- Fara client ales, butonul e vizibil/activ dar Click-ul se opreste cu acest mesaj.
## 3. Ce face efectiv
**Concluzie**: `do_executa` -> `factura_import()` (`Programe\proceduri_acnpro.prg:3151`) ramifica
dupa `poDate.cTip`:
- TRANZIT/CHEIAJ: `vizualizare_tranzit()` -> deschide dialogul `frm_tranzit` (selectie convoaie din
vederea Oracle `ips_vvoyages`) -> la confirmare, `calcul_tranzit()`/`calcul_cheiaj()` interogheaza
direct (SELECT-uri simple, nu pachete PL/SQL) tabelele/vederile `ips_vvoyage_members_calcul`,
`ips_vvoyage_locks`, apoi deschide un al doilea dialog de editare tarife (`frm_calcul_tranzit`).
- CHIRII/APA: `vizualizare_contract()` -> `calcul_contract()` -> SELECT din vederea
`vctr_articole2` (articole de contract) -> dialog `frm_calcul_contract`.
- PENALITATI: `vizualizare_penalitati()` -> `frm_penalitati` cu cursorul `crsCalculPenalitati`
calculat in VFP din vederile `vanzari`/`ireg_parteneri`/`penalitati`.
Dupa confirmarea dialogului (validat prin variabila globala `gnButon = 1`, standard framework
pentru formulare modale), se apeleaza `make_factura_tranzit` / `make_factura_cheiaj` /
`make_factura_contracte` / `make_factura_penalitati`, care insereaza direct in `crsFactura`.
**Important**: nicio procedura Oracle stocata (`pack_*`) nu e apelata in etapa de import — acestea
(`pack_facturare.*`, `pack_acn.salveaza_regdoc`, `pack_contafin.*`) sunt apelate abia la
**salvarea** finala a facturii (`factura_salvare_db`, `Programe\proceduri_acnpro.prg:3290+`), nu
la import.
**Dovezi**:
- `Programe\proceduri_acnpro.prg:3151-3212` (`Procedure factura_import`), `740-771`
(`calcul_tranzit`, sursa `ips_vvoyage_members_calcul`), `1127-1161` (`calcul_contract`, sursa
`vctr_articole2`).
- `Programe\proceduri_acnpro.prg:939-943`:
`loFrmTranzit = Crea("frm_calcul_tranzit", ...); loFrmTranzit.Show(1); llSucces = (m.gnButon = 1)`.
- `Programe\proceduri_acnpro.prg:3331-3467` — apelurile `pack_facturare.*`/`pack_acn.salveaza_regdoc`
sunt in `factura_salvare_db`, nu in `factura_import`.
## 4. Cum populeaza factura
**Concluzie**: Scrie **direct** in cursorul de articole al facturii, `crsFactura`, prin
`INSERT INTO crsFactura(...)` in fiecare `make_factura_*` — nu trece prin vreo metoda generica
"adauga articol" a formularului (exista o metoda separata `do_adauga_articol` pentru adaugare
manuala de linie, dar importul n-o foloseste). Liniile se **adauga** peste cele existente (nu
sterge/inlocuieste `crsFactura` inainte). Protectia la dublu-import e partiala:
- dupa un import reusit, `This.cmdImport.Enabled = .F.` dezactiveaza butonul (nu se mai poate
importa a doua oara in aceeasi sesiune de editare a facturii);
- pentru TRANZIT/CHEIAJ exista un avertisment (nu blocaj) daca pe convoaiele alese exista deja
facturi (`ips_vvoyages_vanzari.numar_act IS NOT NULL`) — utilizatorul poate continua oricum.
**Dovezi**:
- `Clase\oacnpro.vc2:7827-7834`:
```
llSucces = factura_import(m.tlImportCalculat)
IF m.llSucces
This.cmdImport.Enabled = .F. && nu mai import altceva
This.chkIntern.Enabled = .F.
This.ActiveazaSalvare()
...
```
- `Programe\proceduri_acnpro.prg:3601` (TRANZIT) / `3677-3678` (CHEIAJ) / `3764-3765`
(CHIRII/APA): `Insert Into crsFactura(nrcrt, id_articol, denumire, ...)`.
- `Clase\oacnpro.vc2:14915-14930` — avertisment dublu-import in `frm_tranzit.do_executa`:
```
SELECT numar_act, data_act, client FROM ips_vvoyages_vanzari WHERE vye_id in (...) AND numar_act is NOT null ...
IF RECCOUNT('cFacturiTranzitTemp') > 0
lcMesaj = 'Atentie! Exista facturi pe tranzitele alese!' + CHR(13)+CHR(10) + ...
AMESSAGEBOX(m.lcMesaj,0+48,_screen.Caption)
ENDIF
```
(mesaj informativ, apoi continua oricum cu `calcul_tranzit`/`calcul_cheiaj`).
## 5. Feedback catre utilizator
**Concluzie**: Mesaje punctuale prin `AMESSAGEBOX`, nu un sistem unitar de raportare:
- Client lipsa: `'Alegeti clientul!'` (`oacnpro.vc2:7821`).
- Convoi/liniile de import lipsa dupa dialog: `'Alegeti un convoi!'` in `make_factura_tranzit`
daca `poDate.uuid` (id-urile alese) e gol (`proceduri_acnpro.prg:3530`); analog pentru
CHIRII/APA prin `factura_salvare` (`'Alegeti convoiul'`/`'Adaugati prestatii'`,
`proceduri_acnpro.prg:3221`, dar aceasta e verificare la *salvare*, nu la import).
- Facturi deja existente pe convoaiele alese: avertisment neblocant (vezi punctul 4).
- Zero rezultate in dialogul de selectie (`frm_tranzit`/`frm_calcul_contract`): niciun mesaj
explicit gasit — grila ramane goala, iar la `Calculare`/`Terminat` fara nimic bifat `lcVyeIds`
ramane vid si `IF !EMPTY(m.lcVyeIds)` (`oacnpro.vc2:14912`) sare peste tot calculul, fara mesaj
catre utilizator (comportament implicit: butonul pare sa nu faca nimic).
- Eroare Oracle: nu exista tratare `TRY/CATCH` explicita in `factura_import`/`calcul_tranzit`/
`make_factura_*`; erorile SQL se propaga prin returul `.F.` al lui
`goExecutor.oExecuta`/`oSelecteaza2Value`, iar afisarea erorii tine de comportamentul standard
al `goExecutor` (framework comun, neexaminat in detaliu aici).
**Dovezi**: citatele de mai sus; pentru "zero rezultate fara mesaj" — `Clase\oacnpro.vc2:14898-14943`.
## 6. Selectivitate
**Concluzie**: Da, exista dialoage intermediare cu selectie, diferite pe tip:
- **TRANZIT/CHEIAJ**: `frm_tranzit` (`oacnpro.vc2:14492-15003`) — grid `grdTranzit` cu coloane
`Declaratia`, `Data decl.`, `Convoi`, `Origin`, `Destinatie` si o coloana checkbox `cAles`
(`ControlSource='crsConvoaie.ales'`), plus criterii de cautare (`Cb_tx_cautare1`,
`But_start_criterii1`/`But_reset_criterii1`) si buton `cmdCalculeaza` ("Calculare Tarife").
Utilizatorul bifeaza unul sau mai multe convoaie; daca nu bifeaza niciunul, se ia randul curent
(`lcVyeId` din `crsConvoaie` la pozitia curenta). Dupa `Calculare Tarife`, se deschide **al
doilea nivel** — `frm_calcul_tranzit`/`frm_calcul_cheiaj` — pentru editarea/confirmarea
tarifelor calculate, inainte de a reveni in factura.
- **CHIRII/APA**: `calcul_contract()` deschide `frm_calcul_contract` cu cursorul
`crsArticoleContract` (articol, perioada, um, pret, cantitate, valoare, valuta, locatie) din
vederea `vctr_articole2` filtrata pe `id_ctr` — practic toate articolele contractului curent,
editabile in acel dialog.
- **PENALITATI**: `frm_penalitati` cu grid `grdPenalitati` (`crsCalculPenalitati`), coloane
vizibile precum `cNrDoc`, `cSuma` ("Sold restant" in modul evaluare), `cDataDoc`.
Deci nu e un "importa tot" fara interventie — e mereu mediat de un dialog de vizualizare/calcul/
confirmare (`gnButon = 1` = utilizatorul a confirmat).
**Dovezi**: `Clase\oacnpro.vc2:14500-14515` (obiecte grid + `cAles`), `14801`
(`ControlSource='crsConvoaie.ales'`), `14594-14601` (`cmdCalculeaza`);
`Programe\proceduri_acnpro.prg:1137-1153` (`crsArticoleContract` din `vctr_articole2`);
`Programe\proceduri_acnpro.prg:545-555` (`frm_penalitati`, `grdPenalitati.cSuma`, `.cNrDoc`,
`.cDataDoc`).
## 7. Butoanele vecine
**Concluzie**: Pe `frm_factura`, `cmdImport` e plasat in zona antetului facturii
(`Left=597, Top=65`), langa `cboTip` (`Left=507, Top=67` — combo cu tipul facturii) si
`chkIntern` (`Left=412, Top=70`) — nu langa bara principala de butoane. Bara principala de sus
(`Top=0`) contine, in ordinea `Left`: `but_factura_noua` ("Nou", `Left=688`), `But_salveaza1`
("Salveaza", `Left=719`), `But_renunt1` ("Renunta", `Left=749`). Separat, langa grila
`grdFactura`, exista butoane de linie (`Top=120`): `But_nou1` ("Adauga linie", `Left=707`) si
`But_sterge1` ("Sterge linie", `Left=737`). Mai sunt `but_cautare_client`/`but_cautare_beneficiar`
(lupa cautare partener, langa campurile de client/beneficiar).
**Dovezi**: `Clase\oacnpro.vc2:6779-6818` (definitiile `but_factura_noua`, `But_nou1`,
`But_renunt1`, `But_salveaza1`, `But_sterge1` cu `Left`/`Top`), `6836-6851` (`cboTip`),
`6853-6863` (`chkIntern`), `6894-6905` (`cmdImport`).
## Ce e transferabil in ROAFACTURARE
Tiparul general merita copiat ca **model de arhitectura pentru un buton generic "importa
articole din sursa"**:
1. Buton activ conditionat de (a) factura editabila (nesalvata) si (b) tip de document care are o
sursa de import — exact ca `llFacturaEditabila and llRorisSauContracte`.
2. O metoda de intrare unica (`do_executa`/`factura_import`) care ramifica dupa tipul documentului
catre functii specializate de "vizualizare/selectie" — fiecare deschide un dialog modal de
selectie (grid cu coloana checkbox `ales`, criterii de cautare), returneaza succes/esec prin
variabila globala tip `gnButon = 1`.
3. Populare prin `INSERT INTO <cursor_articole>` direct, aditiv (nu sterge liniile existente), cu
dezactivarea butonului dupa import reusit ca protectie minimala la dublu-import — plus
(optional) un avertisment neblocant daca sursa a mai fost deja folosita in alta factura.
4. Separarea neta intre etapa de **calcul/import** (SELECT-uri simple pe vederi Oracle, fara
proceduri stocate) si etapa de **salvare** (unde intra pachetele PL/SQL) — util ca principiu:
importul nu trebuie sa scrie definitiv in baza, doar sa populeze cursorul local.
Ce e strict specific ACN/RORIS si **nu** se transfera: sursele de date (`ips_vvoyages`,
`ips_voyage_members_vanzari`, `ips_vberthing_details_vanzari`, `vctr_articole2`), logica de calcul
tarife/ecluzari/porturi, formularele `frm_tranzit`/`frm_calcul_tranzit`/`frm_calcul_contract`/
`frm_penalitati` ca atare, si valorile `poDate.cTip` (`TRANZIT/CHEIAJ/CHIRII/APA/PENALITATI`).
## Necunoscute ramase
- Comportamentul exact al `goExecutor.oExecuta`/`oSelecteaza2Value` la eroare Oracle (mesaj
afisat, retry, log) — n-a fost verificat in profunzime (functie framework comun).
- Continutul complet al dialogului `frm_calcul_tranzit`/`frm_calcul_cheiaj` (al doilea nivel,
editare tarife) — am confirmat doar ca exista si ca `gnButon=1` marcheaza confirmarea, dar nu am
detaliat coloanele/campurile lui.
- Detaliile `frm_calcul_contract` (butoane, posibilitate de deselectare articole individuale) nu
au fost citite integral — doar sursa cursorului.
- Nu am verificat daca exista vreo validare suplimentara de "acelasi convoi importat de doua ori
in aceeasi factura" dincolo de avertismentul cross-factura mentionat la punctul 4.