diff --git a/.gitignore b/.gitignore index 967cbec..9799009 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/docs/conventie_encoding_cp1252.md b/docs/conventie_encoding_cp1252.md index 29d16f0..16f5f9c 100644 --- a/docs/conventie_encoding_cp1252.md +++ b/docs/conventie_encoding_cp1252.md @@ -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(".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:.vcx > /tmp/head.vcx - git show HEAD:.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(".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:.vcx > /tmp/head.vcx + git show HEAD:.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). diff --git a/docs/conventie_goexecutor_alter_table.md b/docs/conventie_goexecutor_alter_table.md index 4539b67..937eb33 100644 --- a/docs/conventie_goexecutor_alter_table.md +++ b/docs/conventie_goexecutor_alter_table.md @@ -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()`. diff --git a/docs/conventie_ux_formulare.md b/docs/conventie_ux_formulare.md index fab4f9a..e9e1c92 100644 --- a/docs/conventie_ux_formulare.md +++ b/docs/conventie_ux_formulare.md @@ -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. diff --git a/docs/oracle_export.md b/docs/oracle_export.md index cf864eb..ffe10a8 100644 --- a/docs/oracle_export.md +++ b/docs/oracle_export.md @@ -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/@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/@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ă).