Achizitie import unificata (ROAGEST): ointroduceri, teste UI, documentatie
- import_nota / import_adauga_factura: flux unificat note contabile + articole, sincronizare automata, total factura automat, TVA impartit pe conturile creditoare ale notelor (rundele 1-31) - runda 32: totalurile import_nota pe _label/_textbox din _baza.vcx (Arial 10), fara containerele clb_tx_simplu si fara bifa "Recalculeaza TVA" (recalcul mereu automat); "Sincronizeaza facturile secundare" mutata sub butoane - utile/Teste: harness UI VFP headless (vfp_ui_harness.ps1, ui_harness.prg, precompilare, mock-uri) in radacina; suitele e2e pentru achizitia din import grupate in utile/Teste/achizitie_import/ - docs: flux editare text vcx/scx, testare-ui-vfp si testare-vfp-mcp (mutate din ROAGEST, general valabile), inventar comun, orchestrare subagenti, conventie GO recno, depanare testare VFP Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019DGibQKa5uK4P2TNSFFQNh
This commit is contained in:
15
docs/conventie_go_recno.md
Normal file
15
docs/conventie_go_recno.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Conventie: GO pe Recno() capturat
|
||||
|
||||
`SELECT-SQL ... FROM cursor` lasa pointerul cursorului sursa pe EOF, deci un `Recno()` capturat dupa aceea poate fi `Reccount()+1` -> `GO` da "Record is out of range".
|
||||
|
||||
Regula: nu folosi `GO` direct pe un recno primit ca parametru sau capturat anterior; impacheteaza-l:
|
||||
|
||||
```foxpro
|
||||
TRY
|
||||
GO tnRecNo
|
||||
CATCH
|
||||
GO TOP
|
||||
ENDTRY
|
||||
```
|
||||
|
||||
Preferabil, unde exista cheie de rand (ex. doc_key): repozitionare prin `LOCATE` pe cheie in loc de recno absolut.
|
||||
@@ -18,6 +18,9 @@ max o linie, modificari minime).
|
||||
- `COMUN\utile\Teste\test_repro_cnrcrt_footer.prg` - exemplu complet de harness:
|
||||
init mediu -> replicare flux (cursoarele din modificanote) -> instantiere forma reala ->
|
||||
executie pas cu pas cu logare -> verdict OK/BUG. Copiaza-i structura pentru bug-uri noi.
|
||||
- `COMUN\utile\Teste\test_repro_import_nota.prg` - harness instantiere import_nota
|
||||
(ROAGEST) fara Oracle: cursori dummy + goExecutor dummy; parametrul LPARAMETERS
|
||||
incarca o copie de clasa din scratchpad in loc de cea reala (bisectie A/B).
|
||||
- `COMUN\utile\Teste\teste_roacont.prg` si `COMUN\utile\Teste\test.prg` - teste ad hoc istorice.
|
||||
- Mediu de test standard: server `CENTRAL`, schema `MARIUSM_AUTO`, parola schemei
|
||||
`ROMFASTSOFT`; utilizator de aplicatie "MARIUS M" / parola "123" (unde e nevoie de login).
|
||||
@@ -76,6 +79,15 @@ Cand un bug apare "de azi", compara comportamentul cu clasa veche fara a atinge
|
||||
4. cand difera rezultatul, cauza e in diff-ul acelei clase (sau intr-un defect latent
|
||||
pe care noul cod il activeaza - vezi capcanele de mai jos).
|
||||
|
||||
Varianta pe backup-uri de runda (fara git): copiaza `*.vc2.pre_rundaN.bak` din cache
|
||||
intr-un folder temp ca `ointroduceri.vc2`, regenereaza binarul direct cu
|
||||
`FoxBin2Prg.EXE "<temp>\fisier.vc2" "" "" "" 1 0 1` (pune `..\include\foxpro.h` langa,
|
||||
altfel .ERR), apoi in harness incarca DOAR copia (nu ADDITIVE peste cea reala -
|
||||
rezolvarea intre doua classlib-uri cu aceeasi clasa nu e garantata => fals negativ).
|
||||
Bisectie in interiorul unei runde: neutralizeaza valori IN LOC (ControlSource ->
|
||||
camp simplu, sterge linii de proprietate din mijlocul blocului) - NU sterge
|
||||
obiecte/coloane din ADD OBJECT (strica structura: "Cannot add this object to a Grid").
|
||||
|
||||
## 5. Capcane VFP descoperite (de verificat la bug-uri asemanatoare)
|
||||
|
||||
- `SELECT ... INTO CURSOR` NU mosteneste indecsii cursorului sursa. Orice
|
||||
@@ -93,8 +105,64 @@ Cand un bug apare "de azi", compara comportamentul cu clasa veche fara a atinge
|
||||
- Fix-ul unui typo intr-o clasa partajata poate activa defecte latente in aval
|
||||
(codul care nu rulase niciodata incepe sa ruleze). La regresii dupa fix-uri
|
||||
"inofensive" in COMUN, cauta defectul latent, nu doar diff-ul.
|
||||
- **Coloana de grid cu ControlSource EXPRESIE (nu camp) cere `Bound = .F.`**.
|
||||
Fara el: eroare 9 "Data type mismatch" la CREATEOBJECT-ul formei (faza de
|
||||
constructie, raportata la linia apelanta, Details gol). Caz: import_nota.GridArt
|
||||
Column7/8/9 cu `round(...)` (ROAGEST 16.07.2026); model corect: Grid1.cTaxCode
|
||||
(`Bound = .F.` + expresie, functional de ani).
|
||||
|
||||
## 6. Studiu de caz: "Property CNRCRT is not found" (15.07.2026)
|
||||
## 6. Capcane la SCRIEREA scriptului de test (nu ale bug-ului investigat)
|
||||
|
||||
Descoperite depanand harness-ul pentru "Data type mismatch" la `CREATEOBJECT('IMPORT_nota',...)`
|
||||
(ROAGEST, 16.07.2026) - de verificat oricand un script de test nou pare "agatat".
|
||||
|
||||
- **`DEFINE CLASS ... ENDDEFINE` NU poate sta la mijlocul programului principal.**
|
||||
Daca il pui intre alte instructiuni de top-level (ex. clasa dummy pentru un
|
||||
`goExecutor` de test, definita devreme "ca sa fie la indemana"), VFP compileaza
|
||||
gresit: TOATE liniile de DUPA `ENDDEFINE` dau "Statement is not in a procedure"
|
||||
(vezi `<script>.ERR` generat la compilare). Simptom in productie: `vfp9.exe`
|
||||
pare agatat la nesfarsit - CPU ~0, nicio fereastra de dialog vizibila (verificat
|
||||
si prin enumerare Win32 a ferestrelor procesului), pentru ca de fapt a rulat
|
||||
doar liniile de dinaintea `DEFINE CLASS` si s-a oprit silentios dupa eroarea de
|
||||
compilare, fara sa ajunga la `QUIT`. Fix: muta orice `DEFINE CLASS` auxiliar
|
||||
(dummy executor, helpere) la FINALUL fisierului, dupa `QUIT`, langa celelalte
|
||||
`PROCEDURE` - e locul standard pentru cod suport intr-un script de test.
|
||||
- **Diagnostic rapid compilare vs blocaj real**: cand un script "nu se termina",
|
||||
verifica INTAI daca a aparut `<script>.ERR` langa `.prg` (log de compilare,
|
||||
vezi si `roagest.ERR`/`log.txt` in radacina proiectului) - inseamna ca s-a
|
||||
oprit la compilare, nu ca ruleaza/asteapta ceva. Daca nu exista `.ERR`, verifica
|
||||
CPU-ul procesului (`Get-Process | select CPU`): ~0 dupa cateva secunde inseamna
|
||||
ca asteapta un dialog modal (foloseste enumerarea Win32 de ferestre de mai jos
|
||||
ca sa confirmi), nu ca proceseaza ceva lent.
|
||||
- **Enumerare ferestre Win32 pentru un proces "agatat"** (utila cand nu esti sigur
|
||||
daca exista un dialog modal ascuns): `Add-Type` cu `EnumWindows`/`GetWindowText`/
|
||||
`GetWindowThreadProcessId` din `user32.dll`, filtrat pe PID-ul lui `vfp9.exe`.
|
||||
Daca vezi doar fereastra principala + "Command", nu e dialog - cauta alta cauza
|
||||
(vezi punctul de mai sus).
|
||||
- **`STRTOFILE` inainte de `SET SAFETY OFF` = dialog modal "Overwrite?"** daca
|
||||
fisierul de log exista deja (sub `-A`, SAFETY porneste ON). Pune `SET SAFETY OFF`
|
||||
PRIMA linie sau sterge log-ul inainte de fiecare rulare.
|
||||
- **`-A -T` sunt obligatorii impreuna** la lansare headless (`-A` ignora config.fpw,
|
||||
`-T` sare peste splash screen-ul de start) - fara `-T` procesul ramane agatat pe
|
||||
ecranul de intampinare, identic ca simptom cu o eroare de compilare (CPU ~0,
|
||||
fara log). Confirma mereu care e cauza inainte de a schimba scriptul.
|
||||
- **`goExecutor`/alte dependinte "dummy"**: `CREATEOBJECT('Custom')` + `AddProperty()`
|
||||
poate adauga doar PROPRIETATI, nu METODE. Daca clasa testata apeleaza
|
||||
`goExecutor.oExecute(...)`/`oExecuta(...)`, dummy-ul trebuie sa fie o clasa
|
||||
proprie (`DEFINE CLASS dummyexecutor AS Custom` cu `PROCEDURE oExecute`/
|
||||
`oExecuta` reale), nu un `Custom` cu proprietati adaugate.
|
||||
- **Erorile de instantiere (`CREATEOBJECT`) raportate la linia CREATEOBJECT, nu la
|
||||
`.Init`**: cand `ON ERROR`/`CATCH` arata `Procedure` = scriptul apelant (nu
|
||||
`NUMECLASA.INIT`), inseamna ca eroarea vine din evaluarea proprietatilor/
|
||||
obiectelor din DEFINITIA clasei (`ADD OBJECT ... WITH RowSource = ...`,
|
||||
`ControlSource` de coloana grid evaluat ca expresie, etc.) - controale native
|
||||
VFP (ex. combobox cu `RowSourceType=6` Fields) isi rezolva bind-ul la
|
||||
CONSTRUCTIE, inainte sa apuce sa ruleze `PROCEDURE Init` a formei. Cand
|
||||
reproduci un astfel de bug cu un mediu minimal, o "Alias is not found" pe un
|
||||
cursor pe care nu l-ai deschis tu confirma mecanismul (faza de instantiere),
|
||||
chiar daca nu e mesajul EXACT din bug-ul original.
|
||||
|
||||
## 7. Studiu de caz: "Property CNRCRT is not found" (15.07.2026)
|
||||
|
||||
Lant complet: `frm_import_extrase_banca.modificanote` copia `crsJTVATemp` fara index
|
||||
(defect latent) -> coloana `cExplicatieTVA` din `frm_modific2024.grdRulaje` face
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 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: in `docs\` proiectului.
|
||||
Detalii complete: `D:\ROA\UTIL\foxbin2prg\CLAUDE.md`. Parametrii per proiect: sectiunea de mai jos.
|
||||
|
||||
**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
|
||||
@@ -10,6 +10,12 @@ in IDE. `txt2vcx.ps1` cu `-CacheRoot` = `-ProjectRoot` (implicit). Pasul 0 de ma
|
||||
rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vcx2txt.ps1` +
|
||||
`-CacheRoot` separat) ramane doar pentru proiectele nemigrate.
|
||||
|
||||
## Parametri per proiect (nemigrate, cache extern)
|
||||
|
||||
- **ROAGEST**: `-Project 'D:\ROA\ROAGEST\roagest.pjx' -ProjectRoot 'D:\ROA\ROAGEST'
|
||||
-CacheRoot 'D:\ROA\_vfp_textcache\roagest'`; procese de verificat inainte de write-back:
|
||||
`vfp9`, `roagest`; patch-uri de review in `docs/diff_runda<N>_<subiect>.patch`.
|
||||
|
||||
## Pasii unei runde
|
||||
|
||||
0. Refresh cache (obligatoriu dupa orice sesiune IDE — staleness pe mtime):
|
||||
@@ -23,11 +29,25 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
|
||||
(exit 1 = normal). Utilizatorul revizuieste FISIERUL de patch si aproba; write-back-ul
|
||||
(pasul 5) se face DOAR dupa aprobare. Commit doar dupa confirmare pe patch + test in IDE.
|
||||
Comentariile in cod: maxim o linie (`*!* DD.MM.YYYY autor - motiv scurt`), fara explicatii lungi.
|
||||
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: niciun proces vfp9/<exe proiect> (tin lock pe binar); nu se omoara.
|
||||
5. Write-back: `txt2vcx.ps1 -TextFile <vc2> -ProjectRoot <root> -CacheRoot <cache>`
|
||||
(+ `-AllowComun` cu aprobare explicita pentru tinte COMUN — afecteaza toate aplicatiile ROA).
|
||||
Succes = fidelity-check trecut: binar cu mtime nou; `vcx2txt.ps1` ulterior il vede la zi.
|
||||
6. Backup-urile `.pre_runda*.bak` si patch-urile se sterg la curatenia de dupa commit.
|
||||
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. Backup-urile `.pre_runda*.bak` si patch-urile se sterg la curatenia de dupa commit.
|
||||
|
||||
## Capcane
|
||||
|
||||
@@ -37,5 +57,14 @@ rularea `git_sync.ps1`; restul pasilor raman la fel. Fluxul cu cache extern (`vc
|
||||
- Metoda noua de clasa cere `*m: nume` in `*<DefinedPropArrayMethod>`; fara ea, prima salvare
|
||||
din IDE o arunca tacut, iar refresh-ul urmator absoarbe pierderea in cache (si in .bak-uri).
|
||||
Override-urile de metode de baza (Init, Show, hook-uri) nu au nevoie de `*m:`.
|
||||
- Salvarea din VFP IDE peste un binar scris de txt2vcx poate PIERDE si definitii `*m:` deja
|
||||
existente, desi corpurile PROCEDURE raman (patit pe ROAGEST: `import_adauga_factura.recalc_tva`,
|
||||
`import_nota.do_adauga/do_copie/do_reface`, 07.2026); simptom: crash la Createobject cu
|
||||
"Data type mismatch" raportat la linia apelanta. Dupa orice sesiune IDE pe clasa: refresh
|
||||
cache + compara lista `*m:` cu starea de dinainte.
|
||||
- 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.
|
||||
|
||||
315
docs/inventar-comun.md
Normal file
315
docs/inventar-comun.md
Normal file
@@ -0,0 +1,315 @@
|
||||
# Inventar COMUN - functii/clase reutilizabile (ROAGEST)
|
||||
|
||||
Scop: referinta rapida pt. plan/code-review, ca sa refoloseasca comunele in loc sa se reinventeze
|
||||
(ex: Scan manual pt. lista dintr-un cursor, cand exista deja cursor2lista()). Generat prin grep pe
|
||||
COMUN/programe/*.prg + cache text D:\ROA\_vfp_textcache\roagest (nu presupuneri). Numerele = nr.
|
||||
aparitii grep in tot proiectul (indiciu de cat de "canonic" e functia).
|
||||
|
||||
## 1. Functii comune - COMUN\programe\oproceduri_comune.prg (clasa Oracle/executor + utilitare)
|
||||
|
||||
| Functie | Semnatura scurta | Ce face | Uz |
|
||||
|---|---|---|---|
|
||||
| oExecute | (cSql,cCursor,lProgress,cTitlu,nHandle,lShowError,lQuitOnError,lReconnect) | ruleaza SQL prin Oracle, deschide cursor. Retur: <0 eroare (vezi oPrelucrareEroare), 0 fara randuri, >0 nr. randuri | 851 |
|
||||
| oExecuta | idem oExecute, wrapper | ca oExecute dar arata singur amessagebox la eroare si intoarce .T./.F. | 256 |
|
||||
| oPrelucrareEroare | () | intoarce mesajul de eroare Oracle formatat, dupa un oExecute cu retur <0 | 93 |
|
||||
| oFunction2Value | (cSql/cFunctie,...) | executa o functie Oracle si intoarce direct valoarea scalara | 31 |
|
||||
| oSelect2Value | (cSql,...) | SELECT cu 1 coloana/1 rand -> valoare scalara | 58 |
|
||||
| oSelecteaza2Value | variantul "Selecteaza" al lui oSelect2Value | idem, alt nume istoric | 20 |
|
||||
| oSelecteaza2Object | (cSql,...) | SELECT 1 rand -> obiect cu proprietati = coloane | 23 |
|
||||
| Connect / Disconnect / Oreset() | - | (re)conectare/deconectare goConn, reset stare executor | 33/10/119 |
|
||||
| ProcessError | - | procesare interna eroare conexiune | 14 |
|
||||
| amessagebox | (cMesaj,nIcon,cTitlu,...) | MESSAGEBOX wrapper standard ROA (icon/titlu/localizare) - **functia cea mai folosita din tot COMUN** | 1308 |
|
||||
| amessage | - | varianta simpla fara icon/butoane multiple | 14 |
|
||||
| cursor2lista | (cCursor,cColumn,cSeparator,cFiltru) | Scan cursor -> lista valori separate (";" default), pt. coloane necaracter | 36 |
|
||||
| cursor2listac | (cCursor,cColumn,cSeparator,cFiltru) | ca cursor2lista dar incadreaza itemii intre apostrof (pt. SQL IN ('a','b')) - de folosit in loc de Scan manual | 2 |
|
||||
| lista2array | (cLista,@aArray,cSeparator) | sparge o lista delimitata intr-un array | 35 |
|
||||
| lista2cursor | (cLista,...) | lista delimitata -> cursor | 21 |
|
||||
| get_mask | (nInt,nDec) | intoarce masca de format numeric (ex. "999,999.9999") dupa nr. intregi/zecimale | 24 |
|
||||
| formateaza | - | formatare valoare dupa masca/tip | 18 |
|
||||
| NEW_ID | (tabela,...) | genereaza urmatorul ID secvential pt. o tabela | 22 |
|
||||
| NRORD | - | numar de ordine (contor afisare grid/raport) | 217 |
|
||||
| NRCRT | - | numar curent (similar NRORD, alt istoric) | 108 |
|
||||
| Get_Ora | (nTip) | ora curenta formatata dupa tip | 150 |
|
||||
| ULTIMAZI / ultima_zi_din_luna | (an,luna) | ultima zi calendaristica a lunii | 16/25 |
|
||||
| C_LUNA / CLUNA3 / cluna | (nLuna) | nume luna (lung/prescurtat) in romana | - |
|
||||
| get_trimestru / get_semestru | (nLuna) | trimestrul/semestrul din numar luna | - |
|
||||
| SAVE_GRID / RESTORE_GRID | (oGrid,cCheie) | salveaza/restaureaza layout coloane grid (latimi/ordine) in ini/tabela | 15/15 |
|
||||
| SAVE_GRID_COMMENT / RESTORE_GRID_COMMENT | idem | variante cu comentarii coloane | - |
|
||||
| SAVE_GRID_TAG / RESTORE_GRID_TAG | idem | variante cu tag/sortare curenta | - |
|
||||
| snr_grid | - | switch_and_restore_grid - schimba sursa gridului si reaplica layout salvat | - |
|
||||
| XMENU / XMENUP | - | meniu contextual generic (popup) | 22 |
|
||||
| GETCHOICE | - | dialog alegere dintr-o lista | - |
|
||||
| Get_Version | (lNoRevision,lInfo,cFileName) | citeste versiunea din resursele .exe | 15 |
|
||||
| Get_Hexa | (nDeca) | conversie zecimal->hex | 12 |
|
||||
| format_msg | - | formateaza mesaj cu parametri (gen sprintf) | - |
|
||||
| GetHash | - | hash generic (verificare integritate/duplicate) | 48 |
|
||||
| export_xls / ExportToXMLExcel | - | export cursor -> Excel (functii libere aici, la 1234/5502; NU sunt metoda goExport.export_xls din oexport.prg - cod si semnatura diferite, doar nume identic) | 24 |
|
||||
| copiaza_structura_cursor | (cSursa,cDest) | copiaza doar structura unui cursor (fara date) | 27 |
|
||||
| GETCALLSTACK | - | stack de apel curent, pt. debug/log erori | 24 |
|
||||
| RemoveCharacters / RemoveCharactersDB | (cStr,cChars) | elimina caractere dintr-un string / varianta safe pt. query | 56/9 |
|
||||
| XmlSpecialCharacters / WindowsSpecialCharacters / OracleSpecialCharacters | (cStr) | escapare caractere speciale pe context (XML/Windows/Oracle) | 19/11/- |
|
||||
| EncryptDecrypt | (cStr,cCheie) | criptare/decriptare simetrica simpla | 23 |
|
||||
| StringAgg | (cCursor,cColumn,cSeparator) | agregare valori coloana intr-un singur string (gen LISTAGG) | 18 |
|
||||
| GetNrFromString / GetDigitsFromString / GetIBANFromString | (cStr) | extrage numere/cifre/IBAN dintr-un text liber | 18/- |
|
||||
| Atasament2File / File2Atasament | - | conversie fisier <-> blob-atasament (baza de date) | 12/12 |
|
||||
| romfast_suport / DownloadSupportFile | - | trimite/descarca fisier suport catre ROA | 18 |
|
||||
| SaveBackupSet / RestoreBackupSet / ExistsBackupSet / DeleteBackupSet / UpdateBackupSet | - | set de proceduri pt. backup/restaurare setari private utilizator | 22/12/12/12/10 |
|
||||
| GetOptiuneFirma / citeste_optiune_firma | (cCod) | citeste o optiune de configurare per firma | 20 |
|
||||
| param_listari | (cRaport,cTitlu,cSemnaturi,lFaraTab) | pregateste parametri standard pt. rapoarte (titlu/semnaturi) | 19 |
|
||||
| ceretitlu_rap | - | dialog cerere titlu raport | 16 |
|
||||
| aInputBox | - | InputBox generic cu validare | 12 |
|
||||
| GetPdfPath | - | cale generare/salvare PDF | 13 |
|
||||
| GetDefaultValue / HasProperty / GetValue / SetValue | pe clase interne (ex. optiuni) | pattern generic proprietate-cu-default | 14/11/464/540 |
|
||||
| verificare_note_contabile | - | valideaza notele contabile generate din import (echilibrare debit/credit) | 11 |
|
||||
| verifica_partener / verificare_parteneri / verificare_parteneri_istoric | (cCUI/cCod) | valideaza/cauta partener in nomenclator dupa CIF/cod, inclusiv istoric | 10/4/6 |
|
||||
| VerificaCodFiscal / GetMeniuVerificareCodFiscal / GetOptiuneVerificareCodFiscal | - | validare CUI/CIF (ANAF-like) | 10 |
|
||||
| VerifCF / cValidCNP / ValidCNP / GetDataCNP | (cCod) | validare CIF/CNP + extragere data nastere din CNP | 9/- |
|
||||
| VerifIBAN / verificare_iban / GetSumaControlIBAN | (cIban) | validare IBAN (cifra de control) | 8/4 |
|
||||
| TVA2PROCTVA / GetProcTvaStandard / GetCoeficientTvaStandard / ProcentTva2IdJtva / GetIdJtvaStandard | - | conversii cota TVA <-> procent <-> cod TVA Oracle (gcS) | 6/11/-/-/5 |
|
||||
| GetTaxCodeIdPart / GetTaxCode / GetPaymentCode | - | coduri taxare/plata pt. e-Factura ANAF | 12/-/- |
|
||||
| GetArticolByCodDenumire / GetArticolById / GetArticolEFByPartDenumire | - | cautare articol nomenclator dupa cod/denumire/id | 10/6/- |
|
||||
| GetPartenerByCodFiscal / GetPartenerByDenumire / GetPartenerByContBanca / GetPartenerByUtil / GetIdPartenerBy... / GetDenumirePartenerById / GetCodFiscalPartenerById | - | familie de cautari partener (id<->cod fiscal<->denumire<->cont banca) - **cauta_* pt. nomenclatoare, prioritar fata de SELECT ad-hoc** | 2 fiecare |
|
||||
| GetSectieByCsectie / GetSectieById / GetIdSectie / GetGestiuneById | - | cautari sectie/gestiune | 2 fiecare |
|
||||
| GetVencheltById / GetIdVenchelt | - | cautare venit/cheltuiala | 2 |
|
||||
| GetDocumentByContPartenerAct | - | cautare document existent dupa partener+cont+act | 4 |
|
||||
| GetFdocById | - | cautare tip document (fdoc) | - |
|
||||
| GetValutaByISO | - | cautare valuta dupa cod ISO | - |
|
||||
| NrLuni2AnLuna / GetDataIreg | - | conversii perioada an/luna | - |
|
||||
| sir2array | - | split string -> array (generic, non-cursor) | - |
|
||||
| nvl2 / nvl2Default | (val,default) | echivalent NVL Oracle in VFP | 11 |
|
||||
| TooManyInstances | (nInstante) | verifica daca ruleaza deja alta instanta a exe-ului | - |
|
||||
| MyUnzip / UnzipQuickShell / MyUnzipCallBack | - | dezarhivare (update-uri, atasamente) | - |
|
||||
| HTTPDownloadFile / DownloadFile | - | descarcare fisier prin HTTP | - |
|
||||
| lansare_help / lansare_help_meniu / arata_manual | - | deschide manualul/help-ul aplicatiei | - |
|
||||
| viz_prg_instalat / versiune / CheckNewVersion / CheckVersion / UpdateVersion | - | verificare versiune instalata vs. server update | 57 (versiune) |
|
||||
| xdir / xdelete / DeleteFiles | - | utilitare fisiere (listare/stergere) | 14/- |
|
||||
| ImportTable | - | import tabel extern (DBF/CSV) | - |
|
||||
| GET_SCHEMA_GRID | - | genereaza schema coloane pt. grid dinamic | - |
|
||||
| CloneObj / CopyProps | (oSursa,[oDest]) | clonare obiect / copiere proprietati intre obiecte | 10/- |
|
||||
| Get_zileluc | - | zile lucratoare | - |
|
||||
| GetUserDocPath | - | folder documente utilizator curent | - |
|
||||
| aleg_document_pereche | (vezi ooperatii_comune) | vezi sectiune 2 | - |
|
||||
|
||||
Nota: multe din functiile de mai sus exista **dublat** in `proceduri_comune.prg` (varianta veche,
|
||||
non-obiect) - ex. NEW_ID, SAVE_GRID*, XMENU, cursor2lista*, lista2array/cursor, get_mask, Get_Version,
|
||||
Get_Hexa, format_msg, C_LUNA/cluna, get_trimestru/semestru, GETCALLSTACK, CloneObj/CopyProps,
|
||||
ceretitlu_rap. La duplicat castiga fisierul adaugat **cel mai recent** cu SET PROCEDURE ADDITIVE -
|
||||
in roagest.prg OPROCEDURI_COMUNE.PRG (linia 238) vine dupa proceduri_comune (linia 218), deci
|
||||
varianta activa e cea din `oproceduri_comune.prg`. Din varianta veche raman folosite doar 2 functii
|
||||
unice: `extrage_optiuni(cLista,nId)` (valoare dintr-o lista "id::val;id::val", 11 uz) si
|
||||
`myScatter(tcBlank)` (SCATTER generic in obiect, 3 uz); restul functiilor unice de acolo = moarte.
|
||||
|
||||
## 2. Functii comune - COMUN\programe\ooperatii_comune.prg (contabilitate/analitice/balanta)
|
||||
|
||||
| Functie | Ce face | Uz |
|
||||
|---|---|---|
|
||||
| viz_act | vizualizare document (act) generic | - |
|
||||
| aleg_document_pereche | alege documentul pereche (ex. factura<->aviz) la asociere | - |
|
||||
| exista_cont_in_plan_conturi | verifica daca un cont exista in planul de conturi | - |
|
||||
| verific_partener | valideaza/completeaza partener pe o inregistrare contabila | 7 |
|
||||
| verific_analitic / verific_analitic_ | valideaza analitic contabil (cont+subcont) | 7/2 |
|
||||
| verificare_note_contabile | valideaza echilibrarea notelor contabile generate | 11 |
|
||||
| sterge_nota / scrie_nota_import | sterge/scrie nota contabila generata din import | - |
|
||||
| do_assign_analitic | atribuie analitic automat pe o linie | - |
|
||||
| verific_cont | verifica existenta/valabilitate cont contabil | 9 |
|
||||
| viz_balanta_contabilitate / viz_balanta / make_tbalanta / Eval_balanta | construire/vizualizare balanta de verificare | - |
|
||||
| completare_gruputil_analitice / completare_tva_analitice / completare_taxname / completare_paymentname / completare_explicatie_tva | completeaza campuri derivate pe linie contabila (grup util, TVA, taxname, explicatie) | - |
|
||||
|
||||
## 3. Export si listare - COMUN\programe\oexport.prg (clasa oExportConfig -> obiect global goExport)
|
||||
|
||||
Pattern canonic: `goExport.export2frx(...)` / `goExport.export2xlsx(...)` / `goExport.export2pdf(...)`.
|
||||
Preview rapoarte: FoxyPreviewer (`gcReportPreviewer = "FoxyPreview"` in roagest.prg).
|
||||
|
||||
| Functie/metoda | Semnatura scurta | Ce face | Uz |
|
||||
|---|---|---|---|
|
||||
| export2frx | (tcAlias,tcRaport,tlCereTitlu,...,tcReportPreviewer,toPreviewerConfig) | REPORT FORM cu preview/print (FoxyPreview), logo, imprimanta din setari - **listarea standard, cea mai folosita** | 155 |
|
||||
| export2xls | (tcAlias,tcNumeFisier,tcListaColoane,tcFiltru) | EXPORT TO ... TYPE XL5 (.xls vechi) + deschide fisierul | 30 |
|
||||
| export2xlsx | (tcAlias,tcNumeFisier,tcListaColoane,tcFiltru) | copytoxlsx() - XLSX nativ modern, **preferat pt. cod nou** | 7 |
|
||||
| export2xlsxGrid | (toGrid,tcNumeFisier,tcWhere,tcOrder) | schema din grid (get_schema_grid) -> SELECT -> export2xlsx | 3 |
|
||||
| exportMultiTable2Xlsx | (tcTableList,tcFileName) | mai multe tabele in acelasi workbook xlsx (clasa VFPxWorkbookXLSX) | 3 |
|
||||
| Export2XmlXls | (toGrid,tcFileName,tcSheetName,tlOpen) | XML SpreadsheetML via clasa excelxml, direct din grid | 2 |
|
||||
| export2pdf | (tcAlias,tcRaport,tlPreview,tcCursorSalvare) | REPORT FORM OBJECT pdflistener2 -> PDF; optional continutul in cursor | 26 |
|
||||
| export2html | (tcTargetTables,tcNumeFisier,tcTableTitles,tlJustTables) | HTML/Excel-HTML din unul/mai multe tabele (TEXTMERGE) | 9 |
|
||||
| export2xml_efactura | (toDateFactura,tcCursorLinii,tlSilentios) | wrapper getXmlEFactura() - XML e-Factura ANAF | 6 |
|
||||
| export2frx_paginaregrup | (...) | listare cu numerotare pagini per grup (crsPaginiRaportGrup) | 6 |
|
||||
| getRepPath / getLogoPath | (tcRaport / tcLogo) | rezolva USR_<raport>.frx / logo per schema (DIRGEN\USERREPORTS, atas_atasamente) | 24/10 |
|
||||
| OPEN_DEFAULT_APP | (tcNumeFisier) | ShellExecute "open" cu aplicatia implicita | 70 |
|
||||
| citesteSetare / modificaSetare (+ *Ini/*Registru) | (cCheie[,cVal]) | setari registru/ini dupa setTip/setPath/setSectiune | 13/11 |
|
||||
| verificaDate | (tcAlias,tnTip,tlSilentios) | valideaza alias deschis/cu date inainte de export | 16 |
|
||||
| listareUserReport / export_frx / export_xls | - | dispatcher + variante vechi (marcate de inlocuit); metoda export_xls != functia libera export_xls din oproceduri_comune.prg | 22/13/26 |
|
||||
| FoxyPreview (functie libera, nu pe goExport) | (tcRaport,toPreviewerConfig) | preview FoxyPreviewer.App direct pe .frx, apelata din formulare | 19 |
|
||||
| FoxyPreviewerCaller (clasa) | AddReport(tcReport,tcClauses) / RunReport | combina mai multe .frx intr-un singur preview | 7 |
|
||||
| PreviewerConfig (clasa) | SetValue/GetValue | property-bag optiuni FoxyPreviewer (param toPreviewerConfig la export2frx) | - |
|
||||
|
||||
### Export Excel - 3 mecanisme paralele (atentie la confuzii)
|
||||
1. `goExport.export2xls/export2xlsx` (mai sus) - preferat pt. cod nou (export2xlsx).
|
||||
2. `export_excel` / `export_excel_grid` / `exportare` / `LIST_EXCEL` (proceduri_excel.prg) - OLE
|
||||
Automation, scrie celula cu celula, necesita Excel instalat; uz mic (2-12). `get_excel_mask` de
|
||||
acolo = conversie masca VFP -> format Excel (nu confunda cu `get_mask` din sect. 1).
|
||||
3. Clasa `excelxml` (excelxml.vcx, COMUN\UTILE\excel) - Excel XML direct din `gridobject`, fara
|
||||
Excel instalat (proprietati: file, sheetname, openaftersaving; metoda `save`); 73 uz.
|
||||
Plus functiile libere `export_xls`/`ExportToXMLExcel` din oproceduri_comune.prg (sect. 1) - cod
|
||||
diferit de metoda `goExport.export_xls`, doar nume identic.
|
||||
|
||||
## 4. Utilitare transversale (COMUN\programe, fisiere neinventariate initial)
|
||||
|
||||
### gencursor.prg
|
||||
| Functie | Semnatura scurta | Ce face | Uz |
|
||||
|---|---|---|---|
|
||||
| gencursor | (cNume,cAlias,cSelect,cFiltru,cSchema,cOrder,lAfisare,cGroup,...) | obiect deca_baza/ca_baza cu cursor "lazy" (select/filtru/order pe goConn) - **baza grilelor cu sursa dinamica; nu construi manual ca_baza** | 403 |
|
||||
|
||||
### validare.prg - validare CIF/CNP cu ANAF/MFIN/VIES (vs. VerifCF/ValidCNP offline din sect. 1)
|
||||
| Functie/clasa | Ce face | Uz |
|
||||
|---|---|---|
|
||||
| VerificareCod (clasa) | validare completa cu webservice: metode VERIFICARE_CIF/VERIFICARE_CNP/ANAF/MFIN/VIES/validare/GetError | 169 |
|
||||
| VerificareANAF (clasa) | sincronizare lista CIF-uri cu ANAF (VerificaListaCIF, ANAF_SincronWebService_PlatitorTva) | 26 |
|
||||
| test_cif / VALIDARE_CIF / test_cnp / VALIDARE_CNP | validari format + cifra control, offline | 27/19/9/15 |
|
||||
| VERIFICARE_PLATITORTVA / VIES_VAT / ONRC | platitor TVA / verificare VIES / interogare ONRC | 5/5/9 |
|
||||
| IntroducereCod (clasa Form) | formular introducere + validare cod | 25 |
|
||||
|
||||
### ocautare.prg - dialoguri standard de cautare/alegere (de refolosit in loc de SELECT+grid manual)
|
||||
| Functie | Ce alege | Uz (prg/forme) |
|
||||
|---|---|---|
|
||||
| caut_gestiune / caut_gestiune_dest | gestiune (sursa/destinatie) | 25/324, 12/37 |
|
||||
| caut_fdoc | tip document | 7/170 |
|
||||
| caut_explicatie_tva | explicatie TVA (filtrare exigibil JC/JV) | 9/143 |
|
||||
| caut_partener / CautPartenerContabilitate | partener (generic / dupa cont contabil) | 13/104, 16/16 |
|
||||
| caut_valuta / caut_valuta_iso | valuta | 11/104 |
|
||||
| cauta_nom_articole / caut_articol | articol (filtru text / multiplu) | 8/87, 20/42 |
|
||||
| caut_sectie / caut_facturi | sectie / facturi dupa cont+partener+interval | 8/71, 12/34 |
|
||||
| caut_lucrare, caut_venchelt, caut_contract, caut_delegati, ... | ~40 alte dialoguri de nomenclator, uz mic in ROAGEST | 2-17 |
|
||||
|
||||
### oheader.prg
|
||||
| Clasa | Ce face | Uz |
|
||||
|---|---|---|
|
||||
| PSHeader (As Header) | dublu-click pe header = sortare (cHOrder), evidentiaza coloana activa, apeleaza cCallMethod (default Refresh) pe parintele gridului | 37 in forme |
|
||||
|
||||
### regex.prg
|
||||
| Functie | Ce face | Uz |
|
||||
|---|---|---|
|
||||
| strtranx | STRTRAN cu regex (grupuri $1, evaluare =expr) | 14 |
|
||||
| GetRegExp / GetRegExpAll / OccursRegExp / StrtranRegExp | prima/toate potrivirile, numarare, inlocuire simpla | 15/4/4/2 |
|
||||
| StripNonAscii | elimina caractere non-ASCII dintr-un string (whitelist) | 11 |
|
||||
|
||||
### ini.prg
|
||||
| Functie | Semnatura | Ce face | Uz |
|
||||
|---|---|---|---|
|
||||
| getini / setini | (cIniFile,cSection,cVar[,cVal]) | citire/scriere fisiere .ini low-level (FOPEN) - distinct de GetOptiuneFirma (Oracle) si goExport.citesteSetareIni (wwApi) | 28/9 |
|
||||
|
||||
### altele (o functie-doua per fisier)
|
||||
| Functie (fisier) | Ce face | Uz |
|
||||
|---|---|---|
|
||||
| get_oluna (oproceduri_util.prg) | (an,luna) -> obiect cu intervalul calendaristic disponibil (lunamin/anmin/lunamax/anmax) din tabela calendar | 22 |
|
||||
| ReferinteDocumenteNota / ReferinteDocument (odocumente.prg) | verifica daca un document e referentiat de altul (pack_documente Oracle) - inainte de stergere/modificare | 4/4 |
|
||||
| anunta_rezultat / scrie_in_mesaje / raport_mesaje (mesaje.prg) | log mesaje de verificare in tabel + raport; uz de nisa | 2-3 |
|
||||
|
||||
## 5. Clase UI comune (COMUN\clase, cache text D:\ROA\_vfp_textcache\roagest\comun\clase)
|
||||
|
||||
### Butoane - cmd_butoane.vcx (parinte: _cmd_base.vcx -> buton/cmd_buton)
|
||||
Mecanism: fiecare buton seteaza doar proprietatea `caction` (nume metoda) + `cpictureup/down`.
|
||||
`buton.Click` (in `_cmd_base.vcx`) cauta metoda `caction` pe `this.Parent`, apoi `this.Parent.Parent`,
|
||||
apoi `Thisform`, si o executa cu `clistaparametri` ca argument daca exista (Pemstatus + macro &).
|
||||
**Nu suprascrie Click pe butoane noi - seteaza doar caction pe o instanta din cmd_butoane.vcx.**
|
||||
|
||||
| Clasa buton | caction | Rol |
|
||||
|---|---|---|
|
||||
| but_nou / cmd_adauga | do_adauga | adauga inregistrare noua |
|
||||
| but_copiaza | do_copiaza | copiaza inregistrarea curenta |
|
||||
| but_sterge / cmd_sterge | inainte_de_do_sterge | sterge (cu hook de confirmare) |
|
||||
| but_modifica / cmd_modifica | inainte_de_do_modifica | intra in modificare |
|
||||
| but_termin / but_da / cmd_termin | do_termin | confirma/salveaza si inchide |
|
||||
| but_renunt / but_nu / cmd_renunt | do_renunt | renunta/inchide fara salvare |
|
||||
| but_salveaza | do_salvare | salveaza fara inchidere |
|
||||
| but_reset / cmd_reset | do_reset | reseteaza formularul/filtrul |
|
||||
| but_cautare / cmd_cauta | do_cauta | deschide cautare |
|
||||
| but_compara | do_compara | comparare inregistrari |
|
||||
| but_verifica | do_verifica | validare |
|
||||
| but_retur | do_retur | operatie retur |
|
||||
| but_precedent / but_urmator / but_urmator_tot | do_precedent / do_urmator / do_urmator_tot | navigare inregistrari |
|
||||
| but_excel | inainte_de_do_excel | export Excel |
|
||||
| but_listare | inainte_de_do_listare | listare/raport |
|
||||
| but_factura / but_listfactura | do_factura / do_listfact | facturare/listare factura |
|
||||
| but_grafic | do_grafic | afisare grafic |
|
||||
| but_help | do_help | help contextual |
|
||||
| but_modiparam | do_modiparam | modificare parametri |
|
||||
| but_attach | do_ataseaza | ataseaza fisier |
|
||||
| but_reface | inainte_de_do_reface | reface/reia operatie |
|
||||
| cmd_login / cmd_logoff | do_login / do_logoff | autentificare |
|
||||
| cmd_executa / cmd_select | do_executa / do_select | executie/selectie generica |
|
||||
| but_sus / but_jos | do_scrollup / do_scrolldown | scroll |
|
||||
|
||||
### Container label+text - lb_tx.vcx (parinte: _container, folosesc _lbbase/_txbase din _lb_base.vcx/_tx_base.vcx)
|
||||
| Clasa | Rol |
|
||||
|---|---|
|
||||
| clb_tx_simplu / cb_tx_simplu | label + textbox simplu |
|
||||
| cb_tx_autofill | label + textbox cu autocompletare (cautare in nomenclator) |
|
||||
| cb_tx_cautare | label + textbox + buton cautare integrat |
|
||||
| clb_tx_data | label + textbox cu masca data |
|
||||
| clb_an_luna | pereche an/luna |
|
||||
| clb_luna_intre / clb_nr_intre | interval luna/numar (de-la, pana-la) |
|
||||
| clb_n1n2_simplu | pereche 2 numere simple |
|
||||
| ct_cb_tx | container compus text+combo |
|
||||
| ed_tx_simplu | label + editbox |
|
||||
| op_tx_simplu | label + optiongroup |
|
||||
|
||||
Proprietate cheie comuna: `pcobj` (leaga containerul de camp/proprietate din obiectul sursa).
|
||||
|
||||
### Baze formular - _frm_base.vcx / _frm_child.vcx
|
||||
| Clasa | Rol |
|
||||
|---|---|
|
||||
| _frmbase | baza standard formular; implementeaza deja `do_adauga/do_copiaza/do_modifica/do_renunt/do_sterge/do_termin` (override doar daca logica difera de default) |
|
||||
| _frmnotitle | ca _frmbase, fara bara de titlu; are propriile do_adauga/do_modifica/do_renunt/do_sterge/do_termin |
|
||||
| frm_termin | subclasa _frmbase, expune direct do_termin |
|
||||
| frm_termin_renunt | subclasa frm_termin, adauga do_renunt (fara override suplimentar) |
|
||||
| frm_gol | subclasa _frmbase "goala", cu propriile do_adauga/do_modifica/do_sterge |
|
||||
| _pgfrmbase | baza pageframe |
|
||||
|
||||
### Grid - _grd_base.vcx
|
||||
| Clasa | Rol |
|
||||
|---|---|
|
||||
| _grdbase | grid de baza (subclasa _grid) |
|
||||
| _grdrow | subclasa _grdbase, randuri custom |
|
||||
| _grdfooter | grid separat "atasat" la un grid sursa prin metoda `attachtogrid` (copiaza coloane/fonturi de la oSrcGrd) - pt. randuri de total/footer sub un grid principal |
|
||||
|
||||
## 6. Conventii transversale
|
||||
|
||||
- Prefixe variabile: `g`/`gc`/`gn`/`gl` (globale char/numeric/logic), `p`/`pc`/`pn`/`pl` (proprietati
|
||||
obiect), `t`/`tc`/`tn`/`tl` (parametri PARAMETERS/LPARAMETERS), `l`/`lc`/`ln`/`ll` (locale), `m.`
|
||||
(scoping explicit memvar quand hay coliziune cu camp).
|
||||
- SQL pass-through: mereu prin `goExecutor.oExecute`/`oExecuta`, niciodata SQLEXEC direct in cod nou;
|
||||
schema calificata cu `gcS` (ex. `gcS + ".STOC"`); parametri legati cu `?param` (bind variable VFP->Oracle).
|
||||
- Retur executor: oExecute -> numeric (<0 eroare/`oPrelucrareEroare()`, 0 fara randuri, >0 nr. randuri);
|
||||
oExecuta -> logic (.T./.F., arata singur eroarea).
|
||||
- Cursoare temporare: prefix `crs*` (ex. `crsListaTemp` in cursor2lista/cursor2listac).
|
||||
- Mesaje utilizator: mereu `amessagebox()`/`amessage()`, nu `MESSAGEBOX()` direct.
|
||||
- Formatare numerica: `get_mask()` + `formateaza()`, nu masti hardcodate in cod nou.
|
||||
- Fisiere `.vc2`/`.sc2`: TAB-uri semnificative, proprietatile in blocul `*<PropValue>` sunt
|
||||
alfabetizate - orice editare manuala trebuie sa respecte formatul (vezi CLAUDE.md, flux editare text).
|
||||
|
||||
## 7. Ce am lasat pe dinafara (intentionat)
|
||||
|
||||
- `proceduri_comune.prg` (varianta veche) - acoperita acum in nota de la sect. 1 (2 functii unice
|
||||
folosite, restul dublate sau moarte); functiile ei unice cu 0 aparitii (caut_nume_politica,
|
||||
make_sectii_utilizator, recompune_optiuni, cere*/compara*, debug_*_eventtracking, ...) - omise.
|
||||
- `oproceduri_comune_imob.prg` - varianta specifica ROAIMOB, nu ROAGEST.
|
||||
- `xdate.prg` - script procedural (incarca cursoarele xsets/xrequest/xnote la DO), nu expune functii.
|
||||
- Metoda `getUserRepPath` din oExportConfig - complet comentata (moarta); varianta activa e functia
|
||||
libera omonima din `proceduri_rapoarte.prg` (cod diferit).
|
||||
- Clase de nomenclatoare mari (`onomenclatoare.vcx`, `onom_articole.vcx`, `stocuri.vcx`, `rulaje.vcx`,
|
||||
`ointroduceri*.vcx`, `oinventar.vcx`) - business logic specific gestiune, prea voluminos pt. acest
|
||||
inventar (candidat pt. un inventar separat, per-flux, daca devine necesar).
|
||||
- Clasele de configurare/serii (`configurare.vcx`, `serii_numere.vcx`, `ferestre_oracle.vcx`,
|
||||
`bon_fisc.vcx`) si utilitarele (`GridExtras`, `ctl32`, `hpdf`) - neinventariate, uz mai rar
|
||||
in fluxurile curente de lucru (`excelxml.vcx` e acoperita la sect. 3).
|
||||
- Functiile din `COMUN\programe` fara nicio aparitie gasita prin grep in ROAGEST (posibil folosite
|
||||
doar de alte aplicatii ROA) - omise.
|
||||
|
||||
## 8. Cum se foloseste
|
||||
|
||||
- **La plan**: inainte de a scrie cod/obiecte noi, scaneaza acest fisier + un grep tintit
|
||||
(`grep -rn "<nume_functie_candidata>" COMUN/programe D:\ROA\_vfp_textcache\roagest`) ca sa
|
||||
confirmi ca nu exista deja o comuna echivalenta.
|
||||
- **La code-review**: daca un diff introduce Scan manual pt. liste, MESSAGEBOX direct, SQLEXEC direct,
|
||||
un buton cu Click suprascris in loc de `caction`, un export Excel/listare construite manual in loc
|
||||
de `goExport.export2*`/FoxyPreview, sau un dialog de alegere nomenclator facut din SELECT+grid in
|
||||
loc de `caut_*` (ocautare.prg), semnaleaza reutilizarea comunei corespunzatoare din tabelele de mai sus.
|
||||
40
docs/orchestrare-subagenti.md
Normal file
40
docs/orchestrare-subagenti.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Orchestrare cu subagenti: context mic, misiuni descompuse
|
||||
|
||||
Regula (valabila in toate proiectele ROA/VFP): un singur subagent care duce o misiune lunga
|
||||
(iteratii de teste, investigatii, mai multe sarcini inlantuite) acumuleaza context urias
|
||||
(s-a ajuns la ~800k tokens) — calitate degradata, cost mare. Nu se lucreaza asa.
|
||||
|
||||
## Cum se lucreaza
|
||||
|
||||
- Sesiunea principala (sau un agent primar) e ORCHESTRATOR: imparte planul pe sarcini
|
||||
independente (un test, un audit, un scenariu = o sarcina), monitorizeaza, transmite
|
||||
constatarile intre agenti, verifica rezultatele.
|
||||
- Fiecare sarcina merge la un SUBAGENT PROASPAT cu prompt autosuficient: context complet
|
||||
in prompt + trimitere la un fisier de handoff, nu context acumulat in conversatie.
|
||||
- HANDOFF compact pe disc (docs\handoff_*.md, stil telegrafic): inventar livrabile,
|
||||
stare, ce ramane, detaliile ne-evidente pe care un agent proaspat nu le-ar putea
|
||||
reconstitui usor. Se actualizeaza la fiecare predare de stafeta.
|
||||
- PRAG: maxim ~200-250k tokens per subagent. Orchestratorul urmareste dimensiunea
|
||||
contextului; la atingerea pragului: cere handoff, inchide agentul, respawneaza unul
|
||||
proaspat pe sarcina urmatoare.
|
||||
- Sarcinile independente ruleaza in PARALEL (lane-uri), ex. audit read-only + editare teste.
|
||||
- Orchestratorul da utilizatorului UPDATE-URI SCURTE de progres, regulat (monitor pe
|
||||
artefacte: loguri/fisiere/screenshots; o propozitie-doua la fiecare schimbare relevanta,
|
||||
fara naratiune la evenimente fara continut).
|
||||
- Orchestratorul MONITORIZEAZA ACTIV subagentii sa nu se blocheze: monitor persistent pe
|
||||
artefactele lor + verificare la lipsa de progres (~10 min fara schimbare = suspect):
|
||||
procese agatate (vfp9 zombi, dialoguri modale), semafoare orfane, timeout-uri de tool
|
||||
(120s implicit) care omoara procese. La blocaj: diagnostic direct (procese, fisiere,
|
||||
loguri), mesaj de deblocare cu constatarea concreta, si abia apoi restart daca e cazul.
|
||||
- Modele: subagentii care DOAR ruleaza/editeaza teste si alte sarcini de volum/rutina ->
|
||||
Sonnet; ORCHESTRATORUL subagentilor (cel care imparte, monitorizeaza, deblocheaza,
|
||||
decide) -> Opus (sau sesiunea principala). Commit doar dupa review-ul diff-ului de
|
||||
catre om (vezi reguli_lucru.md).
|
||||
|
||||
## Semne ca ai gresit impartirea
|
||||
|
||||
- Acelasi agent primeste "inca o sarcina" a treia oara -> trebuia agent nou + handoff.
|
||||
- Agentul re-descopera capcane deja documentate -> handoff-ul/docs-ul e incomplet;
|
||||
completeaza-l, nu repeta investigatia.
|
||||
- Orchestratorul face el insusi munca de volum -> deleaga si pastreaza-si contextul
|
||||
pentru decizii, verificari si deblocari.
|
||||
@@ -13,3 +13,6 @@
|
||||
Metoda de depanare (log.txt, cascade ON ERROR, bisectie clase): `depanare_testare_vfp.md`.
|
||||
5. Editare .vcx/.scx pe text (cache, cp1252 byte-safe, fidelity-check): `flux-editare-vfp-text.md`.
|
||||
Cautare in binare: `cautare_vcx_vct.md`.
|
||||
6. Misiuni lungi (teste, investigatii, sarcini inlantuite): NU un singur subagent cu context
|
||||
acumulat — orchestrator + subagenti proaspeti per sarcina (max ~200-250k tokens/subagent),
|
||||
handoff compact pe disc: `orchestrare-subagenti.md`.
|
||||
|
||||
132
docs/testare-ui-vfp.md
Normal file
132
docs/testare-ui-vfp.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# Testare UI VFP headless cu harness + screenshots
|
||||
|
||||
Harness reutilizabil pentru teste care afiseaza un formular REAL (fara Oracle/UI complet),
|
||||
executa actiuni si valideaza vizual prin capturi de ecran. Valabil pentru toate proiectele
|
||||
VFP din suita ROA; exemplele sunt pe ROAGEST. Alternativa la
|
||||
`testare-vfp-mcp.md` (care ruleaza programul principal intreg + windows-mcp): aici instantiem o
|
||||
singura clasa cu dependinte dummy, deci pornire rapida si izolata.
|
||||
|
||||
Fisiere in `COMUN\utile\Teste\`: `vfp_ui_harness.ps1` (orchestrator generic, parametrizat),
|
||||
`_precompile.ps1` (precompilare izolata), `ui_harness.prg` (proceduri VFP de handshake),
|
||||
`mock_amessagebox.prg` (mock dialog) — infrastructura sta in radacina `Teste\`; suitele de
|
||||
teste stau grupate pe subiect in subfoldere (ex. `achizitie_import\`). Exemplu complet:
|
||||
`achizitie_import\test_import_nota_ui.prg` + `.ps1` (wrapper).
|
||||
|
||||
**REGULA (Marius, 17/07/2026): testele pe aplicatii frontend exerseaza fluxul REAL al
|
||||
utilizatorului** — formularul/butonul/metoda pe care o apeleaza aplicatia (ex. "Adauga repere",
|
||||
do_adauga_factura prin dialogul real), NU introducerea directa a randurilor in cursoare/tabele
|
||||
(ex. Append in rul_temp/introdc). Popularea directa sare peste validari/filtre/efecte laterale
|
||||
si da PASS fals (caz real: articol cont 212 "adaugat" direct in rul_temp trecea testul, dar prin
|
||||
fluxul real nu se adauga deloc). Mock-urile raman permise doar pe INFRASTRUCTURA (Oracle,
|
||||
dialoguri modale), nu pe pasii fluxului testat.
|
||||
|
||||
## Test UI nou in 5 pasi
|
||||
|
||||
1. `.prg` de test: `PUBLIC gcUILog, gcSyncDir`; `SET TALK OFF` (obligatoriu, vezi cap. c);
|
||||
`SET PATH/CLASSLIB/PROCEDURE` ca in aplicatie; incarca ULTIMELE
|
||||
`SET PROCEDURE TO ...\ui_harness.prg ADDITIVE` si (daca ai dialoguri)
|
||||
`...\mock_amessagebox.prg ADDITIVE`.
|
||||
2. Creeaza dummy-urile minime (`goExecutor`, `goApp`, etc.) + cursoarele pe care le cere
|
||||
Init-ul clasei (RecordSource-urile grilelor).
|
||||
3. Instantiaza clasa, `WindowType=0`, `Show()`, `WindowState=2`.
|
||||
4. Pe fiecare pas: fa actiunea, verifica efectul in date (loghezi PASS/FAIL cu un helper
|
||||
local), apoi `DO HarnessStep WITH <n>, '<mesaj>'` (scrie ready_n, asteapta cont_n de la
|
||||
orchestrator sau auto-continua dupa ~30s). La final `DO HarnessDone WITH 'done'`.
|
||||
5. Ruleaza: `powershell -File vfp_ui_harness.ps1 -TestPrg <test.prg> -Steps @('pas0',...)`.
|
||||
PNG-urile ies in `screenshots\step_<n>_<eticheta>.png`; log in `<test>_log.txt`.
|
||||
|
||||
## Capcane / deblocari (toate confirmate in sesiune)
|
||||
|
||||
a. **Lansarea orchestratorului**: prin tool cu timeout implicit (~120s) e omorat inainte de
|
||||
finalul pasilor. Ruleaza-l in background (run_in_background) + asteapta `done.txt`, sau
|
||||
timeout mare (300-600s). NU porni VFP separat de orchestrator - si-l lanseaza singur.
|
||||
b. **Asteptarea ready_0 prea scurta** omoara VFP exact inainte sa scrie semaforul. Cu `.fxp`
|
||||
cald START apare in ~2s, la rece mult mai mult (zeci de classlib-uri). Foloseste
|
||||
`-ReadyTimeoutSec` generos (implicit 180s). Retry NUMAI la "start ratat", nu la "start lent".
|
||||
c. **`SET SAFETY OFF` + `SET TALK OFF` ca PRIMUL lucru, inainte de primul `STRTOFILE`.**
|
||||
Cu SAFETY ON, prima scriere a log-ului (daca fisierul exista deja) scoate dialogul modal
|
||||
"...already exists, overwrite it?" care BLOCHEAZA rularea headless (VFP pare "instanta moarta"
|
||||
- proces viu, blocat pe dialog). Cu TALK ON, `SUM`/`CALCULATE` (ex. din `recalculeaza`) isi
|
||||
echo-eaza rezultatele pe desktop, ca text parazit peste formular in screenshots. Harness-ul
|
||||
are `HarnessInit`/`SET SAFETY OFF` defensiv in procedurile de scriere, dar testul trebuie
|
||||
sa faca `SET SAFETY OFF` oricum INAINTE de scrierea lui proprie de "START".
|
||||
d. **`vfp9 -A test.prg` deschide INTERMITENT editorul** in loc sa ruleze (log ramane gol).
|
||||
Lanseaza `.fxp`-ul PRECOMPILAT (`vfp9 -A test.fxp`) - se executa mereu.
|
||||
e. **Precompilarea (`COMPILE`+`QUIT`) atarna** dupa COMPILE; rulata in ACEEASI sesiune
|
||||
powershell care lanseaza apoi testul, otraveste lansarile (nu executa). Ruleaza precompilarea
|
||||
intr-un proces copil izolat (`Start-Process -Wait _precompile.ps1`).
|
||||
f. **Detectia "a pornit" pe mtime-ul log-ului > momentul lansarii**, nu pe "log ne-gol": un log
|
||||
stale tinut deschis de un `vfp9` zombi pacaleste verificarea. Omoara zombii inainte de fiecare
|
||||
lansare.
|
||||
g. **Formulare modale** (`WindowType`) - `Show()` nu returneaza si blocheaza testul. Seteaza
|
||||
`goObj.WindowType = 0` (modeless) pentru afisare non-modala automatizata.
|
||||
h. **Dummy minimali**: `goExecutor` (oExecute/oExecuta creeaza cursorul cerut), `goApp`
|
||||
(`ReadIni` pt. font din settings.ini), `poAct`/`oact` (curs valutar). Init-ul recreeaza
|
||||
cursoarele goale din Oracle daca nu-s pre-populate - pre-populeaza-le INAINTE de instantiere.
|
||||
i. **`LOCATE FOR camp == 'literal'` pe camp `C(n)` padded cu spatii nu gaseste nimic** (`==` e
|
||||
exact) - foloseste `ALLTRIM(camp) == 'literal'`.
|
||||
j. **Messagebox-uri de confirmare blocheaza testul headless**. Mock: `FUNCTION amessagebox`
|
||||
care returneaza direct valoarea butonului (6=Da). Incarca-l cu `SET PROCEDURE ... ADDITIVE`
|
||||
**PRIMUL** (inaintea `oproceduri_comune.prg`): la nume duplicat de procedura, VFP foloseste
|
||||
fisierul cautat PRIMUL in lista (verificat empiric: incarcat ultimul PIERDE, primul CASTIGA).
|
||||
Mock-ul umbreste `amessagebox` si din apelurile din metodele de clasa (ex. `do_sterge_articol`).
|
||||
k. **Cursor bound la o grila, recreat de Init -> grila pierde coloanele (eroare 1925).** Ex.:
|
||||
`import_nota.Init` recreeaza `rul_temp` din Oracle daca e gol la instantiere; GridArt ramane
|
||||
fara coloanele denumite. Fix: pune 1 rand placeholder in cursor INAINTE de instantiere (ca Init
|
||||
sa nu-l recreeze), apoi **`ZAP`** dupa `Show()` (NU `DELETE ALL`: acesta lasa un rand fizic
|
||||
sters si pointerul la EOF, iar cod gen `do_calculeaza_diferente` face `GO recno_EOF` -> eroare 5).
|
||||
l. **CREATEOBJECT/ADDPROPERTY se comporta gresit apelate DINTR-O PROCEDURA in acest runtime headless**
|
||||
(obiect returnat ca string de 30 spatii; `ADDPROPERTY` da eroare 11). Din programul PRINCIPAL
|
||||
merg. Construieste obiectele (ex. `toDlg` pt. `do_adauga_factura`) INLINE in main, nu intr-un
|
||||
helper. (Cauza exacta neclara; reproductibil.)
|
||||
m. **`gl406=.T.` (SAFT) activeaza cod care are nevoie de mock-uri suplimentare**, altfel crapa sau
|
||||
taxcode ramane mereu NULL: `GetTaxCode`/`GetTaxCodeIdPart` (oproceduri_comune.prg) apeleaza
|
||||
`update_jtva_coloane()` care ruleaza `goExecutor.oExecute("select * from vjtva_coloane ...", <cursor>)`
|
||||
- mock-ul de `oExecute` trebuie sa intercepteze `'VJTVA_COLOANE' $ UPPER(tcSql)` si sa returneze
|
||||
un cursor cu structura reala a view-ului (`id_jtva_coloana, denumire, jc, jv, coloana_jc,
|
||||
coloana_jv, cota_tva, id_tva, taxcode, taxcode_neexigibil, taxcode_n50, taxcode_n50_tvai,
|
||||
taxcode_n100, taxcode_regularizare, taxcode_tvai, afisat, ordine`) - codul apelant face singur
|
||||
`INDEX ON id_jtva_coloana TAG id_jtva` dupa, nu trebuie indexat in mock. Cand `id_partc`/`id_partd`
|
||||
pe rand nu e gol, `GetTaxCodeIdPart` cauta si codul fiscal al partenerului prin
|
||||
`goExecutor.oSelect2Value(sql, @toValue)` (`GetCodFiscalPartenerById`) - metoda lipseste din
|
||||
dummyexecutor-ul de baza, trebuie adaugata (returneaza cod fiscal gol -> `VERIFICA_RTVAI` sare
|
||||
peste apelul Oracle real de validare CIF).
|
||||
n. **Explicatia TVA de pe randul T ("in tandem" cu baza) NU se scrie prin cod separat** - e pur si
|
||||
simplu o A DOUA intrare in `jtva_coloane2`/`vjtva_coloane` (coloana `id_tva` de pe randul bazei
|
||||
punctand spre `id_jtva_coloana` al randului TVA); `aplica_explicatie_tva` (ointroduceri.prg
|
||||
~9807) citeste acea a doua intrare si o scrie pe rand T. Populeaza mock-ul cu ambele randuri
|
||||
(baza + TVA), nu doar cu unul si nu concatena manual "TVA " + denumirea bazei in test.
|
||||
o. **FARA FURT DE FOCUS (17/07/2026)**: `Graphics.CopyFromScreen` (captura ecranului intreg) fura
|
||||
focus si se corupe daca utilizatorul lucreaza in paralel - NU se mai foloseste. Capturile se fac
|
||||
cu `PrintWindow` (user32, P/Invoke) pe HANDLE-ul ferestrei vfp9 (`Process.MainWindowHandle`),
|
||||
flag `2` = `PW_RENDERFULLCONTENT` (fallback flag `0` daca iese goala); merge cu fereastra
|
||||
acoperita/in fundal, dar NU minimizata. Fereastra e mutata OFF-SCREEN (`SetWindowPos` cu
|
||||
`HWND_BOTTOM`, x=-4000, `SWP_NOACTIVATE`) imediat ce apare handle-ul si RE-IMPINSA la fiecare
|
||||
pas (VFP isi reactiveaza singur fereastra la `Show()`/dialoguri modale - o singura impingere la
|
||||
lansare nu e suficienta). Toate consolele powershell copil (precompilare) sunt `-WindowStyle
|
||||
Hidden` (sigur pentru consola; NU si pentru GUI VFP, care trebuie doar off-screen, nu ascuns -
|
||||
PrintWindow pe fereastra minimizata/ascunsa poate reda gol). Implementat in
|
||||
`vfp_ui_harness.ps1` (Take-Screenshot, Push-Offscreen, Wait-MainWindowHandle) si
|
||||
`_precompile.ps1` (acelasi Push-Offscreen pe fereastra tranzitorie de compilare).
|
||||
p. **Cursorul `introdc` FARA indexul `ord_doc` schimba documentul "principal" la sincronizari
|
||||
repetate** (sincronizeaza() apelat de mai multe ori, ex. la adaugarea a 2+ articole succesiv
|
||||
prin fluxul real): identificarea documentului principal (`Go Top` + `Locate For
|
||||
Inlist(tip_rand,'B','S') And !Empty(doc_key)`) e stabila in productie doar pentru ca
|
||||
`achizitie_import` (COMUN\programe\ointroduceri.prg:1616-1618) creeaza, INAINTE de
|
||||
`CREATEOBJECT('import_nota')`, indexul `ord_doc` (`Str(Nvl(nr_doc,0),8) +
|
||||
Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='T','3', tip_rand='D','4', '5') +
|
||||
Padr(Nvl(scd,''),10)`) + `SET ORDER TO ord_doc`, care ordoneaza dupa `nr_doc` (S-urile
|
||||
principalei mostenesc nr_doc-ul ei) - documentul cu `nr_doc` minim ramane mereu acelasi. Un
|
||||
test care creeaza `introdc` fara acest index ramane pe ordinea FIZICA (recno): dupa ce
|
||||
principala e sparta (randul B sters, randurile S adaugate la coada), urmatorul apel de
|
||||
sincronizeaza() gaseste gresit ca "principal" documentul cu cel mai mic recno ramas si il
|
||||
sparge si pe el - cascada se repeta la fiecare apel ulterior. Fix: dupa popularea `introdc`,
|
||||
INAINTE de `CREATEOBJECT('import_nota', ...)`, adauga exact acelasi `INDEX ON ... TAG ord_doc`
|
||||
+ `SET ORDER TO ord_doc` ca in `achizitie_import`.
|
||||
q. **Suitele de teste NU se ruleaza in paralel**: `_precompile.ps1` face `Get-Process vfp9 |
|
||||
Stop-Process -Force` (omoara TOATE instantele vfp9 de pe masina), deci un test lansat in
|
||||
paralel ucide testul aflat in curs si corupe rezultatele. Ruleaza suitele strict secvential.
|
||||
r. **Fara SELECT-SQL pe cursorul legat de grid**: SELECT ... FROM introdc INTO CURSOR intr-un
|
||||
test, cat timp introdc e RecordSource-ul unui grid viu, poate omori procesul vfp9 silentios
|
||||
(fara eroare catchabila, fara semafor). Foloseste xBase nativ (COUNT FOR ... TO,
|
||||
CALCULATE, LOCATE) care nu comuta zona de lucru a grid-ului.
|
||||
40
docs/testare-vfp-mcp.md
Normal file
40
docs/testare-vfp-mcp.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Testare automata VFP prin IDE + MCP (windows-mcp)
|
||||
|
||||
Valabil pentru toate proiectele VFP din suita ROA; exemplele de mai jos sunt pe ROAGEST —
|
||||
inlocuieste caile, numele programului principal si titlul ferestrei pentru alt proiect.
|
||||
|
||||
Pentru verificare vizuala dupa modificari pe `.vc2`/`.sc2`, nu se porneste `roagest.exe`
|
||||
(ar cere rebuild complet — vezi `COMUN\docs\flux-editare-vfp-text.md`), ci se lanseaza `vfp9.exe`
|
||||
interpretat peste `Programe\roagest.prg`:
|
||||
|
||||
```powershell
|
||||
Start-Process -FilePath "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" `
|
||||
-ArgumentList '-c"D:\ROA\ROAGEST\config.fpw"','D:\ROA\ROAGEST\Programe\roagest.prg' `
|
||||
-WorkingDirectory "D:\ROA\ROAGEST"
|
||||
```
|
||||
|
||||
- Gate-ul de pornire (`gcNumeProgram = 'ROAGEST'` in `roagest.prg`) verifica
|
||||
`JUSTSTEM(SYS(16,0))` — numele programului de la nivelul 0 al stivei, nu numele
|
||||
procesului `.exe`. Rulat interpretat, `SYS(16,0)` = `roagest.prg`, deci gate-ul trece.
|
||||
- Fereastra rezultata are titlul `ROA - Gestiuni` (setat din `NUMEPROGRAM`).
|
||||
|
||||
## Capcana: focus furat de terminal
|
||||
|
||||
Daca sesiunea Claude Code afiseaza output in timp ce comanda de lansare ruleaza,
|
||||
fereastra terminalului/IDE-ului ramane in prim-plan si VFP porneste in fundal —
|
||||
`Screenshot`/`Snapshot` din `windows-mcp` pot raporta "No windows found" desi procesul
|
||||
si fereastra exista (verificabil cu `Get-Process vfp9 | Select MainWindowTitle`).
|
||||
|
||||
Fix: inainte de screenshot, adu explicit fereastra in prim-plan dupa titlu:
|
||||
|
||||
```
|
||||
mcp__windows-mcp__App mode=switch name="ROA - Gestiuni"
|
||||
```
|
||||
|
||||
apoi `Screenshot`. Nu te baza pe enumerarea implicita de ferestre a `windows-mcp` cand
|
||||
ai lansat procesul chiar in runda curenta de comenzi.
|
||||
|
||||
## Curatare dupa test
|
||||
|
||||
Proces de omorat la final: `mcp__windows-mcp__Process mode=kill pid=<pid>` (gasit prin
|
||||
`mode=list name=vfp9` sau `Get-Process vfp9`).
|
||||
Reference in New Issue
Block a user