Normalizeaza CRLF in fisierele rescrise constant de SVN (continut identic)

SVN scrie aceste fisiere cu CRLF nativ la fiecare update; blob-urile din git
aveau LF, ceea ce cu .gitattributes (* -text) acum activ producea "modificari"
reale de CRLF/LF dupa fiecare svn update. Alinierea la CRLF (ce scrie de fapt
SVN) elimina divergenta pe viitor. Fara schimbari de continut, doar EOL.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 15:50:52 +03:00
parent b7a538835e
commit fc11f3e99a
5 changed files with 299 additions and 299 deletions

86
.gitignore vendored
View File

@@ -1,43 +1,43 @@
# Visual FoxPro - fisiere compilate
*.fxp
*.mpx
# Visual FoxPro - backup-uri
*.bak
*.BAK
*.TBK
# Visual FoxPro - meniuri generate (din .mnx)
*.mpr
*.MPR
# Visual FoxPro - log-uri si erori
*.ERR
*.err
log.txt
# Visual FoxPro - fisiere temporare
*.tmp
*.TMP
*.dct
*.DCT
# Executabile compilate
*.exe
*.EXE
# SVN (COMUN este si working copy SVN)
.svn/
# Windows
*.lnk
Thumbs.db
Desktop.ini
bash.exe.stackdump
# Setari locale Claude Code (specifice masinii, nu proiectului)
.claude/
# Exporturi surse Oracle (regenerabile cu docs/oracle_export.md, prea mari pentru git)
*.pck
*.PCK
# Visual FoxPro - fisiere compilate
*.fxp
*.mpx
# Visual FoxPro - backup-uri
*.bak
*.BAK
*.TBK
# Visual FoxPro - meniuri generate (din .mnx)
*.mpr
*.MPR
# Visual FoxPro - log-uri si erori
*.ERR
*.err
log.txt
# Visual FoxPro - fisiere temporare
*.tmp
*.TMP
*.dct
*.DCT
# Executabile compilate
*.exe
*.EXE
# SVN (COMUN este si working copy SVN)
.svn/
# Windows
*.lnk
Thumbs.db
Desktop.ini
bash.exe.stackdump
# Setari locale Claude Code (specifice masinii, nu proiectului)
.claude/
# Exporturi surse Oracle (regenerabile cu docs/oracle_export.md, prea mari pentru git)
*.pck
*.PCK

View File

@@ -1,82 +1,82 @@
# Capcană: corupere diacritice la editarea `.sc2`/`.vc2` (encoding cp1252)
Partajat între proiectele ROA* (similar cu `PROMPT_cautare_vfp.md` din acest folder) — capcana
ține de formatul `.sc2`/`.vc2` produs de FoxBin2Prg, nu de un proiect anume.
Descoperit de 2 ori în aceeași sesiune (2026-07-10, în ROAAUTO): odată în
`COMUN/clase/cmd_butoane.vc2` (clasa `cmd_select_adv`), odată în `Clase/ofundal_dev.vc2`
(meniul principal) — de fiecare dată un agent anterior a editat text-cache-ul cu un tool care
nu scrie cp1252 nativ, și a corupt TOATE caracterele cu diacritice din fișier, nu doar linia
pe care voia s-o schimbe.
## De ce se întâmplă
Fișierele `.sc2`/`.vc2` generate de FoxBin2Prg sunt **cp1252 (Windows-1252)**, nu UTF-8
(vezi antetul fiecărui fișier: `CPID="1252"`). Dacă un editor/tool citește fișierul ca UTF-8
(sau alt encoding), fiecare byte >= 0x80 (diacritic) devine invalid ca secvență UTF-8 și e
înlocuit cu caracterul de replacement U+FFFD. Dacă apoi tool-ul **salvează rezultatul tot ca
UTF-8**, acel U+FFFD e scris ca 3 octeți UTF-8 (`0xEF 0xBF 0xBD`) — care, citiți înapoi ca
cp1252 (cum face FoxBin2Prg la write-back), apar ca `�`. Rezultatul: caracterul original e
**ireversibil pierdut** (nu mai există în fișier sub nicio formă) — recuperabil DOAR din altă
sursă (git history, backup).
Codebase-ul ROA folosește un hack vechi de "reciclare" a unor caractere cp1252 needependente
de Ș/ă/ț (care nu au echivalent direct în cp1252) pentru diacritice românești:
| Literă românească | Caracter folosit (cp1252) | Byte |
|---|---|---|
| ă | ã (a-tilde) | `0xE3` |
| Ă | Ã | `0xC3` |
| ț | þ (thorn minuscul) | `0xFE` |
| Ș (majusculă) | ª (ordinal masculin) | `0xAA` |
| ș (minusculă) | º (ordinal feminin) | `0xBA` |
| î, â | î, â (existente nativ în cp1252) | `0xEE`, `0xE2` |
Aceste caractere par "gunoi"/typo la prima vedere într-un editor UTF-8 (`ã`, `þ`, `ª`, `º`) —
**sunt corecte, nu le "corecta" fără să verifici encoding-ul.**
## Cum se verifică dacă un fișier `.sc2`/`.vc2` e corupt
```powershell
$bytes = [System.IO.File]::ReadAllBytes("<path>.vc2")
$text = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
$text -split "`r`n" | Select-String ([char]0xFFFD) # cauta caracterul de replacement
```
Dacă apare `�` (sau `$text` conține U+FFFD) în output — fișierul are corupere de encoding.
## Cum se repară
1. **Nu edita orbește peste corupere** — caracterul original e deja pierdut din fișierul
curent.
2. Dacă fișierul e sub control de versiune (git) și corupera s-a întâmplat **într-o sesiune
anterioară necomisă** (deci HEAD-ul git încă are versiunea curată): recuperează originalul
convertind binarul din HEAD în text și comparând:
```bash
git show HEAD:<cale>.vcx > /tmp/head.vcx
git show HEAD:<cale>.vct > /tmp/head.vct # (sau .VCT, dupa caz)
powershell -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source /tmp/head.vcx -CacheRoot /tmp/head_out
```
apoi decodează ambele fișiere (HEAD curat + curent corupt) ca cp1252 și compară linie cu
linie (PowerShell, nu `diff` direct — `diff`/Bash nu decodează cp1252 corect pentru afișare,
deși detectează totuși diferența de octeți).
3. Reconstruiește fișierul text pornind de la versiunea HEAD (curată), și reaplică DOAR
modificările intenționate din sesiunea curentă peste ea (nu invers — nu încerca să "cârpești"
fișierul corupt caracter cu caracter, e mai sigur să repornești de la baza curată).
4. Scrie rezultatul înapoi ca bytes cp1252 (`[System.Text.Encoding]::GetEncoding(1252).GetBytes(...)`),
NU ca string UTF-8/`Out-File` implicit (care scrie UTF-8 sau UTF-16 după caz).
5. Rulează write-back (`txt2vcx.ps1 -Force`) și verifică fidelity check = zero diferențe.
## Cum se evită pe viitor
Când editezi `.sc2`/`.vc2` cu tool-uri text (Read/Edit/Write), verifică întâi dacă fișierul
conține diacritice (`ã`, `þ`, `ª`, `º`, `î`, `â` etc.) — dacă da, **orice rescrie completă a
fișierului trebuie făcută la nivel de octeți cu encoding cp1252 explicit**, nu presupunând
UTF-8 implicit. Editările punctuale (Edit tool, string replace) sunt sigure DOAR dacă tool-ul
păstrează restul fișierului byte-identic (nu rescrie tot fișierul reîncodat).
## Vezi și
`PROMPT_cautare_vfp.md` din acest folder, pasul 3.c — menționează deja riscul ("Headerul
CPID="1252" poate minți...") pe scurt; acest fișier e detalierea completă (tabel de caractere,
pași de recuperare din git).
# Capcană: corupere diacritice la editarea `.sc2`/`.vc2` (encoding cp1252)
Partajat între proiectele ROA* (similar cu `PROMPT_cautare_vfp.md` din acest folder) — capcana
ține de formatul `.sc2`/`.vc2` produs de FoxBin2Prg, nu de un proiect anume.
Descoperit de 2 ori în aceeași sesiune (2026-07-10, în ROAAUTO): odată în
`COMUN/clase/cmd_butoane.vc2` (clasa `cmd_select_adv`), odată în `Clase/ofundal_dev.vc2`
(meniul principal) — de fiecare dată un agent anterior a editat text-cache-ul cu un tool care
nu scrie cp1252 nativ, și a corupt TOATE caracterele cu diacritice din fișier, nu doar linia
pe care voia s-o schimbe.
## De ce se întâmplă
Fișierele `.sc2`/`.vc2` generate de FoxBin2Prg sunt **cp1252 (Windows-1252)**, nu UTF-8
(vezi antetul fiecărui fișier: `CPID="1252"`). Dacă un editor/tool citește fișierul ca UTF-8
(sau alt encoding), fiecare byte >= 0x80 (diacritic) devine invalid ca secvență UTF-8 și e
înlocuit cu caracterul de replacement U+FFFD. Dacă apoi tool-ul **salvează rezultatul tot ca
UTF-8**, acel U+FFFD e scris ca 3 octeți UTF-8 (`0xEF 0xBF 0xBD`) — care, citiți înapoi ca
cp1252 (cum face FoxBin2Prg la write-back), apar ca `�`. Rezultatul: caracterul original e
**ireversibil pierdut** (nu mai există în fișier sub nicio formă) — recuperabil DOAR din altă
sursă (git history, backup).
Codebase-ul ROA folosește un hack vechi de "reciclare" a unor caractere cp1252 needependente
de Ș/ă/ț (care nu au echivalent direct în cp1252) pentru diacritice românești:
| Literă românească | Caracter folosit (cp1252) | Byte |
|---|---|---|
| ă | ã (a-tilde) | `0xE3` |
| Ă | Ã | `0xC3` |
| ț | þ (thorn minuscul) | `0xFE` |
| Ș (majusculă) | ª (ordinal masculin) | `0xAA` |
| ș (minusculă) | º (ordinal feminin) | `0xBA` |
| î, â | î, â (existente nativ în cp1252) | `0xEE`, `0xE2` |
Aceste caractere par "gunoi"/typo la prima vedere într-un editor UTF-8 (`ã`, `þ`, `ª`, `º`) —
**sunt corecte, nu le "corecta" fără să verifici encoding-ul.**
## Cum se verifică dacă un fișier `.sc2`/`.vc2` e corupt
```powershell
$bytes = [System.IO.File]::ReadAllBytes("<path>.vc2")
$text = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
$text -split "`r`n" | Select-String ([char]0xFFFD) # cauta caracterul de replacement
```
Dacă apare `�` (sau `$text` conține U+FFFD) în output — fișierul are corupere de encoding.
## Cum se repară
1. **Nu edita orbește peste corupere** — caracterul original e deja pierdut din fișierul
curent.
2. Dacă fișierul e sub control de versiune (git) și corupera s-a întâmplat **într-o sesiune
anterioară necomisă** (deci HEAD-ul git încă are versiunea curată): recuperează originalul
convertind binarul din HEAD în text și comparând:
```bash
git show HEAD:<cale>.vcx > /tmp/head.vcx
git show HEAD:<cale>.vct > /tmp/head.vct # (sau .VCT, dupa caz)
powershell -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source /tmp/head.vcx -CacheRoot /tmp/head_out
```
apoi decodează ambele fișiere (HEAD curat + curent corupt) ca cp1252 și compară linie cu
linie (PowerShell, nu `diff` direct — `diff`/Bash nu decodează cp1252 corect pentru afișare,
deși detectează totuși diferența de octeți).
3. Reconstruiește fișierul text pornind de la versiunea HEAD (curată), și reaplică DOAR
modificările intenționate din sesiunea curentă peste ea (nu invers — nu încerca să "cârpești"
fișierul corupt caracter cu caracter, e mai sigur să repornești de la baza curată).
4. Scrie rezultatul înapoi ca bytes cp1252 (`[System.Text.Encoding]::GetEncoding(1252).GetBytes(...)`),
NU ca string UTF-8/`Out-File` implicit (care scrie UTF-8 sau UTF-16 după caz).
5. Rulează write-back (`txt2vcx.ps1 -Force`) și verifică fidelity check = zero diferențe.
## Cum se evită pe viitor
Când editezi `.sc2`/`.vc2` cu tool-uri text (Read/Edit/Write), verifică întâi dacă fișierul
conține diacritice (`ã`, `þ`, `ª`, `º`, `î`, `â` etc.) — dacă da, **orice rescrie completă a
fișierului trebuie făcută la nivel de octeți cu encoding cp1252 explicit**, nu presupunând
UTF-8 implicit. Editările punctuale (Edit tool, string replace) sunt sigure DOAR dacă tool-ul
păstrează restul fișierului byte-identic (nu rescrie tot fișierul reîncodat).
## Vezi și
`PROMPT_cautare_vfp.md` din acest folder, pasul 3.c — menționează deja riscul ("Headerul
CPID="1252" poate minți...") pe scurt; acest fișier e detalierea completă (tabel de caractere,
pași de recuperare din git).

View File

@@ -1,65 +1,65 @@
# Capcană: `ALTER TABLE` pe cursorul întors de `goExecutor.oExecute()`
Partajat între proiectele ROA* — `goExecutor` (clasa `oExecutor`, definită în
`COMUN/programe/oproceduri_comune.prg`, metoda `oExecute`) e utilitarul standard pentru
interogări SQL pass-through (`SQLExec`) către Oracle, folosit peste tot în codul ROA*.
## Ce nu funcționează
```foxpro
lnSucces = goExecutor.oExecute(lcSql, lcCursor)
...
ALTER TABLE (lcCursor) ADD COLUMN coloananoua L && <- pică
```
Cursorul întors de `oExecute()` (rezultatul unui `SQLExec`) poate refuza comenzi DDL
ulterioare, cu erori în lanț (descoperite empiric, în această ordine, în ROAAUTO
`autopass_cursor_comenzi`/`autopass_cursor_operatii`):
1. `Function is not supported on remote tables.` — pe `ALTER TABLE` direct pe cursorul
original.
2. Chiar și după o încercare de rematerializare (`SELECT * FROM (cursor) INTO CURSOR
(acelasi_nume) READWRITE`) → `Alias name is already in use.` (sursa și ținta nu pot
avea același nume într-un `SELECT...INTO CURSOR`).
3. Cu un alias scratch diferit ca țintă (`SELECT * FROM (cursor) INTO CURSOR
(nume_final_diferit_de_sursa) READWRITE`) → tot `Invalid operation for the cursor.` pe
`ALTER TABLE`, chiar dacă acum cursorul final teoretic ar trebui să fie unul local
obișnuit.
Nu există niciun alt loc în codul ROA* care să facă `ALTER TABLE` imediat după
`goExecutor.oExecute()` — deci acest pattern nu avea niciun precedent testat înainte de
funcțiile AUTOPASS.
## Ce funcționează
**Nu folosi `ALTER TABLE` deloc pe rezultatul unui `oExecute()`.** Include coloanele
suplimentare direct în `SELECT`-ul de rematerializare, ca expresii literale alături de `*`
(VFP suportă `SELECT *, expr AS coloana FROM ...`):
```foxpro
lcCursorRaw = lcCursor + '_raw'
IF USED(lcCursorRaw)
USE IN (lcCursorRaw)
ENDIF
lnSucces = goExecutor.oExecute(lcSql, lcCursorRaw)
IF lnSucces < 0
* tratare eroare, RETURN
ENDIF
SELECT *, .F. AS coloananoua, SPACE(100) AS altacoloana ;
FROM (lcCursorRaw) INTO CURSOR (lcCursor) READWRITE
USE IN (lcCursorRaw)
* de-aici incolo doar REPLACE (date), NICIODATA ALTER TABLE (structura) pe (lcCursor)
```
După acest pas, cursorul (`lcCursor`) e un cursor local obișnuit — `ALTER TABLE` funcționează
normal pe el DUPĂ ACEEA (ex. dintr-o altă funcție care primește cursorul deja gata construit,
nu direct rezultatul unui `oExecute`), doar comanda imediat următoare unui `oExecute()` e
restricționată.
## Vezi și
Exemplu complet aplicat: ROAAUTO, `Programe/oproceduri_autopass.prg`,
`autopass_cursor_comenzi()`/`autopass_cursor_operatii()`.
# Capcană: `ALTER TABLE` pe cursorul întors de `goExecutor.oExecute()`
Partajat între proiectele ROA* — `goExecutor` (clasa `oExecutor`, definită în
`COMUN/programe/oproceduri_comune.prg`, metoda `oExecute`) e utilitarul standard pentru
interogări SQL pass-through (`SQLExec`) către Oracle, folosit peste tot în codul ROA*.
## Ce nu funcționează
```foxpro
lnSucces = goExecutor.oExecute(lcSql, lcCursor)
...
ALTER TABLE (lcCursor) ADD COLUMN coloananoua L && <- pică
```
Cursorul întors de `oExecute()` (rezultatul unui `SQLExec`) poate refuza comenzi DDL
ulterioare, cu erori în lanț (descoperite empiric, în această ordine, în ROAAUTO
`autopass_cursor_comenzi`/`autopass_cursor_operatii`):
1. `Function is not supported on remote tables.` — pe `ALTER TABLE` direct pe cursorul
original.
2. Chiar și după o încercare de rematerializare (`SELECT * FROM (cursor) INTO CURSOR
(acelasi_nume) READWRITE`) → `Alias name is already in use.` (sursa și ținta nu pot
avea același nume într-un `SELECT...INTO CURSOR`).
3. Cu un alias scratch diferit ca țintă (`SELECT * FROM (cursor) INTO CURSOR
(nume_final_diferit_de_sursa) READWRITE`) → tot `Invalid operation for the cursor.` pe
`ALTER TABLE`, chiar dacă acum cursorul final teoretic ar trebui să fie unul local
obișnuit.
Nu există niciun alt loc în codul ROA* care să facă `ALTER TABLE` imediat după
`goExecutor.oExecute()` — deci acest pattern nu avea niciun precedent testat înainte de
funcțiile AUTOPASS.
## Ce funcționează
**Nu folosi `ALTER TABLE` deloc pe rezultatul unui `oExecute()`.** Include coloanele
suplimentare direct în `SELECT`-ul de rematerializare, ca expresii literale alături de `*`
(VFP suportă `SELECT *, expr AS coloana FROM ...`):
```foxpro
lcCursorRaw = lcCursor + '_raw'
IF USED(lcCursorRaw)
USE IN (lcCursorRaw)
ENDIF
lnSucces = goExecutor.oExecute(lcSql, lcCursorRaw)
IF lnSucces < 0
* tratare eroare, RETURN
ENDIF
SELECT *, .F. AS coloananoua, SPACE(100) AS altacoloana ;
FROM (lcCursorRaw) INTO CURSOR (lcCursor) READWRITE
USE IN (lcCursorRaw)
* de-aici incolo doar REPLACE (date), NICIODATA ALTER TABLE (structura) pe (lcCursor)
```
După acest pas, cursorul (`lcCursor`) e un cursor local obișnuit — `ALTER TABLE` funcționează
normal pe el DUPĂ ACEEA (ex. dintr-o altă funcție care primește cursorul deja gata construit,
nu direct rezultatul unui `oExecute`), doar comanda imediat următoare unui `oExecute()` e
restricționată.
## Vezi și
Exemplu complet aplicat: ROAAUTO, `Programe/oproceduri_autopass.prg`,
`autopass_cursor_comenzi()`/`autopass_cursor_operatii()`.

View File

@@ -1,48 +1,48 @@
# Convenție UX pentru formulare VFP (preferința lui Marius, valabilă pe toate proiectele ROA*)
Partajat între proiectele ROA* (similar cu `PROMPT_cautare_vfp.md`, `prompt_project_insights_docs.md`
din acest folder) — pentru că `COMUN\` e clonat/sincronizat în fiecare aplicație ROA, e locul
corect pentru o convenție de design care nu ține de un singur proiect.
Origine: confirmat de Marius pe `frm_autopass.scx` (ROAAUTO) după o rundă de regrupare vizuală
(2026-07-10) — "imi place designul acesta" pe layout-ul cu rânduri clar separate pe funcție,
butoane grupate la margini, fără elemente lipite unele de altele.
## Ce înseamnă in practică, pe proprietăți VFP
- **Fiecare grup funcțional pe rândul lui** — nu înghesui controale fără legătură directă pe
același `Top`. Ex: rândul de perioadă (date + Actualizează) separat de rândul de
statistici (Declarabile/Transmise/Blocate), separat de panoul de configurare.
- **Spațiere vizibilă între grupuri, strânsă în interiorul unui grup** — butoane din
aceeași acțiune (ex. Validează dry-run → Transmite → Renunță) la 6-10px unele de altele;
gap de 20-30px față de următorul grup funcțional (ex. Selectează tot vs. grupul
Validare/Transmitere vs. Actualizează statusuri).
- **Butoanele secundare/de configurare aliniate la marginea din dreapta a containerului**,
nu lipite imediat după textbox-ul pe care îl controlează — altfel nu se disting vizual ca
acțiune separată de câmpul de input.
- **Acțiunea principală + oprirea ei alăturate** — un buton de tip "Renunță/Oprește" trebuie
poziționat lângă acțiunea pe care o anulează (ex. Transmite + Renunță), nu împrăștiat în
altă parte a rândului.
- **Un singur rând de acțiuni cât se poate** — dacă mai multe grupuri de butoane încap pe
lățimea formei, preferă un singur rând orizontal în loc să adaugi rânduri noi dedesubt;
păstrează formele compacte pe verticală.
- **Caption-uri scurte, sentence case, nu ALL CAPS** — ex. "Transmite" nu "TRANSMITE";
"Dashboard AutoPass" nu "Deschide dashboard AUTOPASS". ALL CAPS/text lung pe un buton
citește ca zgomot, nu ca ierarhie.
- **Culoare = semnal, nu decor** — folosește culoare distinctă doar pentru acțiuni cu
semnificație clară (verde = acțiune pozitivă/transmite, roșu = oprire/pericol, albastru =
navigare/deschidere link extern); restul butoanelor rămân stilul implicit din `_baza.vcx`.
## Vocabular
Funcțional, compact, aerisit, minimalist, grupat, ușor de înțeles de utilizatori, aer aerisit,
modern — asta e reperul calitativ pentru orice formular nou sau refacere de layout, dincolo de
regulile mecanice de mai sus, pe orice aplicație ROA*.
## Vezi și
- `PROMPT_cautare_vfp.md` din acest folder — cum se caută/editează cod în binarele VFP text-cache
(relevant când aplici aceste reguli prin fluxul `.sc2`/`.vc2` + write-back).
- Capcana de encoding cp1252 la editarea `.sc2`/`.vc2` (corupere diacritice) — documentată în
proiectul unde a fost descoperită (ROAAUTO `docs/conventie_encoding_cp1252.md`); relevantă ori
de câte ori editezi text-cache-ul unui formular/librărie pentru a aplica aceste reguli de UX.
# Convenție UX pentru formulare VFP (preferința lui Marius, valabilă pe toate proiectele ROA*)
Partajat între proiectele ROA* (similar cu `PROMPT_cautare_vfp.md`, `prompt_project_insights_docs.md`
din acest folder) — pentru că `COMUN\` e clonat/sincronizat în fiecare aplicație ROA, e locul
corect pentru o convenție de design care nu ține de un singur proiect.
Origine: confirmat de Marius pe `frm_autopass.scx` (ROAAUTO) după o rundă de regrupare vizuală
(2026-07-10) — "imi place designul acesta" pe layout-ul cu rânduri clar separate pe funcție,
butoane grupate la margini, fără elemente lipite unele de altele.
## Ce înseamnă in practică, pe proprietăți VFP
- **Fiecare grup funcțional pe rândul lui** — nu înghesui controale fără legătură directă pe
același `Top`. Ex: rândul de perioadă (date + Actualizează) separat de rândul de
statistici (Declarabile/Transmise/Blocate), separat de panoul de configurare.
- **Spațiere vizibilă între grupuri, strânsă în interiorul unui grup** — butoane din
aceeași acțiune (ex. Validează dry-run → Transmite → Renunță) la 6-10px unele de altele;
gap de 20-30px față de următorul grup funcțional (ex. Selectează tot vs. grupul
Validare/Transmitere vs. Actualizează statusuri).
- **Butoanele secundare/de configurare aliniate la marginea din dreapta a containerului**,
nu lipite imediat după textbox-ul pe care îl controlează — altfel nu se disting vizual ca
acțiune separată de câmpul de input.
- **Acțiunea principală + oprirea ei alăturate** — un buton de tip "Renunță/Oprește" trebuie
poziționat lângă acțiunea pe care o anulează (ex. Transmite + Renunță), nu împrăștiat în
altă parte a rândului.
- **Un singur rând de acțiuni cât se poate** — dacă mai multe grupuri de butoane încap pe
lățimea formei, preferă un singur rând orizontal în loc să adaugi rânduri noi dedesubt;
păstrează formele compacte pe verticală.
- **Caption-uri scurte, sentence case, nu ALL CAPS** — ex. "Transmite" nu "TRANSMITE";
"Dashboard AutoPass" nu "Deschide dashboard AUTOPASS". ALL CAPS/text lung pe un buton
citește ca zgomot, nu ca ierarhie.
- **Culoare = semnal, nu decor** — folosește culoare distinctă doar pentru acțiuni cu
semnificație clară (verde = acțiune pozitivă/transmite, roșu = oprire/pericol, albastru =
navigare/deschidere link extern); restul butoanelor rămân stilul implicit din `_baza.vcx`.
## Vocabular
Funcțional, compact, aerisit, minimalist, grupat, ușor de înțeles de utilizatori, aer aerisit,
modern — asta e reperul calitativ pentru orice formular nou sau refacere de layout, dincolo de
regulile mecanice de mai sus, pe orice aplicație ROA*.
## Vezi și
- `PROMPT_cautare_vfp.md` din acest folder — cum se caută/editează cod în binarele VFP text-cache
(relevant când aplici aceste reguli prin fluxul `.sc2`/`.vc2` + write-back).
- Capcana de encoding cp1252 la editarea `.sc2`/`.vc2` (corupere diacritice) — documentată în
proiectul unde a fost descoperită (ROAAUTO `docs/conventie_encoding_cp1252.md`); relevantă ori
de câte ori editezi text-cache-ul unui formular/librărie pentru a aplica aceste reguli de UX.

View File

@@ -1,61 +1,61 @@
# Export surse Oracle (PACK_CONTAFIN & co.) — cum se face
`PACK_CONTAFIN.pck` din acest folder este exportul sursei pachetului PL/SQL `PACK_CONTAFIN`.
**Claude Code își face singur exportul/reîmprospătarea** — nu mai e nevoie de export manual din
PL/SQL Developer.
## Conexiune
- Client: `D:\ROA\instantclient_19_18\sqlplus.exe` (`TNS_ADMIN` e deja setat spre același folder).
- Alias TNS: `ROA_CENTRAL``10.0.20.121:1521`, `SERVICE_NAME=ROA` (vezi `tnsnames.ora`).
- Schema/utilizator: `MARIUSM_AUTO` (schema de dezvoltare a lui Marius).
- **Parola nu e versionată** — se află local, în `D:\ROA\ROAGEST\docs\local\oracle.md`
(folder ignorat de git), pe mașina de lucru.
`PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus un sinonim `PUBLIC`.
Exportul de referință se face din `MARIUSM_AUTO`.
## Gotcha sqlplus pe Windows/PowerShell
Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF-16 sparge parserul
(`SP2-0734: unknown command beginning "select..."`). Scrie un fișier `.sql` cu encoding **ASCII**
și rulează-l cu `@fisier.sql`.
## Comanda de export (re-generare .pck)
```sql
-- export_pack.sql
set pagesize 0 linesize 400 trimspool on feedback off heading off termout off
spool D:\ROA\ROAGEST\COMUN\docs\PACK_CONTAFIN.pck
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE' order by line;
select '/' from dual;
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE BODY' order by line;
select '/' from dual;
spool off
exit
```
```powershell
& 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'MARIUSM_AUTO/<parola>@ROA_CENTRAL' '@export_pack.sql'
```
Același tipar merge pentru orice alt pachet/procedură (`PACK_SESIUNE`, `PACK_PRETURI`, …) sau pentru
DDL de tabele/view-uri (`all_tab_columns`, `dbms_metadata.get_ddl`).
## Ce e strict necesar de știut despre PACK_CONTAFIN
Pachetul central de **scriere a documentelor** — clientul VFP populează tabelele temporare
`ACT_TEMP`/`RUL_TEMP` (prin `oscrie_in_fisiere`-ul din COMUN), apoi pachetul distribuie:
- `SCRIE_IN_FISIERE` — orchestratorul (apelat per document).
- `SCRIE_IN_ACT``ACT_TEMP``ACT` (notele contabile).
- `SCRIE_IN_RUL``RUL_TEMP``RUL` (mișcările de stoc); completează `COD`, `DATAORA`, `ID_FACT`
(min. `id_fact` fără conturi 5xx), `ID_SUCURSALA`, `DATAIN`/`DATAOUT` din `dataact`, opțional
`ID_RUL_AUX` pe furnizor (opțiunea de firmă `RULAJFURNIZOR`). **Scrie exact ce e în RUL_TEMP — nu
derivă rulaje din ACT**, deci filtrarea liniilor de rulaj se face în clientul VFP.
- `SCRIE_IN_RUL_OBINV` / `SCRIE_IN_STOC` / `SCRIE_IN_STOC_OBINV` — variantele pentru obiecte de
inventar și actualizarea stocului.
- `VERIFICA_NOTE_CONTABILE`, `SCRIE_JC_2007`/`SCRIE_JV_2007` (jurnale TVA),
`SCRIE_IN_BALANTA(_PARTENERI)`, `sterge_document`, `finalizeaza_document_*`.
- Stare de sesiune prin settere/gettere (`SET_COD`/`GET_COD`, `SET_IDFACT`, `SET_ID_SUCURSALA`, …)
+ `PACK_SESIUNE` (an/lună, opțiuni firmă).
# Export surse Oracle (PACK_CONTAFIN & co.) — cum se face
`PACK_CONTAFIN.pck` din acest folder este exportul sursei pachetului PL/SQL `PACK_CONTAFIN`.
**Claude Code își face singur exportul/reîmprospătarea** — nu mai e nevoie de export manual din
PL/SQL Developer.
## Conexiune
- Client: `D:\ROA\instantclient_19_18\sqlplus.exe` (`TNS_ADMIN` e deja setat spre același folder).
- Alias TNS: `ROA_CENTRAL``10.0.20.121:1521`, `SERVICE_NAME=ROA` (vezi `tnsnames.ora`).
- Schema/utilizator: `MARIUSM_AUTO` (schema de dezvoltare a lui Marius).
- **Parola nu e versionată** — se află local, în `D:\ROA\ROAGEST\docs\local\oracle.md`
(folder ignorat de git), pe mașina de lucru.
`PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus un sinonim `PUBLIC`.
Exportul de referință se face din `MARIUSM_AUTO`.
## Gotcha sqlplus pe Windows/PowerShell
Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF-16 sparge parserul
(`SP2-0734: unknown command beginning "select..."`). Scrie un fișier `.sql` cu encoding **ASCII**
și rulează-l cu `@fisier.sql`.
## Comanda de export (re-generare .pck)
```sql
-- export_pack.sql
set pagesize 0 linesize 400 trimspool on feedback off heading off termout off
spool D:\ROA\ROAGEST\COMUN\docs\PACK_CONTAFIN.pck
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE' order by line;
select '/' from dual;
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE BODY' order by line;
select '/' from dual;
spool off
exit
```
```powershell
& 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'MARIUSM_AUTO/<parola>@ROA_CENTRAL' '@export_pack.sql'
```
Același tipar merge pentru orice alt pachet/procedură (`PACK_SESIUNE`, `PACK_PRETURI`, …) sau pentru
DDL de tabele/view-uri (`all_tab_columns`, `dbms_metadata.get_ddl`).
## Ce e strict necesar de știut despre PACK_CONTAFIN
Pachetul central de **scriere a documentelor** — clientul VFP populează tabelele temporare
`ACT_TEMP`/`RUL_TEMP` (prin `oscrie_in_fisiere`-ul din COMUN), apoi pachetul distribuie:
- `SCRIE_IN_FISIERE` — orchestratorul (apelat per document).
- `SCRIE_IN_ACT``ACT_TEMP``ACT` (notele contabile).
- `SCRIE_IN_RUL``RUL_TEMP``RUL` (mișcările de stoc); completează `COD`, `DATAORA`, `ID_FACT`
(min. `id_fact` fără conturi 5xx), `ID_SUCURSALA`, `DATAIN`/`DATAOUT` din `dataact`, opțional
`ID_RUL_AUX` pe furnizor (opțiunea de firmă `RULAJFURNIZOR`). **Scrie exact ce e în RUL_TEMP — nu
derivă rulaje din ACT**, deci filtrarea liniilor de rulaj se face în clientul VFP.
- `SCRIE_IN_RUL_OBINV` / `SCRIE_IN_STOC` / `SCRIE_IN_STOC_OBINV` — variantele pentru obiecte de
inventar și actualizarea stocului.
- `VERIFICA_NOTE_CONTABILE`, `SCRIE_JC_2007`/`SCRIE_JV_2007` (jurnale TVA),
`SCRIE_IN_BALANTA(_PARTENERI)`, `sterge_document`, `finalizeaza_document_*`.
- Stare de sesiune prin settere/gettere (`SET_COD`/`GET_COD`, `SET_IDFACT`, `SET_ID_SUCURSALA`, …)
+ `PACK_SESIUNE` (an/lună, opțiuni firmă).