# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What this is ROAACNPRO is a **Visual FoxPro 9** desktop application (Romanian-language) for port/lock operations billing on the Danube. It invoices the service types defined in `Include/roaacnpro.h`: `TRANZIT` (transit), `CHEIAJ` (wharfage), `APA` (water), `CHIRII` (rentals), `PILOTAJ` (pilotage), `PENALITATI` (penalties), `ALTE`/`DIVERSE` (other). It is one member of the larger "ROA" suite (ROAGEST, ROACONT, ROACASA, ROADEF, etc.) and reads vessel/ voyage/lock data from the external **RORIS Oracle** system. The code, comments, menus, and changelog are all in Romanian — match that language when editing user-facing strings, comments, and changelog entries. ## Build, run, version control - **Build/run requires the Visual FoxPro 9 IDE on Windows.** There is no command-line build. Open `roaacnpro.pjx` in the VFP IDE and use *Build > Build Executable* to produce `roaacnpro.exe`. The startup program is `Programe/roaacnpro.prg` (set as the project main). - **`.prg` files are source; `.fxp` are compiled, `.bak` are backups.** Edit the `.prg`. The `.scx/.sct` (forms), `.vcx/.vct` (class libraries), `.frx/.frt` (reports), and `.mnx/.mpr` (menus) are VFP binary/generated artifacts — **edit them in the VFP IDE, not by hand.** `.mpr` is GENMENU-generated from `.mnx`; never hand-edit `.mpr`. - **Version control is Subversion** (`.svn/`), not git. `COMUN/` is its own SVN working copy. - **`config.fpw`** sets the runtime environment (CODEPAGE 1252, `EXCLUSIVE=OFF`, `SAFETY=OFF`, `MULTILOCKS=ON`). Don't enable SAFETY — the code relies on silent overwrite. - The compiler error log is `roaacnpro.ERR`; the runtime log is `log.txt`. Many entries in `roaacnpro.ERR` are benign cross-references resolved at runtime from `COMUN` libraries. ## 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. **At the start of a session (when work may touch classes/forms), refresh the text cache** by running the helper, then search in the cache: ```powershell powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 # incremental ``` By default it is **project-driven**: it reads `roaacnpro.PJX` and converts only the `.vcx`/`.scx` the project actually uses (~78 files), **not** all of `COMUN\` (most of which is unused). It writes a mirrored, read-only text tree to `D:\ROA\UTIL\foxbin2prg\_textcache\` (e.g. `_textcache\Clase\oacnpro.vc2`, `_textcache\comun\clase\_frm_base.vc2`); then `Grep` there. Useful flags: `-Types vcx,scx,frx,mnx` (also reports/menus), `-Source ` (one-off, even outside the project), `-Force`, `-Clean`. The text is **only for reading/search** — edit code in the VFP IDE. Full guide: **`docs/cautare_vcx_vct.md`**. ## The COMUN shared framework `COMUN/` (and the sibling `..\COMUNROA\`) is **shared, framework-level code used by every ROA app** — it is not specific to ROAACNPRO. 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/`, `Rapoarte/`, `Meniuri/` directories. Only touch `COMUN/` when the fix genuinely belongs to the shared framework. - `SET PATH` (see `Programe/roaacnpro.prg` ~line 37) makes `COMUN\CLASE`, `COMUN\FERESTRE`, `COMUN\PROGRAME`, `COMUN\RAPOARTE`, and the `COMUN\UTILE\*` helper libraries (calendar, ctl32, hpdf PDF, web/HTTP, nfjson, nfxml, excel, GridExtras) resolvable by bare filename. So `SET PROCEDURE TO email.prg` resolves to `COMUN\PROGRAME\email.prg`. ## Application architecture Startup flow (`Programe/roaacnpro.prg`): 1. Sets `gcAppPath`, builds `gcComunPath`, `SET PATH`, `SET PROCEDURE TO roa.prg`. 2. `goApp = CreateObject("oApp")` — `oApp` is a thin subclass of **`RoaApp`** (`COMUN/programe/roa.prg`, ~1200 lines). This is the application object and the backbone of the whole framework. 3. `goApp.initializeaza(...)` runs an ordered `initializeaza*` pipeline: program check, read login params, Win32 declares, env, paths, class libs, procedures, settings ini, **security** (Oracle host/credentials, decrypted from `roa_security.xml`), report previewer, locale, variables, and global objects. 4. `goApp.lanseazaAplicatie()` shows `_screen`, runs the startup menu + `fundal.scx` shell form. 5. `READ EVENTS` — VFP event loop. `onShutDown` handles exit. **App-specific overrides** live in `oApp` at the bottom of `Programe/roaacnpro.prg`: the empty hook methods `initializeazaAlteClassLib` / `initializeazaAlteProceduri` are where this app loads its own class libraries (`oacnpro.vcx`, `ofacturare_comun.vcx`, `serii_numere.vcx`, …) and procedure files (`proceduri_acnpro.prg`, `ofacturare.prg`, `xmlefactura.prg`, …). When adding a new class library or procedure file to the app, register it in one of these two methods — that is the canonical extension point. ### Globals convention The framework promotes the `RoaApp` properties into **public global variables** in `initializeazaVariabileGlobale` / `initializeazaObiecteGlobale`. These are used pervasively throughout the codebase: - `goApp` (the app object), `goConn`/`goExecutor` (Oracle connection + SQL executor), `goLog`/`poLog` (logger), `goCalendar`, `goExport`, `goFundal` (shell form), `goFirma`, `goUtilizator`. - `gcS` = Oracle schema, `gnIdFirma`, `gnIdUtil`, `gnAn`/`gnLuna` (working year/month), `gcAppPath`, `gcDirMare` (suite root), `gcComunPath`. - `g`-prefix = global, `gc`/`gn`/`gl` = char/numeric/logical, `m.` = memory-variable scoping. ### Data layer - Backend is **Oracle**, reached via ODBC/SQL pass-through through `goConn`/`goExecutor`. Run queries with `SQLEXEC()` against the connection handle; results come back as VFP cursors. - `database.txt` documents the Oracle setup: it creates **synonyms** (`ips_voyages`, `ips_berthings`, `ips_cargoes`, …) into the external `roris` schema and `GRANT`s to the app user. The `ips_*` tables are RORIS source data; `ips_*_vanzari` and the app's own tables hold billing data. `versiune_db.txt` tracks the DB schema version. - App tables and report cursors carry Romanian/domain names (`tranzit`, `cheiaj`, `factura`, `recapitulatie`, `tarife`, `contracte`). ## Domain quick reference - **Service-type constants** are in `Include/roaacnpro.h` (string `TIP_*` and numeric `NTIP_*`, e.g. `NTIP_TRANZIT 0`, `NTIP_CHEIAJ 1`). These same defines are repeated at the top of `Programe/proceduri_acnpro.prg`. - **`Programe/proceduri_acnpro.prg`** — core billing procedures (`factura_salvare_db`, `calcul_cheiaj`, `salvare_cheiaj`, `make_factura_penalitati`, TVA/VAT handling, …). The file header is an append-only dated change journal; follow that style when adding procedures. - **`docs/facturare.md`** — read this first for any **invoice/billing change**: it maps the invoice flow (form `frm_factura` → `factura_salvare_db` → `PACK_FACTURARE.pck` → reports/list), the `crsFactura` structure, the VAT formulas, and which files to touch for a given task. Key rule: `PACK_FACTURARE.pck` is the source of truth; the `frm_factura` preview must mirror its formulas, and reports/list only read package-computed values. - **`docs/fluxuri_calcul_facturare.md`** — the end-to-end billing chain (Import → Calcul → Salvare → Listare) documented per service type (tranzit, cheiaj, chirii, penalități, apă, diverse): where source data is imported from (RORIS/`ips_*`), the exact value/coefficient formulas and roundings, where results are persisted, and what reports/recapitulations read back. Read this to find which file:line computes a given value. Includes a "Capcane cunoscute" section (e.g. the distance-coefficient rounding that zeroes sub-32m distances). - **`Programe/proceduri_acnpro_rapoarte.prg`** — report-generation procedures feeding the `Rapoarte/*.frx` layouts (factura, recapitulatie_cheiaj/tranzit/penalitati, registru tranzit). - **`Programe/importroris*.prg`** + `importroris.pjx` — a *separate* small executable (`importroris.exe`) that imports voyage/lock data from RORIS. `verificare_roris_ecluze.*` is another standalone verification tool. These build independently of the main project. - **VAT/TVA** is first-class and time-sensitive: the app supports multiple concurrent VAT-rate regimes (e.g. 19/9/5% historical vs. 21/11% from 2025-08-01). Be careful that billing logic selects rates by the document's period, not "current" rates. ## Changelog & release convention `changelog_roaacnpro.txt` is the user-facing release log. **Newest entry goes at the top**, in this exact HTML-comment block format (Romanian, `DD/MM/YYYY`): ``` ``` Tags: `:nou:` (new feature), `:modificare:` (change), `:eroare:` (bug fix). Bump the `MAJOR.MINOR.PATCH` version when you add an entry. The app auto-updates from `https://www.romfast.ro/...` via `COMUN/programe/actualizare_aplicatie.prg`; the runtime reads its version from the built `.exe`.