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

10 KiB

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

  1. 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).
  2. 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).
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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).
  8. 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 ("...rn..." 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.