# 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 <file|folder>` (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`):

```
<!--
10/02/2026
ROAACNPRO - 2.0.3

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

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`.
