8.6 KiB
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.pjxin the VFP IDE and use Build > Build Executable to produceroaacnpro.exe. The startup program isPrograme/roaacnpro.prg(set as the project main). .prgfiles are source;.fxpare compiled,.bakare 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..mpris GENMENU-generated from.mnx; never hand-edit.mpr.- Version control is Subversion (
.svn/), not git.COMUN/is its own SVN working copy. config.fpwsets 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 islog.txt. Many entries inroaacnpro.ERRare benign cross-references resolved at runtime fromCOMUNlibraries.
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 -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-levelPrograme/,Clase/,Ferestre/,Rapoarte/,Meniuri/directories. Only touchCOMUN/when the fix genuinely belongs to the shared framework. SET PATH(seePrograme/roaacnpro.prg~line 37) makesCOMUN\CLASE,COMUN\FERESTRE,COMUN\PROGRAME,COMUN\RAPOARTE, and theCOMUN\UTILE\*helper libraries (calendar, ctl32, hpdf PDF, web/HTTP, nfjson, nfxml, excel, GridExtras) resolvable by bare filename. SoSET PROCEDURE TO email.prgresolves toCOMUN\PROGRAME\email.prg.
Application architecture
Startup flow (Programe/roaacnpro.prg):
- Sets
gcAppPath, buildsgcComunPath,SET PATH,SET PROCEDURE TO roa.prg. goApp = CreateObject("oApp")—oAppis a thin subclass ofRoaApp(COMUN/programe/roa.prg, ~1200 lines). This is the application object and the backbone of the whole framework.goApp.initializeaza(...)runs an orderedinitializeaza*pipeline: program check, read login params, Win32 declares, env, paths, class libs, procedures, settings ini, security (Oracle host/credentials, decrypted fromroa_security.xml), report previewer, locale, variables, and global objects.goApp.lanseazaAplicatie()shows_screen, runs the startup menu +fundal.scxshell form.READ EVENTS— VFP event loop.onShutDownhandles 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 withSQLEXEC()against the connection handle; results come back as VFP cursors. database.txtdocuments the Oracle setup: it creates synonyms (ips_voyages,ips_berthings,ips_cargoes, …) into the externalrorisschema andGRANTs to the app user. Theips_*tables are RORIS source data;ips_*_vanzariand the app's own tables hold billing data.versiune_db.txttracks 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(stringTIP_*and numericNTIP_*, e.g.NTIP_TRANZIT 0,NTIP_CHEIAJ 1). These same defines are repeated at the top ofPrograme/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 (formfrm_factura→factura_salvare_db→PACK_FACTURARE.pck→ reports/list), thecrsFacturastructure, the VAT formulas, and which files to touch for a given task. Key rule:PACK_FACTURARE.pckis the source of truth; thefrm_facturapreview must mirror its formulas, and reports/list only read package-computed values.Programe/proceduri_acnpro_rapoarte.prg— report-generation procedures feeding theRapoarte/*.frxlayouts (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.