Files
comun/docs/flux-editare-vfp-text.md
Marius Mutu 940bb39701 Import eFactura in lot: borderou cu ce lipseste, coada de contabilizare, alegerea contului
Borderoul tine per factura ce mai are de completat si daca are articole de gestiune
(camp gest, coloana si filtru), coada contabilizeaza in serie facturile bifate si
incheie cu un rezumat, iar contul de furnizor/client se alege din planul de conturi.
Cheia normalizata de articol, rezolvarea automata a partenerului si anularea in bloc
intra tot aici. Pozitia in lista se pastreaza peste reaplicarea filtrului.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aroafxp4z8bmM5oVECZRXY
2026-09-09 22:06:48 +03:00

147 lines
10 KiB
Markdown

# Flux editare .vcx/.scx pe text (comun proiectelor VFP)
Textul .vc2/.sc2 e sursa de editare; write-back in binar cu `txt2vcx.ps1`, fara VFP IDE.
Detalii complete: `D:\ROA\UTIL\foxbin2prg\CLAUDE.md`. Parametrii per proiect (nemigrate):
`cautare_vcx_vct.md`.
**Proiecte migrate (ROACONT, COMUN, …): flux in-arbore.** Textul .??2 sta langa binare, il
improspateaza `git_sync.ps1 -ProjectRoot <root>` (nu cache extern) — la inceput de sesiune si
inainte de orice `git commit`. Write-back doar pentru vcx/scx; `frx/mnx/lbx/pjx/dbc/dbf` doar
in IDE. `txt2vcx.ps1` cu `-CacheRoot` = `-ProjectRoot` (implicit). Pasul 0 de mai jos devine
rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vcx2txt.ps1` +
`-CacheRoot` separat) ramane doar pentru proiectele nemigrate.
**Capcana: `git_sync.ps1` cu `-ProjectRoot` pe COMUN direct.** Lista implicita
`-RoundtripExempt` are cai de forma `COMUN\clase\<f>.vcx` (raportate la radacina unei aplicatii,
unde COMUN e subfolder) si se lipeste de `-ProjectRoot`. Cand radacina E chiar COMUN, caile nu
mai potrivesc si clasele scutite (FFC/third-party cu `#INCLUDE`, ex. `oinventar.vcx`) raporteaza
fals `roundtrip text1 != text2`. Ruleaza atunci cu lista rebazata:
`git_sync.ps1 -ProjectRoot 'D:\ROA\ROAGEST\COMUN' -RoundtripExempt @('clase\accessibility.vcx',
'clase\oinventar.vcx','clase\_gdiplus.vcx','clase\_reportlistener.vcx',
'utile\foxcharts\foxcharts.vcx','utile\web\_webview.vcx')` - si apeleaza scriptul cu `&`, nu cu
`powershell -File` (acolo lista nu se leaga ca array).
## Invariante — se verifica la FIECARE editare, inainte de write-back
1. **Membru nou de clasa (proprietate SAU metoda) are intrare in `*<DefinedPropArrayMethod>`**:
`*p: nume` / `*m: nume`. Sectiunea "Membri noi de clasa" mai jos.
2. **Ordinea alfabetica FoxBin2Prg**: `_` vine DUPA litere, nu inainte (ASCII). Ordinea canonica se
citeste din `<staging>\verify\*.vc2`, nu se deduce.
3. **CRLF, zero LF izolati**:
`perl -e 'local $/; open F,"<:raw",$ARGV[0]; $d=<F>; $crlf=()=$d=~/\r\n/g; $lf=()=$d=~/\n/g; print $lf-$crlf' <fisier>`
trebuie sa dea 0.
4. **Cens de octeti >= 0x80 identic** cu cel de dinainte de editare:
`od -An -tx1 <fisier> | tr ' ' '\n' | grep -v '^$' | awk '$1>"7f"' | sort | uniq -c`
(detalii: `conventie_encoding_cp1252.md`).
**Nici fidelity-check-ul, nici `-DryRun` nu acopera punctele 1, 3 si 4** — trec cu OK peste toate
trei. Sunt verificari separate, de facut de mana.
## Membri noi de clasa: `*p:` / `*m:`
Orice proprietate sau metoda NOUA cere, pe langa valoarea din `*<PropValue>` / corpul `PROCEDURE`,
o intrare in blocul `*<DefinedPropArrayMethod>` al clasei: `*p: nume` pentru proprietate, `*m: nume`
pentru metoda. Override-urile de metode mostenite (Init, Show, hook-uri) NU au nevoie de `*m:`.
Fara acea intrare, esecul e tacut in patru pasi:
1. textul se scrie si `txt2vcx.ps1` **trece fidelity-check-ul** — fidelity compara text-sursa cu
text-regenerat, deci nu are cum sa observe lipsa; binarul primeste valoarea/corpul ca text;
2. VFP nu materializeaza membrul pe obiect: `PEMSTATUS(o,'nume',5)` da `.F.`, iar accesul cade cu
eroarea 1734 "Property ... is not found" (proprietate) sau "Data type mismatch" la
`Createobject` (metoda). Dovedit in ambele sensuri pe o clasa de proba izolata;
3. **prima salvare din IDE-ul VFP peste acel binar sterge tacit membrul** — la metode raman doar
corpurile `PROCEDURE` orfane, la proprietati dispare si valoarea;
4. urmatorul `git_sync` regenereaza textul din binarul deja ciuntit, deci pierderea intra si in
`.??2`, si in backup-urile de runda.
Pasul 3 loveste si definitii `*m:` **deja existente si corecte** (patit pe ROAGEST:
`import_adauga_factura.recalc_tva`, `import_nota.do_adauga/do_copie/do_reface`; simptom: crash la
`Createobject` cu "Data type mismatch" raportat la linia apelanta). Deci dupa ORICE sesiune IDE pe
o clasa atinsa: `git_sync` + compara lista `*p:`/`*m:` cu starea de dinainte.
**`Column` nu are `When`, `Valid` sau `Click`** - apartin controlului din coloana (masurat:
`PEMSTATUS(grid.Column1,'When',5)` da `.F.`, pe `Column1.Text1` da `.T.`). O
`PROCEDURE <grid>.<coloana>.When` scrisa in text ajunge in binar si chiar ruleaza, dar prima
salvare din IDE o sterge tacit, ca la pasul 3. Se scrie pe `CurrentControl`-ul coloanei:
`<grid>.<coloana>.<control>.When`.
Verificare inainte de write-back: `grep -n '\*[pm]: <nume>' <fisier>.vc2`.
Pozitia in fisier nu e libera — FoxBin2Prg regenereaza membrul la pozitia lui alfabetica din
`*<DefinedPropArrayMethod>` (cu `_` dupa litere); o intrare sau o metoda scrisa in alta parte pica
fidelity-check-ul. Sursa de adevar pentru ordine si pozitie: textul din `<staging>\verify\*.vc2`.
## Pasii unei runde
0. Refresh text (obligatoriu la inceput de sesiune si dupa orice sesiune IDE — staleness pe
mtime): `git_sync.ps1 -ProjectRoot <root>` (proiecte nemigrate: `vcx2txt.ps1 -Project <pjx>
-ProjectRoot <root> -CacheRoot <cache> -Types vcx,scx`).
1. Baseline: `Copy-Item <f>.vc2 <f>.vc2.pre_runda<N>.bak` (langa binar, in arbore; la runde
succesive necomise, diff-ul fata de HEAD ar amesteca rundele).
2. Editare byte-safe: PowerShell `[IO.File]::ReadAllText/WriteAllText(..., GetEncoding(1252))` -
doar pentru round-trip pe octeti, NU pentru retastat literal diacritice (antetul zice
`CPID="1252"`, dar octetii diacriticelor sunt de fapt cp1250: `conventie_encoding_cp1252.md`).
NU tool-ul Edit/Write (UTF-8 strica diacriticele). Continut nou ASCII, TAB-uri ca in jur,
fara reflow (format position-sensitive, proprietati alfabetizate). Valabil si pentru `.prg`.
3. Patch review: `git diff --no-index <bak> <editat> > docs/diff_runda<N>_<subiect>.patch`
(exit 1 = normal). Utilizatorul revizuieste FISIERUL de patch si aproba — aprobarea
conditioneaza COMMIT-ul, nu write-back-ul: pasii 5 si 6 se fac imediat, fara sa astepti
raspunsul (si pe `COMUN`), ca review-ul sa primeasca rezultate de test, nu o propunere
netestata. Rollback daca patch-ul e respins sau modificarea nu merge: `git checkout` pe
binare (`.vcx`+`.vct`) sau write-back din `*.pre_runda<N>.bak`.
Comentariile in cod: conventia din `reguli_lucru.md` (punctul 2).
Obligatoriu inainte de a preda patch-ul la review: skill-ul de code-review rulat pe bucatile
de cod din diff (nu doar citire manuala) - prinde defecte gen IIF cu numar gresit de
argumente, deduplicari care nu se declanseaza niciodata, interogari mai largi decat e nevoie.
Review-ul verifica si compactitatea/reutilizarea: cod care refoloseste functiile si clasele
comune existente in loc sa le reinventeze (ex. cursor2lista()/cursor2listac() pentru liste
dintr-un cursor in loc de Scan manual; butoane din cmd_butoane.vcx in loc de butoane ad-hoc).
Inventarul comunelor: COMUN\docs\inventar-comun.md - se consulta si la pasul de plan/arhitectura,
inainte de a scrie cod nou.
4. Preconditie write-back: binarul tinta sa nu fie blocat. `txt2vcx.ps1` verifica singur
(`Test-ExclusiveAccess` pe `.vcx`+`.vct`) si refuza cu mesaj clar daca e lock. NU conteaza
existenta altor instante `vfp9` — utilizatorul poate lucra in paralel in alt proiect VFP —
si NU se omoara procese: cand lock-ul exista, se cere utilizatorului sa inchida sesiunea.
5. Write-back: `txt2vcx.ps1 -TextFile <vc2> -ProjectRoot <root>` (`-CacheRoot` implicit =
`-ProjectRoot`; pentru proiecte nemigrate cu cache separat, paseaza-l explicit)
(+ `-AllowComun` pentru tinte COMUN — afecteaza toate aplicatiile ROA, deci schimbarea in sine
se propune explicit, dar write-back-ul local nu asteapta aprobarea; nimic nu pleaca la celelalte
aplicatii pana la commit+push).
Succes = fidelity-check trecut: binar cu mtime nou; `vcx2txt.ps1` ulterior il vede la zi.
6. Teste finale pe cerinta initiala (cerinta Marius, valabila in toate proiectele VFP):
dupa ultima runda, teste e2e (harness UI, pe fluxul real al utilizatorului) care verifica
ca rezultatul construit *arata si se comporta* conform cerintei initiale — scenariul concret
dat de Marius, cu valorile lui asteptate — nu doar teste per-fix. Assert-uri pe continutul
rezultatului (sume, campuri, randuri), nu pe efecte de suprafata ("a aparut un rand" nu e
suficient).
7. Curatenie dupa commit (backup-uri `.pre_runda*.bak`, patch-uri, artefacte de test):
`powershell -File COMUN\utile\curatenie.ps1` — vezi regula 1 din `reguli_lucru.md`.
## Capcane
- `.mnx`/`.frx` raman read-only (GENMENU in IDE / round-trip fragil).
- Linii complet goale in metode pica fidelity doar pe whitespace; fix: preia `verify\*.vc2`
din staging peste cache si reia write-back-ul.
- Nu folosi *Project > Build* ca sa recompilezi un binar vizat: rebuild-ul recompileaza toate
`.vcx`/`.vct` din proiect si le rescrie antetul (timestamp compilare) si posibil p-code-ul
intern si la librarii neatinse efectiv, aparand fals ca "modificate" in diff — de aici
fluxul text->bin punctual pe binarul vizat.
- Subagentii delegati primesc regulile 2-5 in prompt si raporteaza unicitatea sirurilor
inlocuite + rezultatul fidelity-check-ului.
- Fisierele `.vc2`/`.sc2` sunt CRLF, dar here-string-urile PowerShell (`"...`r`n..."` sau
`@"..."@`) produc LF simplu pe orice linie noua inserata daca nu incluzi explicit `` `r`n ``
la fiecare capat de linie - rezultatul e un fisier cu sfarsituri de linie amestecate (CRLF pe
continutul vechi, LF pe cel nou). Verificare finala obligatorie dupa orice scriere: numara
octetii `0x0A` neprecedati de `0x0D` (LF izolati) - trebuie sa fie 0.
- **`-DryRun` NU e plasa de siguranta pentru capete de linie** - fidelity-check-ul compara doar
continutul text, nu CRLF vs LF, deci un fisier convertit integral la LF de un tool Edit/Write
(patit si cumulat, pe mai multe runde succesive) trece cu OK/EXITCODE=0. Verificare separata,
obligatorie dupa fiecare editare, langa censul de octeti non-ASCII deja documentat mai sus:
`perl -e 'local $/; open F,"<:raw",$ARGV[0]; $d=<F>; $crlf=()=$d=~/\r\n/g; $lf=()=$d=~/\n/g; print $lf-$crlf' <fisier>`
trebuie sa dea 0. Semnal secundar: daca `git diff --numstat` arata brusc tot fisierul schimbat
(nu doar liniile atinse), capetele de linie sunt gresite. Reparare (doar dupa ce ai confirmat ca
fisierul n-are deja niciun `\r`): `perl -pe 's/\n/\r\n/' < f > f.tmp`.
- `txt2vcx.ps1` si `vfp_symbols.ps1` fara `-ProjectRoot`/`-CacheRoot` explicit cad pe default-ul lor,
care arata spre `ROAACNPRO` - pe alt proiect esueaza cu "Cannot find path" sau, mai rau, citesc alt
arbore. Paseaza-le mereu explicit, si in prompturile subagentilor.