docs: runda 6 - cercetari, propuneri si conventia mediului Oracle
Cercetarile si propunerile rundelor 4-6 pe editarea facturii emise. Starea rundei 6 si ce s-a stabilit intra in progres.md. Nou: docs/conventii_mediu_oracle.md - pe dev/test se lucreaza numai cu ROA_CENTRAL si schemele CONTAFIN_ORACLE si MARIUSM_AUTO; schema ACN nu se foloseste. Scripturile de pachet sunt necalificate, deci schema tinta o decide sirul de conectare, nu fisierul. roafacturare.pj2 regenerat de git_sync. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013gYCNE26G1G7UoGu2ju7aS
This commit is contained in:
229
docs/cercetare/rec_r6_zecimale_si_aspect_grid.md
Normal file
229
docs/cercetare/rec_r6_zecimale_si_aspect_grid.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# R6: zecimale la Pret si aspect gri al campurilor editabile, grid Articole (frm_modific2024)
|
||||
|
||||
Cercetare, fara modificari de cod. Zona: `COMUN\clase\omodificari.vc2`, clasa `frm_modific2024`
|
||||
(liniile 6375-16838), grid-ul de articole al facturii editate: `pgfArticole.PAGE3.grdArticoleFactura`
|
||||
(nu vechiul `Grid1`/`Column1..44` — acela e alt grid, RecordSource `"tACT"`, folosit pentru notele
|
||||
contabile, nu pentru articolele facturii; grid-ul de articole are 16 coloane numite, ADD OBJECT la
|
||||
`omodificari.vc2:12330`).
|
||||
|
||||
## Partea 1 — zecimalele la pret
|
||||
|
||||
### A. Coloanele monetare din grid si masca lor
|
||||
|
||||
RecordSource al grid-ului = cursorul `tvd` (creat in `COMUN\programe\ofacturare_editare.prg:278`,
|
||||
populat in `IncarcaArticoleFactura`, `ofacturare_editare.prg:294-328`, din view-ul Oracle
|
||||
`VVANZARI_ARTICOLE`).
|
||||
|
||||
| Coloana (Header) | Name | ControlSource | Format/InputMask | Linie |
|
||||
|---|---|---|---|---|
|
||||
| Pret | cPretArt | `tvd.pret` | `get_mask(12,gnPPRET)` | `omodificari.vc2:12391` |
|
||||
| Pret achizitie | cPretAchizitieArt | `tvd.pret_achizitie` | `get_mask(12,gnPPRET)` | `omodificari.vc2:12400` |
|
||||
| Pret cu TVA | cPretCuTvaArt | `tvd.pret_cu_tva` | **fara Format/InputMask** | `omodificari.vc2:12404-12409` |
|
||||
| Discount unitar | cDiscountUnitarArt | `tvd.discount_unitar` | `get_mask(12,gnPPRET)` | `omodificari.vc2:12426` |
|
||||
| Cantitate | cCantitateArt | `tvd.cantitate` | `get_mask(12,gnPCANT)` | `omodificari.vc2:12382` |
|
||||
| Valoare | cValoareArt | `tvd.valoare` | `get_mask(14,gnPa)` | `omodificari.vc2:12463` |
|
||||
| TVA % | cProcTvavArt | `tvd.proc_tvav` | `"9.99"` (fix, 2 zecimale) | `omodificari.vc2:12417` |
|
||||
|
||||
Structura cursorului `tvd` (`ofacturare_editare.prg:278-281`):
|
||||
|
||||
```
|
||||
pret N(14,4) NULL, pret_cu_tva N(14,4) NULL, proc_tvav N(6,4) NULL, discount_unitar N(14,4) NULL,
|
||||
..., pret_achizitie N(14,4) NULL, ..., cantitate N(12,3) NULL (nu e in acest citat, vezi mai jos)
|
||||
```
|
||||
|
||||
Precizia campurilor din cursor e **hardcodata** (4 zecimale la pret/pret_cu_tva/discount_unitar/
|
||||
pret_achizitie, 3 la cantitate — vezi linia completa `ofacturare_editare.prg:278`), independent de
|
||||
`gnPPret`/`gnPCant`. Asta e doar plafonul de stocare; ce se AFISEAZA il decide InputMask-ul de pe
|
||||
coloana (cand exista).
|
||||
|
||||
### B. De unde vin cele 3 zecimale afisate la "Pret"
|
||||
|
||||
**Nu dintr-un bug de masca lipsa.** Coloana "Pret" (`cPretArt`, `tvd.pret`) ARE InputMask legat de
|
||||
o variabila globala: `get_mask(12,gnPPRET)`, `omodificari.vc2:12391`. Daca `gnPPRET` = 3 in mediul
|
||||
curent, InputMask-ul produce exact 3 zecimale — comportamentul e "controlat de o variabila globala",
|
||||
exact ce cere utilizatorul. **Problema e ca variabila legata e cea gresita**: `gnPPRET`, nu
|
||||
`gnPPretV` — vezi punctul D.
|
||||
|
||||
### C. Ce este `gnPPret` si care e sablonul consacrat
|
||||
|
||||
`gnPPret` e o variabila PUBLIC incarcata din firma (parametru `OPTIUNI.PPRET`), documentata deja in
|
||||
cercetarea anterioara `docs\cercetare\rec_fact008_pret_achizitie_zecimale.md:28`:
|
||||
|
||||
> `OPTIUNI.PPRET` (precizia pretului de achizitie) = **3** (in mediul de productie investigat acolo)
|
||||
|
||||
N-am gasit in acest proiect linia exacta unde `gnPPret` e citit din `OPTIUNI` si atribuit (cautare
|
||||
in `COMUN\programe\oinit_optiuni.prg` — gaseste `gnPA`, `gnPC`, `gnPCurs`, `gnPPretV`, `gnZ`, dar
|
||||
nu `gnPPret`; probabil incarcat generic, printr-un mecanism care nu foloseste literal sirul
|
||||
`"gnPPret ="`) — **NESTABILIT exact unde**, dar valoarea si semantica (precizie **achizitie**) sunt
|
||||
confirmate atat de raportul anterior cat si de tiparul de folosire de mai jos.
|
||||
|
||||
Exista o familie de variabile de precizie, cu roluri distincte, confirmate prin comentarii si prin
|
||||
folosire consecventa in cod:
|
||||
|
||||
- `gnPPret` — precizie **pret de achizitie** (cost). Folosire: `ofacturare_stoc.prg:364`
|
||||
`Alltrim(Str(poArticol.pret_achizitie,18,Max(gnPPret,4)))`; masti pe `pret_achizitie` in
|
||||
`ointroduceri.vc2:16390,19638` (`get_mask(12,gnPPret)`, coloana NIR).
|
||||
- `gnPPretV` — precizie **pret de vanzare**, comentata explicit
|
||||
`COMUN\programe\oinit_optiuni.prg:515`: `Store 0 To gnPPretV && nr. de zecimale pret vanzare`.
|
||||
Folosire masiva in `ofacturare_comun.prg` (peste 40 de locuri: `pretftva`, `pretctva`,
|
||||
`pretv_orig`, `discountftva` etc. — toate rotunjite/formatate cu `gnPPretV`) si, esential, la
|
||||
**scrierea efectiva a pretului de vanzare al liniei de factura**:
|
||||
`ofacturare_stoc.prg:367` — `Alltrim(Str(poArticol.Pret,18,Iif(poDate.in_valuta=1,gnPVal,gnPPretV)))`
|
||||
(in functia care insereaza randul in `VANZARI_DETALII`, aceeasi coloana `PRET` pe care o incarca
|
||||
`tvd.pret`).
|
||||
- `gnPCant` — precizie cantitate (`get_mask(12,gnPCANT)`, `omodificari.vc2:12382`).
|
||||
- `gnPc` (`gnPC`) — precizie de calcul/valoare (`get_mask(14,gnPa)`/`gnPc` la coloana Valoare).
|
||||
- `gnPa` (`gnPA`) — precizie de afisare generica (folosit la `cValoareArt`).
|
||||
|
||||
Sablonul consacrat de constructie a mastii: `get_mask(nrCaractere, nrZecimale)`
|
||||
(`COMUN\programe\proceduri_comune.prg:1090-1110`) — construieste un sir `"999 999.999"` cu atatea
|
||||
`9` dupa punct cate zecimale i se dau; **nu exista logica speciala in `get_mask`**, deci diferenta
|
||||
de comportament vine strict din CE variabila i se paseaza la fiecare coloana.
|
||||
|
||||
### D. Modelul corect exista deja, in acelasi fisier de clase — `ofacturare.vc2`
|
||||
|
||||
`COMUN\clase\ofacturare.vc2:3489-3498`, grid de rulaje/stoc, doua coloane invecinate:
|
||||
|
||||
```
|
||||
Column5.ControlSource = "pret", ;
|
||||
Column5.InputMask = (get_mask(14,gnPPret)), ; && cost / achizitie
|
||||
Column5.Name = "cPret", ;
|
||||
...
|
||||
Column6.ControlSource = "pretv", ;
|
||||
Column6.InputMask = (get_mask(14,gnPPretV)), ; && vanzare
|
||||
Column6.Name = "cPretv", ;
|
||||
```
|
||||
|
||||
Acelasi tipar apare si in `COMUN\clase\ocomenzi.vc2:1174`
|
||||
(`This._grdrow2.cPret.InputMask = get_mask(14,gnPPretV)` — pret de vanzare pe comanda) si in
|
||||
`ointroduceri.vc2:10071,16390,19638` (`get_mask(...,gnPPret)` — toate pe campuri de **achizitie**,
|
||||
in formularele de NIR).
|
||||
|
||||
**Regula confirmata in tot codul suitei: campul care reprezinta pretul de ACHIZITIE foloseste
|
||||
`gnPPret`; campul care reprezinta pretul de VANZARE al liniei foloseste `gnPPretV`.** Chiar scrierea
|
||||
in Oracle a coloanei `VANZARI_DETALII.PRET` (aceeasi coloana din care se umple `tvd.pret`) respecta
|
||||
aceasta regula: `ofacturare_stoc.prg:367` foloseste `gnPPretV`, nu `gnPPret`.
|
||||
|
||||
### Concluzie Partea 1 — defectul
|
||||
|
||||
`omodificari.vc2:12391` — `Column6.InputMask = (get_mask(12,gnPPRET))` pentru **`cPretArt`**
|
||||
(`tvd.pret`, coloana "Pret" = pretul de VANZARE al liniei) foloseste variabila gresita din familie:
|
||||
**`gnPPRET`** (precizie achizitie) in loc de **`gnPPretV`** (precizie vanzare, cea corecta pentru
|
||||
acest camp). Coloana vecina, `cPretAchizitieArt` (`omodificari.vc2:12400`, `tvd.pret_achizitie`),
|
||||
foloseste corect `gnPPRET` — e evident ca la scrierea acestei sectiuni de grid s-a copiat masca de
|
||||
la achizitie si pe coloana de vanzare de langa ea.
|
||||
|
||||
Daca in mediul reclamat `OPTIUNI.PPRET` (achizitie) = 3 si `OPTIUNI.PPRETV` (vanzare) e alta
|
||||
valoare (tipic 2), exact asta explica simptomul: coloana "Pret" (vanzare) afiseaza 3 zecimale
|
||||
pentru ca "imprumuta" precizia de achizitie, nu pe cea de vanzare.
|
||||
|
||||
Coloana "Pret cu TVA" (`cPretCuTvaArt`) nu are deloc InputMask (`omodificari.vc2:12404-12409`) — nu
|
||||
e sursa celor "3 zecimale" reclamate la "Pret", dar e un defect inrudit: afiseaza precizia bruta a
|
||||
campului din cursor (4 zecimale, `pret_cu_tva N(14,4)`), necontrolata de nicio variabila globala.
|
||||
|
||||
**Schita de interventie** (fara aplicare): `Column6.InputMask = (get_mask(12,gnPPRET))` ->
|
||||
`Column6.InputMask = (get_mask(12,gnPPretV))` la `omodificari.vc2:12391`, dupa modelul din
|
||||
`ofacturare.vc2:3497` / `ocomenzi.vc2:1174`.
|
||||
|
||||
## Partea 2 — fundalul gri al campurilor editabile
|
||||
|
||||
### E-F. Sursa reala a griului si divergenta Column.ReadOnly vs Text1.ReadOnly
|
||||
|
||||
Confirmat: aproape toate coloanele au `DynamicForeColor` (nu `BackColor`) la nivel de coloana —
|
||||
un singur `IIF` pentru culoarea textului dupa `tvd.sters`/`id_vanzare_set`, identic pe toate cele
|
||||
16 coloane (ex. `omodificari.vc2:12350`). **Niciun `DynamicBackColor`, niciun `Enabled=.F.`** pe
|
||||
coloane. Culoarea de fundal reala vine din proprietatea `BackColor` fixa a controlului `Text1`
|
||||
inclus in fiecare coloana (`ADD OBJECT '...Text1' AS textbox`), si **nu coincide cu
|
||||
`Column.ReadOnly`**:
|
||||
|
||||
| Camp | Column.ReadOnly | Column linie | Text1.ReadOnly | Text1.BackColor | Text1 linii |
|
||||
|---|---|---|---|---|---|
|
||||
| Denumire (cDenumireArt) | `.F.` (editabil) | 12354 | **`.T.`** | **225,225,225 (gri)** | 12527-12536 |
|
||||
| Cod material (cCodmatArt) | `.T.` | 12361 | `.T.` | 225,225,225 | 12506-12515 (consistent) |
|
||||
| Serie (cSerieArt) | `.F.` (editabil) | 12368 | **`.T.`** | **225,225,225 (gri)** | 12734-12743 |
|
||||
| Lot (cLotArt) | `.F.` (editabil) | 12375 | **`.T.`** | **225,225,225 (gri)** | 12631-12640 |
|
||||
| Cantitate (cCantitateArt) | `.F.` | 12384 | `.F.` | 255,255,255 (alb) | 12485-12494 (consistent) |
|
||||
| Pret (cPretArt) | `.F.` | 12393 | `.F.` | 255,255,255 (alb) | 12673-12682 (consistent) |
|
||||
| Pret achizitie (cPretAchizitieArt) | `.F.` | 12402 | `.F.` | 255,255,255 (alb) | 12652-12661 (consistent) |
|
||||
| TVA % (cProcTvavArt) | `.F.` (editabil) | 12419 | **`.T.`** | **225,225,225 (gri)** | 12713-12722 |
|
||||
| Discount unitar (cDiscountUnitarArt) | `.T.` | 12428 | `.T.` | 225,225,225 | 12548-12557 (consistent) |
|
||||
| Gestiune (cGestiuneArt) | `.F.` (editabil) | 12435 | **`.T.`** | **225,225,225 (gri)** | 12610-12619 |
|
||||
| Valuta (cValutaArt) | `.F.` (editabil) | 12442 | **`.T.`** | **225,225,225 (gri)** | 12797-12806 |
|
||||
| Explicatie (cExplicatieArt) | `.F.` (editabil) | 12449 | **`.T.`** | **225,225,225 (gri)** | 12569-12578 |
|
||||
| Taxcode (cTaxcodeArt) | `.F.` (editabil) | 12456 | **`.T.`** | **225,225,225 (gri)** | 12755-12764 |
|
||||
| Valoare (cValoareArt) | `.T.` | 12465 | `.T.` | 225,225,225 | 12776-12785 (consistent) |
|
||||
| Explicatie TVA (cExplicatieTvaArt) | `.F.` (editabil) | 12472 | **`.T.`** | **225,225,225 (gri)** | 12589-12598 |
|
||||
|
||||
**9 din 16 coloane sunt declarate editabile la nivel de `Column.ReadOnly=.F.` dar controlul `Text1`
|
||||
inclus e `ReadOnly=.T.` cu fundal gri (225,225,225).** In VFP, cand o coloana de grid contine un
|
||||
control custom (nu editorul implicit), editabilitatea reala vine din controlul inclus, nu din
|
||||
`Column.ReadOnly` — deci aceste 9 campuri **nu accepta tastare directa in celula**, indiferent ce
|
||||
spune `Column.ReadOnly`. Asta explica de ce aratau gri: griul e corect pentru "nu se editeaza prin
|
||||
tastare directa".
|
||||
|
||||
Pentru unele din ele exista insa un mecanism real de editare, prin dialog, nu prin tastare:
|
||||
`cGestiuneArt.Text1.GotFocus` (`omodificari.vc2:12734`... de fapt liniile de cod sunt la
|
||||
`16734-16744`) seteaza `Thisform.pccontrol` si `InteractiveChange` deschide un editor:
|
||||
|
||||
```
|
||||
PROCEDURE pgfArticole.PAGE3.grdArticoleFactura.cGestiuneArt.Text1.InteractiveChange (16739)
|
||||
loEditor = Createobject('ArticoleNotaEditor', Thisform)
|
||||
loEditor.ModificaNomenclator(Thisform.pccontrol)
|
||||
```
|
||||
|
||||
Acelasi tipar la `cExplicatieTvaArt` (`16722-16732`). Pentru `cSerieArt`, `cLotArt`, `cExplicatieArt`
|
||||
exista doar un handler `.When` (`16745`, `16716`, `16804`) care blocheaza intrarea in celula cand
|
||||
`Thisform.lArticoleReadOnly` sau `id_vanzare_set<>0`, dar **niciun cod care sa comute
|
||||
`Text1.ReadOnly` la `.F.`** — n-am gasit nicio atribuire dinamica `.Text1.ReadOnly = ...` in tot
|
||||
corpul clasei `frm_modific2024` pentru aceste coloane (cautare exhaustiva pe intervalul
|
||||
6375-16838). **Concluzie verificabila pe cod**: cu configuratia actuala, `cSerieArt`, `cLotArt`,
|
||||
`cExplicatieArt`, `cValutaArt`, `cTaxcodeArt`, `cDenumireArt`, `cProcTvavArt` **nu au niciun
|
||||
mecanism de editare activ in acest grid** — nici tastare (Text1.ReadOnly=.T.), nici editor prin
|
||||
dublu-clic/InteractiveChange (spre deosebire de cGestiuneArt/cExplicatieTvaArt, care au editor).
|
||||
Daca utilizatorul le percepe ca "editabile", fie testeaza cu date/build vechi, fie editarea se
|
||||
intampla prin alta cale neinventariata aici (buton `but_modificaR` — vezi mai jos, NESTABILIT unde
|
||||
e definit click-ul lui).
|
||||
|
||||
`Thisform.but_modificaR.Enabled` se seteaza in `AfterRowColChange`
|
||||
(`omodificari.vc2:16678-16682`) dupa coloana curenta si `!lArticoleReadOnly`, sugerand un buton
|
||||
extern de "Modifica" — dar **n-am gasit definitia obiectului `but_modificaR` sau handler-ul lui de
|
||||
`Click` in `omodificari.vc2`** (cautare `grep -n "but_modificaR"` in tot fisierul: doar cele 7
|
||||
referinte de mai sus, toate `.Enabled = ...` sau `.Visible = ...`, niciun `ADD OBJECT` sau
|
||||
`PROCEDURE but_modificaR...Click`). **NESTABILIT**: butonul e probabil mostenit dintr-o clasa
|
||||
parinte in afara acestui fisier — nu s-a investigat mai departe (ar necesita cautare in
|
||||
`_frm_base.vcx`/alte `.vc2` din `COMUN\clase`, in afara scopului "aceasta clasa").
|
||||
|
||||
### G. Conventia de culoare in restul aplicatiei
|
||||
|
||||
**Exista o conventie, si e vizibila chiar in acelasi fisier de clasa**, pe pagina "Rulaje"
|
||||
(`pgfArticole.PAGE1.grdRulaje`, alt tab al aceluiasi formular):
|
||||
|
||||
- editabil prin tastare directa: `BackColor = 255,255,255` (alb) + `ReadOnly = .F.` — ex.
|
||||
`cPret.Text1`, `omodificari.vc2:9990-9999`.
|
||||
- editabil prin dialog (GotFocus seteaza `pccontrol`, InteractiveChange deschide editor):
|
||||
`BackColor = 160,255,205` (**verde deschis**) + `ReadOnly = .F.` — ex. `cGest.Text1`
|
||||
(`omodificari.vc2:9689-9698`) si `cDenumire.Text1` (`omodificari.vc2:9595-9604`).
|
||||
- needitabil: `BackColor = 225,225,225` (gri) + `ReadOnly = .T.`.
|
||||
|
||||
Pe pagina "Articole" (`grdArticoleFactura`, PAGE3 — grid-ul reclamat), campul `cGestiuneArt` are
|
||||
**exact acelasi mecanism de editare prin dialog** ca `cGest` de pe pagina Rulaje (acelasi tipar
|
||||
GotFocus/InteractiveChange/`ArticoleNotaEditor`), dar culoarea lui e **gri + ReadOnly=.T.**
|
||||
(`omodificari.vc2:12610-12619`), nu verde + ReadOnly=.F. ca omologul lui de pe Rulaje. **Asta e
|
||||
dovada directa a inconsistentei**: acelasi tipar functional (editare prin editor extern) e codat
|
||||
cu doua culori diferite in doua pagini ale aceluiasi formular — verde (corect, semnaleaza "se
|
||||
editeaza altfel") pe Rulaje, gri (gresit, semnaleaza "nu se editeaza") pe Articole.
|
||||
|
||||
## Rezumatul defectelor gasite (fara aplicare)
|
||||
|
||||
1. **Zecimale**: `Column6.InputMask` la `cPretArt` (`omodificari.vc2:12391`) foloseste `gnPPRET`
|
||||
(precizie achizitie) in loc de `gnPPretV` (precizie vanzare) — schita: schimbat argumentul.
|
||||
2. **Aspect gri**: 9 coloane (`cDenumireArt`, `cSerieArt`, `cLotArt`, `cProcTvavArt`,
|
||||
`cGestiuneArt`, `cValutaArt`, `cExplicatieArt`, `cTaxcodeArt`, `cExplicatieTvaArt`) au
|
||||
`Column.ReadOnly=.F.` dar `Text1.ReadOnly=.T.` + `BackColor=225,225,225` — contrazic propria
|
||||
lor declaratie de editabilitate. Dintre ele, doar `cGestiuneArt` si `cExplicatieTvaArt` au
|
||||
mecanism real de editare (editor extern) si ar trebui colorate verde
|
||||
(`160,255,205`, ca modelul de pe Rulaje) + `ReadOnly=.F.` pe Text1; restul (`cDenumireArt`,
|
||||
`cSerieArt`, `cLotArt`, `cProcTvavArt`, `cValutaArt`, `cExplicatieArt`, `cTaxcodeArt`) fie n-au
|
||||
deloc cale de editare activa in cod (raman corect needitabile — atunci `Column.ReadOnly` ar
|
||||
trebui pus `.T.` ca sa nu mai contrazica aspectul), fie editarea lor se face pe o cale
|
||||
neidentificata in aceasta cercetare (butonul `but_modificaR`, NESTABILIT unde e definit).
|
||||
Reference in New Issue
Block a user