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

12 KiB

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:474caction = do_executa (mostenit de cmd_executa).
  • COMUN\clase\_cmd_base.vc2:120-159PROCEDURE Click a clasei de baza: construieste lcCommand = [this.Parent.] + lcAction + ... si il executa cu macro (&lcCommand).
  • Clase\oacnpro.vc2:7814-7836PROCEDURE 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 nivelfrm_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.