Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
200 lines
14 KiB
Markdown
200 lines
14 KiB
Markdown
# Cercetare — proforma, copiere document, puncte de intrare comanda/contract
|
|
|
|
Investigatie read-only, 09.08.2026. Nicio modificare de cod. Vezi si `docs\plan_13_unificare_formular_facturare.md`
|
|
si `docs\handoff_13_formular_unificat.md` (sesiune paralela, activa la data cercetarii — nu s-a atins
|
|
`COMUN\clase\ofacturare_comun.vc2` si nici `COMUN\programe\ofacturare_editare.prg`, marcate acolo ca "in lucru").
|
|
|
|
## 1. Proforma
|
|
|
|
**Concluzie.** Proforma nu e un tip de document separat (`poDate.tip` ramane 1-52, ca la orice
|
|
factura), ci un **atribut de numerotare/serie** (`poDate.nIdTipDoc = 23`, fata de `5` = FACTURA).
|
|
Se seteaza dintr-un combo "Tip document" (FACTURA/PROFORMA/BON FISCAL) aflat direct pe formularul
|
|
de antet unificat `frm_date_factura` — **acelasi formular** folosit si pentru facturi normale, fara
|
|
formular separat. Combo-ul e vizibil doar cand `frm_date_factura` e instantiat, adica doar pentru
|
|
tipuri de "factura" (nu si pentru avize, care merg pe `frm_date_aviz`, fara acest combo).
|
|
Nu exista un buton/meniu dedicat "Proforma noua": utilizatorul apeleaza fluxul normal de facturare
|
|
(`factureaza(tnTip)`) si comuta manual pe PROFORMA in antet.
|
|
|
|
**Dovezi:**
|
|
- `COMUN\programe\ofacturare_comun.prg:593-599` — setter-ul care leaga `nIdTipDoc` de `eProforma`:
|
|
`This.eProforma = IIF(m.tnIdTipDoc = This.nIdTipDocProforma, 1, 0)` (`nIdTipDocProforma = 23`,
|
|
`COMUN\programe\ofacturare_comun.prg:104`).
|
|
- `COMUN\clase\ofacturare.vc2:9396-9403` — `frm_date_factura.do_schimba_tipdoc`:
|
|
`lcTipDoc = UPPER(this.ct_clb_fdoc._combobox1.Value)` → mapare FACTURA/PROFORMA/BON FISCAL/AVIZ
|
|
la `nIdTipDoc`.
|
|
- `COMUN\clase\ofacturare.vc2:8745-8754` — combo-ul: `RowSource = "FACTURA,PROFORMA,BON FISCAL"`,
|
|
`Value = FACTURA` (implicit). Owner confirmat cu `vfp_symbols.ps1 -Where`:
|
|
`frm_date_factura [class] ofacturare.vc2:8482-9869`.
|
|
- `COMUN\clase\ofacturare.vc2:9415,9427-9428` — la schimbarea tipului: `initializeaza_setari_document(-102)`
|
|
pentru proforma, `poGeneratorNumere.dezaloca_numar(...)` + `creeaza_cursor_serii(poDate.nIdTipDoc)` —
|
|
**serie/numar propriu**, realocat la comutare.
|
|
- `COMUN\programe\ofacturare.prg:81-196` — `factureaza(tnTip, toFactura)`: la creare, `poDate.nIdTipDoc`
|
|
se seteaza explicit la `5` (FACTURA) sau `6` (AVIZ) dupa `tnTip` (`:187-196`); PROFORMA (23) nu
|
|
apare niciodata aici — se ajunge la ea **doar** din interactiunea cu combo-ul din antet.
|
|
- **Fara note contabile pe proforma**: `COMUN\programe\ofacturare.prg:1960,1996,2052,2063,2103` —
|
|
blocurile de scriere/actualizare nota contabila si atasamente sunt garzduite cu
|
|
`poDate.eProforma = 0`.
|
|
- **Continut specific de raport**: `COMUN\programe\ofacturare.prg:1119` (`Case poDate.eProforma = 1`)
|
|
ramifica pe un SQL de antet propriu (parteneri/adresa facturare) pentru listare; `:1638-1643`
|
|
(`Case ... And poDate.eProforma = 1` → `lcRaport = [PROFORMA]`) alege formularul `.fr2` dedicat
|
|
(`COMUN\Rapoarte\proforma.fr2`, `proforma_orig.fr2`, `proforma_val.fr2`).
|
|
- **Transformare in factura = copiere**: tooltip explicit,
|
|
`COMUN\clase\ofacturare_comun.vc2:1409`: *"Copiere (CTRL+K) * Se foloseste si pentru generarea
|
|
unei facturi din proforma prin copiere"*. Mecanismul: la copiere (`completeaza_setari_document`,
|
|
vezi §2) linia care ar propaga `nIdTipDoc` de la documentul sursa e **comentata**
|
|
(`COMUN\programe\ofacturare_comun.prg:370`: `*.nIdTipDoc = toDateAnterior.nIdTipDoc`), deci noul
|
|
document porneste implicit la `nIdTipDoc=5` (FACTURA) indiferent ca sursa era proforma — functioneaza,
|
|
dar prin omisiune, nu printr-o ramura dedicata "proforma → factura".
|
|
- **Relistare proforma**: cale separata de `factureaza`, in gridul de facturi:
|
|
`COMUN\clase\ofacturare_comun.vc2:7230-7264` (`PROCEDURE do_listare`, alt context decat
|
|
`frm_facturi.do_listare`) — filtreaza `crsFacturi` dupa `id_proforma=`, forteaza
|
|
`poDate.eProforma = 1` si `poDate.nRelistare = 1` (`:7258-7260`).
|
|
- Referinta tipuri: `COMUN\docs\tipuri_documente_facturare.md` — confirma ca `TIP` (1-52) e ortogonal
|
|
fata de proforma; niciun rand din tabel nu e "proforma" ca atare.
|
|
|
|
**Ce e specific proformei, confirmat cu dovada:**
|
|
1. Serie/numar propriu (`nIdTipDoc=23`, realocare la comutare din combo).
|
|
2. Fara scriere de nota contabila / atasamente (gate `eProforma=0` in `ofacturare.prg`).
|
|
3. Raport de listare propriu (`.fr2` dedicate).
|
|
4. "Transformare in factura" = copiere obisnuita, care scapa tipul de document proforma pentru ca
|
|
linia de propagare e comentata (efect secundar, nu design explicit).
|
|
|
|
**Nu am putut confirma cu dovada** (vezi "Necunoscute ramase"): daca descarcarea de gestiune e
|
|
efectiv sarita pentru proforma la nivel de Oracle (`PACK_FACTURARE`, sursa nu e in cache text local).
|
|
|
|
## 2. Copierea documentului
|
|
|
|
**Concluzie.** Traseul e `frm_facturi.But_copiaza1.Click` → `do_copiaza` (degradeaza tipul) →
|
|
`copiere_factura` → `factureaza(tip_degradat, toFactura)` → `frm_date_factura` cu antetul
|
|
pre-completat din `completeaza_setari_document(toFactura, .T.)`. Se aloca **intotdeauna** numar nou
|
|
(alocarea de serie ruleaza neconditionat in `factureaza`, indiferent de `llCopiere`). Campurile de
|
|
antet raman editabile (nimic din traseu seteaza `Enabled=.F.` pe controale de antet la copiere);
|
|
singurul efect vizibil e relabelarea campului "Altele" in "Nr. factura" cand tipul degradat e
|
|
1/5/10/48/49 sau 48/49 sub `gnScadereStoc=0`.
|
|
|
|
**Dovezi:**
|
|
- `COMUN\clase\ofacturare_comun.vc2:3628-3713` — `do_copiaza`: degradeaza tipul (tabelul deja
|
|
cunoscut, ex. `T2/T3/T4/T8/... → T1`, `:3696-3710`), apoi `DO copiere_factura WITH loFactura IN
|
|
oproceduri_facturare.prg` (`:3710`).
|
|
**Bug observat, nu cerut de investigat**: ramura `CASE INLIST(loFactura.tip,T21,T24,T26,T30,...)`
|
|
(`:3702-3703`) scrie `lnTip = T22` in loc de `loFactura.tip = T22` — variabila gresita, degradarea
|
|
nu se aplica efectiv pe aceasta ramura (avize catre clienti din comanda/contract/retur etc.).
|
|
- `COMUN\programe\oproceduri_facturare.prg:150-153` — `copiere_factura`: `factureaza(toFactura.Tip,
|
|
toFactura)`.
|
|
- `COMUN\programe\ofacturare.prg:111` — `llCopiere = (Type('toFactura') = 'O')`;
|
|
`:203-206` — `If m.llCopiere: poDate.completeaza_setari_document(m.toFactura, .T.)`.
|
|
- `COMUN\programe\ofacturare_comun.prg:362-412` — `completeaza_setari_document(toDateAnterior,
|
|
tlFactura)`: ramura `tlFactura=.T.` (copiere) seteaza `.lCopiere=.T.` si precompleteaza
|
|
lucrare/sectie/agent/delegat/masina/`listaid = toDateAnterior.id_vanzare`/`descriere`
|
|
(serie+numar sursa)/client (`:368-390`); **nu** propaga `nIdTipDoc`, `id_responsabil`,
|
|
`id_venchelt` (comentate, `:370,373,377`).
|
|
- **Numar nou, mereu**: `COMUN\programe\ofacturare.prg:208,211` — `poGeneratorNumere.ResetNumere()`
|
|
+ `poDate.rezultat_serii = poGeneratorNumere.creeaza_cursor_serii(poDate.nIdTipDoc)` ruleaza in
|
|
bucla principala a lui `factureaza`, inainte de a deschide formularul, **neconditionat de
|
|
`llCopiere`**. Functia: `COMUN\programe\oserii_numere.prg:128-177` (`Function
|
|
creeaza_cursor_serii`).
|
|
- **Relabel antet la copiere**: `COMUN\clase\ofacturare.vc2:9622-9628,9652-9658` —
|
|
`IF m.llCopiere: .ct_clb_altele.do_schimba_explicatia([Nr. factura])` (altfel campul e eliminat
|
|
din formular pentru acele tipuri).
|
|
- **Reutilizabil vs specific degradarii**: reutilizabil = `copiere_factura`/`factureaza(tip,
|
|
toFactura)`/`completeaza_setari_document` (mecanismul general de copiere, indiferent de tip);
|
|
strict legat de degradare = tabelul `#DEFINE T.../DO CASE` din `do_copiaza` (`:3629-3708`) — acolo
|
|
se decide explicit "ce tip devine ce tip la copiere", nimic din asta nu se refoloseste in afara
|
|
acestei metode.
|
|
|
|
## 3. Punctele de intrare "factura din comanda" / "factura din contract"
|
|
|
|
**Concluzie.** Ambele exista deja, **cu precompletare reala**, dar pe cai diferite:
|
|
- **Contract**: azi precompletarea vine **din ROACONTRACTE** (produs separat), nu din ROAFACTURARE.
|
|
Butonul "Factura" de pe gridul de contracte populeaza globalul `goContract` din randul selectat si
|
|
cheama acelasi `factureaza(2/6/52)` din COMUN.
|
|
- **Comanda**: exista deja un buton de facturare **direct in ROAFACTURARE**, pe tab-ul Comenzi
|
|
(`Page5.Ct_comenzi1`), care populeaza `goComanda` din randul de grid selectat inainte de a chema
|
|
`factureaza(3)` — deci raspunsul la "exista deja un buton?" e **da**, nu ipotetic.
|
|
- Exista si o cale **generica, nepre-completata**, in meniul principal al ROAFACTURARE
|
|
(`Clase\ofundal_facturare.vc2`, tab Page2): pentru contract nu atinge `goContract`; pentru comanda
|
|
**reseteaza explicit** `goComanda = ''` inainte de apel — utilizatorul alege manual din formular.
|
|
|
|
**Semnatura `factureaza`:**
|
|
```
|
|
COMUN\programe\ofacturare.prg:81-82
|
|
Procedure factureaza
|
|
Lparameters tnTip, toFactura
|
|
```
|
|
`tnTip` = tipul de business (1-52, tabelul din `tipuri_documente_facturare.md`); `toFactura` = obiect
|
|
opational, folosit azi **doar** pentru copiere factura/aviz (nu pentru contract/comanda). Nu exista
|
|
parametru dedicat pentru "contract precompletat" sau "comanda precompletata" — canalul e globalul
|
|
`goContract`/`goComanda`, citit in `oDateFactura.Init`.
|
|
|
|
**Dovezi — mecanismul comun (globale citite la creare `poDate`):**
|
|
- `COMUN\programe\ofacturare_comun.prg:261-297` — `Init`, ramura
|
|
`If INLIST(m.tnTip, 2, 6, 52) And Type('goContract') <> 'U'` → `.id_client = goContract.id_part`,
|
|
`.listaid = goContract.id_ctr`, `.descriere = goContract.contract`, plus interogare
|
|
`fact_vcontracte` pentru scadenta (`:274-296`).
|
|
- `COMUN\programe\ofacturare_comun.prg:301-328` — ramura
|
|
`If tnTip = 3 And Type('goComanda') = 'O'` → `.id_client = goComanda.id_part`,
|
|
`.listaid = goComanda.id_comanda`, `.descriere = goComanda.nr_comanda`, plus interogare sectie
|
|
(`:312-323`).
|
|
|
|
**Dovezi — contract, din ROACONTRACTE:**
|
|
- `D:\ROA\ROACONTRACTE\Clase\ferestre_contracte.vc2:1605` — `grid_contracte.AfterRowColChange`:
|
|
`SCATTER NAME goContract MEMO` la fiecare schimbare de rand selectat.
|
|
- `D:\ROA\ROACONTRACTE\Clase\ferestre_contracte.vc2:1538-1549` — `but_factura.Click`: meniu
|
|
"Factura lei;Invoice;Factura fiscala in valuta" → `DO facturare_contracte WITH 'FACTURA LEI'/...
|
|
IN oproceduri_facturare.prg` (copia locala din `ROACONTRACTE\COMUN`, acelasi cod ca in
|
|
ROAFACTURARE).
|
|
- `COMUN\programe\oproceduri_facturare.prg:118-136` — `facturare_contracte(tcTip)` →
|
|
`factureaza(2)` / `factureaza(6)` / `factureaza(52)`.
|
|
- **Cale generica, fara precompletare**, in ROAFACTURARE insusi:
|
|
`Clase\ofundal_facturare.vc2:886-897` (`Page2.Cw2.do_actiune`) — acelasi meniu, aceeasi
|
|
`facturare_contracte`, dar **nu** atinge `goContract` inainte — daca globalul nu a fost populat
|
|
in sesiune (`Type('goContract') = 'U'`), ramura de precompletare din `Init` nu se activeaza si
|
|
userul alege contractul manual din `frm_date_factura.do_cauta_contract`
|
|
(`COMUN\clase\ofacturare.vc2:9067-9115`, deja cunoscut din context).
|
|
|
|
**Dovezi — comanda, buton deja existent in ROAFACTURARE:**
|
|
- `COMUN\clase\ocomenzi.vc2:1580-1596` — `ct_comenzi.do_factura`:
|
|
`SELECT crsComenzi` → `SCATTER NAME goComanda MEMO` → `DO facturare_comenzi IN
|
|
oproceduri_facturare.prg` → `this.do_cauta()`.
|
|
- `COMUN\clase\ocomenzi.vc2:932-937` — butonul: `ADD OBJECT 'But_factura1' AS but_factura`, clasa
|
|
de baza `COMUN\clase\cmd_butoane.vc2:96-107` (`DEFINE CLASS but_factura ... caction = do_factura`,
|
|
`ToolTipText = "Factura"`, `Picture = factura1.bmp`).
|
|
Vizibilitate conditionata de starea comenzii: `COMUN\clase\ocomenzi.vc2:2199-2203`
|
|
(`grid_comenzi...`) — `this.Parent.but_factura1.Visible = (goComanda.facturat = 0)` (ascuns daca
|
|
deja facturata).
|
|
- **Montare in ROAFACTURARE**: `Clase\ofundal_facturare.vc2:604` — `ADD OBJECT 'Page5.Ct_comenzi1'
|
|
AS ct_comenzi`; `Ferestre\fundal.sc2:206` — `Page5.Ct_comenzi1.But_factura1.Name = "But_factura1"`
|
|
confirma montarea concreta pe formular (nu doar in clasa sursa).
|
|
- `COMUN\programe\oproceduri_facturare.prg:138-141` — `facturare_comenzi` → `factureaza(3)`.
|
|
- **Cale generica, fara precompletare**: `Clase\ofundal_facturare.vc2:899-902`
|
|
(`Page2.Cw3.do_actiune`): `goComanda = ''` apoi `DO facturare_comenzi ...` — reseteaza explicit
|
|
globalul inainte de apel, deci userul alege comanda manual in formular.
|
|
|
|
**Concluzie combinata pentru "gazda naturala"**: pentru comanda, gazda exista deja
|
|
(`COMUN\clase\ocomenzi.vc2`, buton `But_factura1`, montat in `Clase\ofundal_facturare.vc2` Page5).
|
|
Pentru contract, gazda echivalenta **nu exista in ROAFACTURARE** — traieste azi doar in
|
|
`ROACONTRACTE\Clase\ferestre_contracte.vc2`; daca s-ar dori acelasi tipar in ROAFACTURARE, ar trebui
|
|
fie o pagina de contracte proprie (subiectul planului `docs\plan_10_integrare_contracte.md`, azi
|
|
"propunere, neinceput", cu decizie go/no-go in asteptare), fie un buton similar montat direct pe o
|
|
lista de contracte inexistenta azi in acest produs.
|
|
|
|
## Necunoscute ramase
|
|
|
|
1. **Descarcare de gestiune pe proforma**: n-am putut confirma/infirma daca `PACK_FACTURARE`
|
|
(server-side Oracle) sare efectiv descarcarea de stoc pentru documente cu `nIdTipDoc=23`. Sursa
|
|
pachetului nu e in cache text local (`COMUN\docs\PACK_FACTURARE.pck` nu exista; doar
|
|
`PACK_CONTAFIN.pck`, `PACK_UPDATE.pck` etc.). Comentariul din `ofacturare.prg:52` ("daca este
|
|
proforma, pun toate articolele negestionabile, ca sa nu mai arate stocul") sugereaza ca partea
|
|
VFP trateaza stocul doar vizual, nu ca dovada asupra scrierii server-side.
|
|
2. **Campuri de antet blocate la copiere**: am confirmat ca traseul de copiere nu seteaza explicit
|
|
`Enabled=.F.` pe controale de antet (nimic gasit in `frm_date_factura` pentru `llCopiere`), dar
|
|
nu am verificat exhaustiv fiecare control individual — doar relabelarea campului "Altele".
|
|
Tratati ca "probabil toate editabile", nu ca fapt verificat camp-cu-camp.
|
|
3. **Bug-ul din `do_copiaza` (`:3702-3703`, `lnTip` in loc de `loFactura.tip`)** e raportat ca
|
|
dovada gasita in timpul cercetarii, nu ca urmare a unei cereri explicite de audit — nu a fost
|
|
verificat efectul lui in productie (date de test).
|
|
4. **ROACONTRACTE nu are cod la fel de detaliat verificat ca ROAFACTURARE**: desi are cache text
|
|
(203 fisiere `.vc2/.sc2`, contrar notei mai vechi din `plan_10_integrare_contracte.md` care spunea
|
|
ca nu exista), nu am facut o trecere completa a formularului de contracte — doar traseul minim
|
|
pentru `but_factura.Click`.
|