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

View File

@@ -1,82 +1,82 @@
# Capcană: corupere diacritice la editarea `.sc2`/`.vc2` (encoding cp1252) # Capcană: corupere diacritice la editarea `.sc2`/`.vc2` (encoding cp1252)
Partajat între proiectele ROA* (similar cu `PROMPT_cautare_vfp.md` din acest folder) — capcana 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. ț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 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` `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 (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 nu scrie cp1252 nativ, și a corupt TOATE caracterele cu diacritice din fișier, nu doar linia
pe care voia s-o schimbe. pe care voia s-o schimbe.
## De ce se întâmplă ## De ce se întâmplă
Fișierele `.sc2`/`.vc2` generate de FoxBin2Prg sunt **cp1252 (Windows-1252)**, nu UTF-8 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 (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 (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 î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 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 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ă **ireversibil pierdut** (nu mai există în fișier sub nicio formă) — recuperabil DOAR din altă
sursă (git history, backup). sursă (git history, backup).
Codebase-ul ROA folosește un hack vechi de "reciclare" a unor caractere cp1252 needependente 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: de Ș/ă/ț (care nu au echivalent direct în cp1252) pentru diacritice românești:
| Literă românească | Caracter folosit (cp1252) | Byte | | Literă românească | Caracter folosit (cp1252) | Byte |
|---|---|---| |---|---|---|
| ă | ã (a-tilde) | `0xE3` | | ă | ã (a-tilde) | `0xE3` |
| Ă | Ã | `0xC3` | | Ă | Ã | `0xC3` |
| ț | þ (thorn minuscul) | `0xFE` | | ț | þ (thorn minuscul) | `0xFE` |
| Ș (majusculă) | ª (ordinal masculin) | `0xAA` | | Ș (majusculă) | ª (ordinal masculin) | `0xAA` |
| ș (minusculă) | º (ordinal feminin) | `0xBA` | | ș (minusculă) | º (ordinal feminin) | `0xBA` |
| î, â | î, â (existente nativ în cp1252) | `0xEE`, `0xE2` | | î, â | î, â (existente nativ în cp1252) | `0xEE`, `0xE2` |
Aceste caractere par "gunoi"/typo la prima vedere într-un editor UTF-8 (`ã`, `þ`, `ª`, `º`) — Aceste caractere par "gunoi"/typo la prima vedere într-un editor UTF-8 (`ã`, `þ`, `ª`, `º`) —
**sunt corecte, nu le "corecta" fără să verifici encoding-ul.** **sunt corecte, nu le "corecta" fără să verifici encoding-ul.**
## Cum se verifică dacă un fișier `.sc2`/`.vc2` e corupt ## Cum se verifică dacă un fișier `.sc2`/`.vc2` e corupt
```powershell ```powershell
$bytes = [System.IO.File]::ReadAllBytes("<path>.vc2") $bytes = [System.IO.File]::ReadAllBytes("<path>.vc2")
$text = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes) $text = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
$text -split "`r`n" | Select-String ([char]0xFFFD) # cauta caracterul de replacement $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. Dacă apare `�` (sau `$text` conține U+FFFD) în output — fișierul are corupere de encoding.
## Cum se repară ## Cum se repară
1. **Nu edita orbește peste corupere** — caracterul original e deja pierdut din fișierul 1. **Nu edita orbește peste corupere** — caracterul original e deja pierdut din fișierul
curent. curent.
2. Dacă fișierul e sub control de versiune (git) și corupera s-a întâmplat **într-o sesiune 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 anterioară necomisă** (deci HEAD-ul git încă are versiunea curată): recuperează originalul
convertind binarul din HEAD în text și comparând: convertind binarul din HEAD în text și comparând:
```bash ```bash
git show HEAD:<cale>.vcx > /tmp/head.vcx git show HEAD:<cale>.vcx > /tmp/head.vcx
git show HEAD:<cale>.vct > /tmp/head.vct # (sau .VCT, dupa caz) 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 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 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, linie (PowerShell, nu `diff` direct — `diff`/Bash nu decodează cp1252 corect pentru afișare,
deși detectează totuși diferența de octeți). 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 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" 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ă). 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(...)`), 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). 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. 5. Rulează write-back (`txt2vcx.ps1 -Force`) și verifică fidelity check = zero diferențe.
## Cum se evită pe viitor ## Cum se evită pe viitor
Când editezi `.sc2`/`.vc2` cu tool-uri text (Read/Edit/Write), verifică întâi dacă fișierul 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 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 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 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). păstrează restul fișierului byte-identic (nu rescrie tot fișierul reîncodat).
## Vezi și ## Vezi și
`PROMPT_cautare_vfp.md` din acest folder, pasul 3.c — menționează deja riscul ("Headerul `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, CPID="1252" poate minți...") pe scurt; acest fișier e detalierea completă (tabel de caractere,
pași de recuperare din git). pași de recuperare din git).

View File

@@ -1,65 +1,65 @@
# Capcană: `ALTER TABLE` pe cursorul întors de `goExecutor.oExecute()` # Capcană: `ALTER TABLE` pe cursorul întors de `goExecutor.oExecute()`
Partajat între proiectele ROA* — `goExecutor` (clasa `oExecutor`, definită în Partajat între proiectele ROA* — `goExecutor` (clasa `oExecutor`, definită în
`COMUN/programe/oproceduri_comune.prg`, metoda `oExecute`) e utilitarul standard pentru `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*. interogări SQL pass-through (`SQLExec`) către Oracle, folosit peste tot în codul ROA*.
## Ce nu funcționează ## Ce nu funcționează
```foxpro ```foxpro
lnSucces = goExecutor.oExecute(lcSql, lcCursor) lnSucces = goExecutor.oExecute(lcSql, lcCursor)
... ...
ALTER TABLE (lcCursor) ADD COLUMN coloananoua L && <- pică ALTER TABLE (lcCursor) ADD COLUMN coloananoua L && <- pică
``` ```
Cursorul întors de `oExecute()` (rezultatul unui `SQLExec`) poate refuza comenzi DDL Cursorul întors de `oExecute()` (rezultatul unui `SQLExec`) poate refuza comenzi DDL
ulterioare, cu erori în lanț (descoperite empiric, în această ordine, în ROAAUTO ulterioare, cu erori în lanț (descoperite empiric, în această ordine, în ROAAUTO
`autopass_cursor_comenzi`/`autopass_cursor_operatii`): `autopass_cursor_comenzi`/`autopass_cursor_operatii`):
1. `Function is not supported on remote tables.` — pe `ALTER TABLE` direct pe cursorul 1. `Function is not supported on remote tables.` — pe `ALTER TABLE` direct pe cursorul
original. original.
2. Chiar și după o încercare de rematerializare (`SELECT * FROM (cursor) INTO CURSOR 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 (acelasi_nume) READWRITE`) → `Alias name is already in use.` (sursa și ținta nu pot
avea același nume într-un `SELECT...INTO CURSOR`). avea același nume într-un `SELECT...INTO CURSOR`).
3. Cu un alias scratch diferit ca țintă (`SELECT * FROM (cursor) 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 (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 `ALTER TABLE`, chiar dacă acum cursorul final teoretic ar trebui să fie unul local
obișnuit. obișnuit.
Nu există niciun alt loc în codul ROA* care să facă `ALTER TABLE` imediat după 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 `goExecutor.oExecute()` — deci acest pattern nu avea niciun precedent testat înainte de
funcțiile AUTOPASS. funcțiile AUTOPASS.
## Ce funcționează ## Ce funcționează
**Nu folosi `ALTER TABLE` deloc pe rezultatul unui `oExecute()`.** Include coloanele **Nu folosi `ALTER TABLE` deloc pe rezultatul unui `oExecute()`.** Include coloanele
suplimentare direct în `SELECT`-ul de rematerializare, ca expresii literale alături de `*` suplimentare direct în `SELECT`-ul de rematerializare, ca expresii literale alături de `*`
(VFP suportă `SELECT *, expr AS coloana FROM ...`): (VFP suportă `SELECT *, expr AS coloana FROM ...`):
```foxpro ```foxpro
lcCursorRaw = lcCursor + '_raw' lcCursorRaw = lcCursor + '_raw'
IF USED(lcCursorRaw) IF USED(lcCursorRaw)
USE IN (lcCursorRaw) USE IN (lcCursorRaw)
ENDIF ENDIF
lnSucces = goExecutor.oExecute(lcSql, lcCursorRaw) lnSucces = goExecutor.oExecute(lcSql, lcCursorRaw)
IF lnSucces < 0 IF lnSucces < 0
* tratare eroare, RETURN * tratare eroare, RETURN
ENDIF ENDIF
SELECT *, .F. AS coloananoua, SPACE(100) AS altacoloana ; SELECT *, .F. AS coloananoua, SPACE(100) AS altacoloana ;
FROM (lcCursorRaw) INTO CURSOR (lcCursor) READWRITE FROM (lcCursorRaw) INTO CURSOR (lcCursor) READWRITE
USE IN (lcCursorRaw) USE IN (lcCursorRaw)
* de-aici incolo doar REPLACE (date), NICIODATA ALTER TABLE (structura) pe (lcCursor) * 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ă 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, 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 nu direct rezultatul unui `oExecute`), doar comanda imediat următoare unui `oExecute()` e
restricționată. restricționată.
## Vezi și ## Vezi și
Exemplu complet aplicat: ROAAUTO, `Programe/oproceduri_autopass.prg`, Exemplu complet aplicat: ROAAUTO, `Programe/oproceduri_autopass.prg`,
`autopass_cursor_comenzi()`/`autopass_cursor_operatii()`. `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*) # 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` 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 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. 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ă 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, (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. butoane grupate la margini, fără elemente lipite unele de altele.
## Ce înseamnă in practică, pe proprietăți VFP ## 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 - **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 același `Top`. Ex: rândul de perioadă (date + Actualizează) separat de rândul de
statistici (Declarabile/Transmise/Blocate), separat de panoul de configurare. statistici (Declarabile/Transmise/Blocate), separat de panoul de configurare.
- **Spațiere vizibilă între grupuri, strânsă în interiorul unui grup** — butoane din - **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; 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 gap de 20-30px față de următorul grup funcțional (ex. Selectează tot vs. grupul
Validare/Transmitere vs. Actualizează statusuri). Validare/Transmitere vs. Actualizează statusuri).
- **Butoanele secundare/de configurare aliniate la marginea din dreapta a containerului**, - **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 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țiune separată de câmpul de input.
- **Acțiunea principală + oprirea ei alăturate** — un buton de tip "Renunță/Oprește" trebuie - **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 poziționat lângă acțiunea pe care o anulează (ex. Transmite + Renunță), nu împrăștiat în
altă parte a rândului. altă parte a rândului.
- **Un singur rând de acțiuni cât se poate** — dacă mai multe grupuri de butoane încap pe - **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; lățimea formei, preferă un singur rând orizontal în loc să adaugi rânduri noi dedesubt;
păstrează formele compacte pe verticală. păstrează formele compacte pe verticală.
- **Caption-uri scurte, sentence case, nu ALL CAPS** — ex. "Transmite" nu "TRANSMITE"; - **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 "Dashboard AutoPass" nu "Deschide dashboard AUTOPASS". ALL CAPS/text lung pe un buton
citește ca zgomot, nu ca ierarhie. citește ca zgomot, nu ca ierarhie.
- **Culoare = semnal, nu decor** — folosește culoare distinctă doar pentru acțiuni cu - **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 = 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`. navigare/deschidere link extern); restul butoanelor rămân stilul implicit din `_baza.vcx`.
## Vocabular ## Vocabular
Funcțional, compact, aerisit, minimalist, grupat, ușor de înțeles de utilizatori, aer aerisit, 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 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*. regulile mecanice de mai sus, pe orice aplicație ROA*.
## Vezi și ## Vezi și
- `PROMPT_cautare_vfp.md` din acest folder — cum se caută/editează cod în binarele VFP text-cache - `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). (relevant când aplici aceste reguli prin fluxul `.sc2`/`.vc2` + write-back).
- Capcana de encoding cp1252 la editarea `.sc2`/`.vc2` (corupere diacritice) — documentată în - 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 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. 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 # Export surse Oracle (PACK_CONTAFIN & co.) — cum se face
`PACK_CONTAFIN.pck` din acest folder este exportul sursei pachetului PL/SQL `PACK_CONTAFIN`. `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 **Claude Code își face singur exportul/reîmprospătarea** — nu mai e nevoie de export manual din
PL/SQL Developer. PL/SQL Developer.
## Conexiune ## Conexiune
- Client: `D:\ROA\instantclient_19_18\sqlplus.exe` (`TNS_ADMIN` e deja setat spre același folder). - 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`). - 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). - 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` - **Parola nu e versionată** — se află local, în `D:\ROA\ROAGEST\docs\local\oracle.md`
(folder ignorat de git), pe mașina de lucru. (folder ignorat de git), pe mașina de lucru.
`PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus un sinonim `PUBLIC`. `PACK_CONTAFIN` există în schemele `MARIUSM_AUTO` (dev) și `ACN`, plus un sinonim `PUBLIC`.
Exportul de referință se face din `MARIUSM_AUTO`. Exportul de referință se face din `MARIUSM_AUTO`.
## Gotcha sqlplus pe Windows/PowerShell ## Gotcha sqlplus pe Windows/PowerShell
Nu trimite SQL prin pipe din PowerShell (`'select...' | sqlplus`) — BOM-ul UTF-16 sparge parserul 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** (`SP2-0734: unknown command beginning "select..."`). Scrie un fișier `.sql` cu encoding **ASCII**
și rulează-l cu `@fisier.sql`. și rulează-l cu `@fisier.sql`.
## Comanda de export (re-generare .pck) ## Comanda de export (re-generare .pck)
```sql ```sql
-- export_pack.sql -- export_pack.sql
set pagesize 0 linesize 400 trimspool on feedback off heading off termout off set pagesize 0 linesize 400 trimspool on feedback off heading off termout off
spool D:\ROA\ROAGEST\COMUN\docs\PACK_CONTAFIN.pck 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 text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE' order by line;
select '/' from dual; select '/' from dual;
select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE BODY' order by line; select text from all_source where owner='MARIUSM_AUTO' and name='PACK_CONTAFIN' and type='PACKAGE BODY' order by line;
select '/' from dual; select '/' from dual;
spool off spool off
exit exit
``` ```
```powershell ```powershell
& 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'MARIUSM_AUTO/<parola>@ROA_CENTRAL' '@export_pack.sql' & '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 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`). DDL de tabele/view-uri (`all_tab_columns`, `dbms_metadata.get_ddl`).
## Ce e strict necesar de știut despre PACK_CONTAFIN ## Ce e strict necesar de știut despre PACK_CONTAFIN
Pachetul central de **scriere a documentelor** — clientul VFP populează tabelele temporare 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: `ACT_TEMP`/`RUL_TEMP` (prin `oscrie_in_fisiere`-ul din COMUN), apoi pachetul distribuie:
- `SCRIE_IN_FISIERE` — orchestratorul (apelat per document). - `SCRIE_IN_FISIERE` — orchestratorul (apelat per document).
- `SCRIE_IN_ACT``ACT_TEMP``ACT` (notele contabile). - `SCRIE_IN_ACT``ACT_TEMP``ACT` (notele contabile).
- `SCRIE_IN_RUL``RUL_TEMP``RUL` (mișcările de stoc); completează `COD`, `DATAORA`, `ID_FACT` - `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 (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 `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. 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 - `SCRIE_IN_RUL_OBINV` / `SCRIE_IN_STOC` / `SCRIE_IN_STOC_OBINV` — variantele pentru obiecte de
inventar și actualizarea stocului. inventar și actualizarea stocului.
- `VERIFICA_NOTE_CONTABILE`, `SCRIE_JC_2007`/`SCRIE_JV_2007` (jurnale TVA), - `VERIFICA_NOTE_CONTABILE`, `SCRIE_JC_2007`/`SCRIE_JV_2007` (jurnale TVA),
`SCRIE_IN_BALANTA(_PARTENERI)`, `sterge_document`, `finalizeaza_document_*`. `SCRIE_IN_BALANTA(_PARTENERI)`, `sterge_document`, `finalizeaza_document_*`.
- Stare de sesiune prin settere/gettere (`SET_COD`/`GET_COD`, `SET_IDFACT`, `SET_ID_SUCURSALA`, …) - Stare de sesiune prin settere/gettere (`SET_COD`/`GET_COD`, `SET_IDFACT`, `SET_ID_SUCURSALA`, …)
+ `PACK_SESIUNE` (an/lună, opțiuni firmă). + `PACK_SESIUNE` (an/lună, opțiuni firmă).