# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this is

ROAGEST is a **Visual FoxPro 9** desktop application (Romanian-language) for **gestiune de stocuri și mărfuri** — goods/inventory management: purchases (`achiziție`, NIR — *notă intrare recepție*), sales, warehouse transfers, stock (`stoc`), consumption vouchers (`bon consum`), inventory counts (`inventar`), price changes (`schimbare preț`), and cash-register (`casă de marcat`, e500/mp500) integration. It backs onto an **Oracle** database (`gcS` schema, default `CONTAFIN`) reached through the shared `goExecutor`/`goConn` SQL pass-through objects. It is one member of the larger "ROA" suite built by ROA Romfast SRL (ROAACNPRO, ROAIMOB, ROACONT, ROACASA, ROADEF, etc.) and lives alongside its siblings under `D:\ROA`.

The code, comments, menus, and changelog are all in Romanian — match that language when editing user-facing strings, comments, and changelog entries.

**Architecturally, ROAGEST is older-generation than ROAACNPRO/ROAIMOB**: those apps instantiate `oApp` as a subclass of the shared `RoaApp` framework class (`COMUN/programe/roa.prg`) with an ordered `initializeaza*` method pipeline. ROAGEST does **not** use `RoaApp` at all — `COMUN/programe/roa.prg` exists in this repo (vendored, shared with the other apps) but is unreferenced. Instead, `Programe/roagest.prg` is a long, monolithic startup script that manually chains `SET PATH`/`SET CLASSLIB ... ADDITIVE`/`SET PROCEDURE ... ADDITIVE` statements and instantiates `goApp = CREATEOBJECT("wzApplication")` — the classic VFP "Application Wizard" base class (defined in `COMUN/clase/appwiz.vcx`). Don't assume the `RoaApp`/`initializeaza*` conventions documented for ROAACNPRO/ROAIMOB apply here.

## Build, run, version control

- **Build/run requires the Visual FoxPro 9 IDE on Windows.** There is no command-line build. Open `roagest.pjx` in the VFP IDE and use *Project > Build* to produce `roagest.exe`. The startup program is `Programe/roagest.prg`.
- **`.prg` files are source; `.fxp`/`.FXP` are compiled, `.BAK` are backups.** Edit the `.prg`. The `.scx/.sct` (forms), `.vcx/.vct` (class libraries), `.frx/.frt` (reports), and `.mnx/.mnt`/`.mpr` (menus) are VFP binary/generated artifacts — **edit them in the VFP IDE, not by hand.** `.mpr`/`.mpx` are GENMENU-generated from `.mnx`; never hand-edit them.
- **SVN remains the "live" source of truth**, especially for `COMUN/` — use `svn`, not `git`, for the authoritative history. A **git** repo now runs in parallel (see "Version control: git alongside SVN" below).
- **`config.fpw`** sets the runtime environment (`CODEPAGE=1252`, `EXCLUSIVE=OFF`, `SAFETY=OFF`, `MULTILOCKS=ON`, `TALK=OFF`). Don't enable `SAFETY` — the code relies on silent overwrite. `Programe/roagest.prg` re-asserts most of these plus `SET DATE TO DMY`, `SET DECIMALS TO 4`, `SET EXACT ON`.
- `roagest.exe` refuses to start unless its own filename matches `gcNumeProgram = 'ROAGEST'` (`IF !LIKE(gcNumeProgram + '*', ...)` near the top of `roagest.prg`) — a guard against running a renamed/copied executable.
- The compiler error log is `roagest.ERR`; the runtime log is `log.txt`. `roagest.Stats` and `versiune_db.txt` (format `YYYY_MM_DD_NN`, e.g. `2026_01_21_02`) track build/DB-schema stamps checked against the update server on launch (`COMUN/programe/oupdate.prg`, `wwcodeupdate.prg`).
- `Programe/cont2000.prg` is a near-duplicate of `roagest.prg` (same startup pattern, older `CONT2000` naming) still present in the tree — treat it as legacy/reference, not the active entry point, unless you confirm otherwise from `roagest.pjx`'s main-file setting.

## Version control: git alongside SVN

Git rulează în paralel cu SVN-ul legacy, nu îl înlocuiește. SVN rămâne sursa "vie" pentru `COMUN/`, sincronizat manual către git; nu rula comenzi `svn` din git și nu presupune că git-ul e la zi cu ultimele modificări SVN dacă nu a fost sincronizat explicit.

- Repo-ul principal (rădăcina acestui folder) e propriul lui `.git`, cu remote `git@gitea.romfast.ro:romfast/roagest.git`. `.gitignore` exclude `COMUN/` (gestionat separat, vezi mai jos), `.svn/`, artefactele VFP compilate (`*.fxp`, `*.bak`, `*.mpr`, `*.exe`, …) și fișierele Windows uzuale.
- `COMUN/` are propriul `.git` separat, cu remote `git@gitea.romfast.ro:romfast/comun.git` — **același repo partajat de toate aplicațiile ROA** (ROAACNPRO, ROAIMOB, etc.). O modificare împinsă acolo afectează toate proiectele. Nu face `push --force` peste `comun.git` fără aprobare explicită — ar șterge istoric comun tuturor proiectelor.
- Căutarea în cod VFP binar (`.vcx`/`.scx`) pentru acest proiect folosește `vcx2txt.ps1` parametrizat pentru ROAGEST (vezi secțiunea de mai jos) — cache separat, `_textcache_roagest`, nu-l amesteca cu cache-urile altor proiecte.

## Searching code inside `.vcx`/`.scx` (binary) libraries

Most class/form code lives **inside binaries** (`.vcx`+`.vct`, `.scx`+`.sct`, …), not in `.prg`, so plain grep can't read it cleanly. To search method/procedure bodies, convert the binaries to their TEXT form first and grep the text, using the shared `foxbin2prg` tool already built at `D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE`:

```powershell
& 'D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1' -Project 'D:\ROA\ROAGEST\roagest.pjx' -ProjectRoot 'D:\ROA\ROAGEST' -CacheRoot 'D:\ROA\UTIL\foxbin2prg\_textcache_roagest' -Types vcx,scx,frx,mnx
```

This reads the file list straight from `roagest.pjx`, so it only converts the `.vcx`/`.scx`/`.frx`/`.mnx` this project actually references — not all of `COMUN\` (most of which is unused by any one app). It's incremental and safe to re-run after IDE edits. Output lands in `_textcache_roagest/` as `.vc2`/`.sc2`/`.fr2`/`.mn2` text mirrors — `Grep` those. The text is **only for reading/search** — make real edits in the VFP IDE, then re-run the script to refresh the cache.

## The COMUN shared framework

`COMUN/` is **shared, framework-level code used by every ROA app** — it is not specific to ROAGEST. Treat it as a vendored library:

- A change in `COMUN/` affects all ROA applications. Prefer making app-specific changes in this repo's top-level `Programe/`, `Clase/`, `Ferestre/`, `Meniuri/`, `Rapoarte/` directories. Only touch `COMUN/` when the fix genuinely belongs to the shared framework.
- Unusually for this app, **most of the actual "gestiune" business logic lives in `COMUN/programe/`, not in this repo's own `Programe/`.** ROAGEST's own `Programe/` folder has only ~24 files (`roagest.prg`, `gestiuni.prg`, `cont2000.prg`, `oimportdinxml.prg`, `ofactureaza.prg`, `exportare.prg`, `fisa_ob_inventar.prg`, `update_nomenclator.prg`, `suma_in_vorbe.prg`, `actualizari.prg`, `cumplun-furn.prg`, `inchidere_k.prg`, `ovariabile_globale.prg`, `shutdown.prg`), while the core stock/article/movement procedures — `oproceduri_stocuri.prg`, `oproceduri_articole.prg`, `oproceduri_rulaje.prg`, `oproceduri_casademarcat.prg` (+ `_e500`/`_mp500` cash-register variants), `oproceduri_facturare.prg`, `oproceduri_obinv.prg` (fixed-asset-in-use items), `anaf_efactura.prg` (ANAF e-Factura), `osecurity.prg`, `oproceduri_configurare.prg`, `oproceduri_listari.prg`, `oproceduri_retete.prg`, `orapoarte.prg` — all resolve from `COMUN/programe/` via `SET PATH`. Likewise most class libraries used (`onomenclatoare`, `stocuri.vcx`, `rulaje.vcx`, `ointroduceri*`, `oinventar`, `orapoarte_gestiuni`, `bon_fisc`, `onom_articole`, `onom_retete`, `ferestre_oracle`, `configurare.vcx`, `serii_numere.vcx`, …) live in `COMUN/clase/`, not this repo's `Clase/`.
- ROAGEST's **own** `Clase/` folder is small: `gestiuni.vcx`, `oavize.vcx`, `oimportxml.vcx`, `orapoarte_gestiuni.vcx`, `ovizrul.vcx`, `atentie.vcx`. Its own `Ferestre/` is also small: `fundal.scx` (shell form), `accesindivid.scx`, `frm_conversii.scx`, `frm_schimbare_pret_tva.scx`. The bulk of forms actually used are `COMUN\ferestre\*` (e.g. login is `COMUN\ferestre\frm_login.scx`).
- `SET PATH` (see `Programe/roagest.prg` ~line 109) makes `COMUN\CLASE`, `COMUN\FERESTRE`, `COMUN\PROGRAME`, `COMUN\GRAFICE`, `COMUN\RAPOARTE`, `COMUN\MENIURI`, and the `COMUN\UTILE\*` helper libraries (GridExtras, ctl32, hpdf/ReportOutput, web, Excel) resolvable by bare filename, plus a sibling `..\COMUNROA\` directory (built from `gcAppPath`'s grandparent). So `SET PROCEDURE TO email.prg` resolves to `COMUN\PROGRAME\email.prg`.

## Application architecture

Startup flow (`Programe/roagest.prg`, procedural — no `oApp`/`RoaApp` object wraps it):

1. Verifies the running exe is actually named `ROAGEST*`; sets `SET CENTURY/DELETED/DATE/EXACT/...` environment options.
2. Computes `gcAppPath` (own folder) and `gcDirMare`/`dirgen` (suite root, one level up — e.g. `D:\ROA\`), builds the long `SET PATH TO` string across its own folders + `COMUN\*` + `..\COMUNROA\`, then issues **dozens of ordered** `SET CLASSLIB ... ADDITIVE` and `SET PROCEDURE ... ADDITIVE` statements (order matters: later `ADDITIVE` registrations can shadow earlier same-named procedures/classes).
3. Parses the launch parameter string (`tparam`, semicolon-delimited: `host;user;password;idutil;idprogram;...;an;luna;schema;idfirma`) when launched by the central ROA launcher; otherwise falls back to hardcoded dev defaults (`JCSSERVER`/`CONTAFIN_ORACLE`).
4. Sets up cross-cutting globals: `goLog`/`poLog` (`Log_Mesaje.prg`), `goLocale` (Romanian by default, `glTraducere = .F.` — translation path largely dormant), `goExecutor`/`goConn` (Oracle SQL pass-through), `goExport`, `goMyXMLHTTP` (remote error reporting), and an optional `goKeepAlive` timer (avoids ODBC idle timeouts).
5. `NUMEPROGRAM = 'ROA - Gestiuni'`, `_program = 'gest'`; reads the actual version string from the built `.exe`'s file version resource.
6. Registers `ON SHUTDOWN ShutDown()` / `ON ERROR ErrorHandler(...)`, instantiates `goApp = CREATEOBJECT("wzApplication")`, sets `goApp.cStartupMenu` to `Meniuri\roagest.mpr` and `goApp.cStartupForm` to `COMUN\ferestre\frm_login.scx`, then `goApp.SHOW` — this is the VFP event loop entry (AppWizard's `Show`/`Run` machinery), analogous to `READ EVENTS` in the newer apps.
7. `ErrorHandler` posts errors to a remote endpoint via `goMyXMLHTTP.postError(...)` (host read from `settings.ini`'s `[errors] host` key) in addition to showing `AMESSAGEBOX`. `Cleanup()`/`ShutDown()` release class libs, procedures, and the menu stack on exit.

### Globals convention

Same `g`/`gc`/`gn`/`gl` Hungarian-ish prefixing as the rest of the suite (`g` = global, `gc`/`gn`/`gl` = char/numeric/logical, `m.` = memory-variable scoping), declared `PUBLIC`/`PRIVATE` directly in `roagest.prg` rather than promoted by a framework object:

- `goApp` (AppWizard app object), `goConn`/`goExecutor` (Oracle connection + SQL executor), `goLog`/`poLog` (logger), `goLocale`, `goExport`, `goCalendar`, `goFirma`.
- `gcS` = Oracle schema (default `CONTAFIN`), `gnIdFirma`, `gnAn`/`gnLuna` (working year/month), `gcAppPath` (this app's folder), `gcDirMare`/`dirgen` (suite root, e.g. `D:\ROA\`), `gcSecurityPath`/`gcSecurityFile` (`DIRGEN + 'Security\ROA_SECURITY.TXT'`), `gcGeneralIniFile`/`gcSettingsFile` (`DIRGEN + 'settings.ini'`).
- Legacy holdovers from the pre-Oracle (`CONT2000`) codebase are still declared even though mostly unused now: `nror[65000]`, `RTVA[22,2]`, `SER_PERM`/`SER_PERI`/`VERSIUNE` (commented out), old disk-serial license-check functions (`decodare1`, `HEXDEC`, `DECTOBIN`, the commented-out `PORNIRE`/`verif_ser_perm`) — dead code kept for reference, not active.

### Data layer

- Backend is **Oracle**, reached via `goConn`/`goExecutor` (created from the `DECABAZA` classlib, same pattern as the sibling apps) — run queries with `SQLEXEC()`/the executor wrapper; results come back as VFP cursors.
- Domain tables/views follow Romanian/domain naming: `stoc`, `rulaje`/`rull` (stock movements), `act` (documents/NIR), `articole`/nomenclator, `gestiuni` (warehouses/locations), `casa de marcat` bon fiscal tables. Look in `COMUN/programe/oproceduri_stocuri.prg`, `oproceduri_articole.prg`, and `oproceduri_rulaje.prg` for the canonical query/view names (e.g. `viz_stocuri` filters on `an`, `luna`, `id_sucursala`, `id_gestiune`).
- `Initializari/` holds XML templates for cash-register integrations (`roagest_bon.xml(.tmpl)`, `roagest_mp500.xml(.tmpl)`, `euro500t.txt(.tmpl)`, `euro500t_erori.xml(.tmpl)`).
- `Locale/` is a full VFP database (`locale.dbc` + `.dbf`/`.cdx`) for the (largely dormant) translation feature, not just an .ini.

## Domain quick reference

- **No app-specific `.h` include** defines domain constants the way `roaacnpro.h` does for ROAACNPRO — `Include/CONT2000.H` is just a historical comment (a class-tree diagram from the old `CONT2000` codebase), and `Include/foxpro.h` is the stock VFP header. Domain behavior (document types, movement signs, VAT handling) is expressed directly in procedure logic in `COMUN/programe/oproceduri_*.prg`, not centralized constants — expect to trace behavior through those procedures rather than a single defines file.
- **`Rapoarte/*.frx`** (24 report layouts in this repo, more resolved from `COMUN\RAPOARTE`) name the real workflows: `rap_nirtransfer_achi` (NIR/transfer receiving), `rap_centralizator_intrari`/`_intrari2`, `rap_centralizator_iesiri`/`_iesiri2` (in/out summaries), `rap_fisa_magazie_fifo` (FIFO stock card), `rap_gest_val_subgrupe`/`_gestc` (valued stock by subgroup), `rap_vechime_stocuri` (stock aging), `rap_marfuri_lista_centr`/`_desf`/`_valoric` (goods lists), `rap_vanzari_comp_cant`/`_val`/`_web` (sales comparisons), `rap_instiintaripret` (price-change notices), `rap_inchidere_k`, `rap_stoc_obinv` (inventory-use objects), `rap_rul_consum_lucrari_articole`/`_centralizator_consum_lucrari` (consumption vouchers).
- **`Meniuri/`** menu names map to the app's top-level operations: `achi*` (achiziții/purchases), `vanz*` (vânzări/sales), `consum*` (bon consum), `transfer*` (stock transfers), `config*` (configurare), `casademarcat`/`casamarcat` (fiscal cash registers), `obinvent` (obiecte de inventar), `stoc`, `rulaje`, `list*`/`rapoarte` (reports), `roagest.mnx`/`.mpr` (the root startup menu, referenced by `goApp.cStartupMenu`).
- **`todo.txt`** is an informal running work list (Romanian, `ok`/`OK`-prefixed = done, otherwise pending) — recent items concern store inventory (`inventar magazin`), FIFO stock cards, and VAT-rate handling during the 19%→21% transition; useful as a quick pulse on active/recent pain points but not authoritative documentation.
- **VAT/TVA** is time-sensitive here too: recent changelog entries (v2.11.0–2.11.2) explicitly prepare the app for the 21%/11% rates effective 2025-08-01 while still supporting 19%/9%/5% for prior periods — the same "rate by document period, not 'current' rate" caution as the other ROA apps applies.
- **Cash register / fiscal integration**: `oproceduri_casademarcat.prg`, `oproceduri_casa_marcat_e500.prg`, `oproceduri_casa_marcat_mp500.prg` (in `COMUN/programe/`) integrate specific fiscal printer/cash-register protocols (E500, MP500); `Initializari/roagest_bon.xml`/`roagest_mp500.xml` are their config templates.
- **ANAF e-Factura / SAFT**: `COMUN/programe/anaf_efactura.prg` provides e-invoicing against ANAF, shared with sibling apps.

## Changelog & release convention

`changelog_roagest.txt` is the user-facing release log (188KB, going back to v1.0.x). **Newest entry goes at the top**, in this exact HTML-comment block format (Romanian, `DD/MM/YYYY`):

```
<!--
21/01/2026
ROAGEST - 2.11.5

:nou:
  <what changed>

:modificare:
  <what changed>
-->
```

Tags in use: `:nou:` (new feature), `:modificare:` (change), `:eroare:` (bug fix), and occasionally `:adaugare:` (addition) — match this exact tag vocabulary (a lone historical `:modfiicare:` typo exists; don't repeat it). Bump the `MAJOR.MINOR.PATCH` version (currently `2.11.5`) when you add an entry. The app checks for updates on startup (`COMUN/programe/oupdate.prg`, `wwcodeupdate.prg`) against `versiune_db.txt`'s schema stamp; the runtime reads its own version from the built `.exe`'s file version resource.

## Project insights (docs/)

`docs/` holds short, concrete notes discovered while working on real tasks — hidden flows, gotchas, key procedures/packages, relevant tables — that go beyond what this file covers. See `docs/README.md` for the index. **Proactively offer to update `docs/` whenever you uncover a non-obvious project insight while fixing a bug or investigating a flow** (don't wait to be asked), so future sessions can reuse it instead of re-investigating from scratch. Keep entries concise and factual — no restating what's obvious from reading the code.
