Skip to content

About

Consignment Software built using JavaFX, SQLite, Jasper reports

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Repository files navigation

OpenConsignment

Build Release License: GPL v3 Java 17 JavaFX 17

Logo

OpenConsignment is a JavaFX desktop application for managing consignment sale data — buyers, suppliers, transports, bills, collections, and payments — with SQLite storage and PDF ledger reports.

Features

  • Master data — maintain buyers, suppliers, and transports.
  • Bill entry — record consignment bills, including LR (lorry receipt) details, with an editable history view.
  • Collections & payments — record buyer collections and supplier payments against pending bills, with dedicated history views.
  • Ledger reports — generate buyer, supplier, and transport ledgers as PDFs (via JasperReports), including agewise-outstanding variants.
  • Local-first storage — data is kept in a local SQLite database (database.db), with helper scripts to configure backups to a private Git repository (see Backups).

Tech stack

  • Java 17, JavaFX 17
  • Dagger 2 for dependency injection (see src/main/java/openconsignment/di)
  • SQLite (via sqlite-jdbc) for storage
  • JasperReports for PDF report generation
  • SLF4J with Log4j 2 for asynchronous rolling-file logging
  • Gradle (Kotlin DSL) with the Shadow plugin for a single runnable JAR
  • JUnit 5, Mockito, and TestFX for testing; Spotless (palantir-java-format) for formatting; JaCoCo for coverage

Getting started

Prerequisites

  • JDK 17, with java available on your PATH.
  • A graphical desktop environment to run the application, and a PDF viewer to open generated reports.

The repository includes the Gradle wrapper; a separate Gradle installation is not required. Gradle resolves JavaFX dependencies when running from source.

Run from source

./gradlew run

Run commands from the repository root. On Windows, use gradlew.bat in place of ./gradlew.

Build a runnable JAR

./gradlew shadowJar

This produces build/libs/OpenConsignment.jar and copies the launch scripts, backup configuration script, and backup templates into build/libs/. The launch scripts require a separate JavaFX 17 SDK matching your operating system and CPU architecture.

On macOS/Linux, the launcher defaults to ~/javafx-sdk-17.0.19/lib:

bash build/libs/start.sh

To use a different SDK location, set JAVAFX_MODULE_PATH to its lib directory:

JAVAFX_MODULE_PATH="/path/to/javafx-sdk-17/lib" bash build/libs/start.sh

On Windows, edit build/libs/start.bat to match your local Java and JavaFX installations, then run it from build/libs/:

cd build\libs
start.bat

The batch script currently sets Java to C:\Program Files\Java\jdk-17 and the JavaFX module path to %USERPROFILE%\javafx-sdk-17.0.18\lib. Keep the JAR and launch script together when moving the application.

Data and reports

  • The application creates and initializes database.db in its working directory using src/main/resources/sql/init.sql.
  • Repository queries live in domain-specific folders under src/main/resources/sql (for example, bill/get.sql). Paths are registered in the SqlQuery enum and loaded with SqlLoader.load(SqlQuery.BILL_GET), using UTF-8 decoding and caching. When adding a query, add its SQL file and enum entry; tests verify that every entry has a non-empty resource.
  • Running ./gradlew run uses the repository root; the packaged launch commands above use build/libs/. Each location has its own database.
  • Reports are written to report.pdf in the working directory, replacing the previous report, and opened with the system's default PDF viewer.

Application configuration

At startup, the application reads UTF-8 application.yaml beside the JAR, regardless of the current working directory. If this file does not exist, the application copies src/main/resources/application.yaml from inside the JAR to that location and loads the new file. Existing configuration files are never overwritten.

Edit the generated file to set your organization name:

organizationName: "YOUR ORGANIZATION"

This name appears on the welcome screen and in buyer, supplier, and transport ledger reports. The bundled YAML is used only as the template for first-run creation; properties are not merged or filled in from it when an external file already exists. YAML is bound directly to configuration POJOs using SnakeYAML. Quote the name to preserve its exact text; scalar values such as numbers are converted to strings. Surrounding whitespace is trimmed. A blank or null name, malformed YAML, or an unreadable configuration file is reported as a startup error. An empty file or missing required property also fails validation. The application needs write access to the JAR directory when creating the file for the first time.

For Gradle/IDE runs, the file is created and read in the working directory (the repository root for ./gradlew run). The example file is included in build/libs/ when building. Restart the application after editing the file. Updating the JAR does not replace an existing configuration file.

Logging

The application writes INFO and higher messages to stderr and to logs/openconsignment.log in its working directory. Application logging uses SLF4J directly with Log4j 2 as its backend, including exception stack traces. Use SLF4J's LoggerFactory and parameterized messages in application code.

The file is rolled at startup, daily, or when it reaches 10 MB. Archives are compressed; during rollover, archives older than 30 days or beyond 100 MB total are deleted. The active file is separate from that archive limit. File writes use a bounded asynchronous queue; if it fills, callers wait rather than dropping messages. The queue is drained on normal JVM shutdown. An abrupt termination may lose queued messages. Log4j reports file setup problems to stderr, where console logging remains available.

The working directory is the repository root when using ./gradlew run and build/libs when using the supplied launch scripts. To use a different directory or file size, pass JVM properties, for example:

java -Dopenconsignment.logDir=/path/to/logs -Dopenconsignment.logSize="20 MB" ...

Configure these options in the launch script when running the packaged JAR. Use a separate log directory for each simultaneous application instance; the rolling files are not coordinated across processes. Log files can contain exception details, so restrict access and review them before sharing.

Testing

./gradlew test
  • Unit tests (src/test/java/openconsignment/service, .../repository) cover the service layer (mocked repositories, mocked static Utils.generatePdf calls) and the repository layer (real in-memory SQLite, schema-initialized from src/main/resources/sql/init.sql).
  • Functional tests (src/test/java/functional) use TestFX to smoke-test the JavaFX UI and check bill-entry layout.

Tests run headlessly by default. To debug with visible JavaFX windows:

./gradlew test -PheadlessTests=false

To run a specific group of tests:

./gradlew test --tests 'openconsignment.service.*'
./gradlew test --tests 'openconsignment.repository.*'
./gradlew test --tests 'functional.*'

Every test run also produces a JaCoCo coverage report at build/reports/jacoco/test/html/index.html. The test results are available at build/reports/tests/test/index.html.

Code style

Formatting is enforced by Spotless and checked on every build (spotlessJavaCheck). To auto-format:

just format
# or: ./gradlew spotlessApply

Project structure

src/main/java/openconsignment/
├── di/           Dagger modules and components (wires the object graph,
│                 including JavaFX's controller factory)
├── controller/   JavaFX FXML controllers, grouped by feature area
├── service/      Business logic, one per domain (bill, buyer, supplier, ...)
├── repository/   JDBC/SQL access, one per domain
├── entity/       Persistence-shaped data classes
├── model/        Read-model/report row classes (ledgers, etc.)
└── common/       Shared utilities (PDF generation, constants, ...)
src/main/resources/
├── fxml/         JavaFX view definitions
├── jrxml/        JasperReports report templates
├── css/          Shared and feature-specific stylesheets
├── icons/        Application and toolbar icons
└── sql/          Database schema (init.sql)
src/test/java/
├── openconsignment/  Service, repository, and dependency-injection tests
└── functional/       JavaFX UI tests
scripts/              Launchers and financial-year backup helpers
gradle/libs.versions.toml  Dependency and plugin versions

Backups

scripts/configure-backup.py generates year-scoped upload/download scripts (from scripts/templates) for backing up database.db to a private, per-financial-year Git repository. It requires Python 3, Git, and SSH access to the backup repository. The repository must already exist; the script clones it rather than creating it.

The repository owner is currently hard-coded as drcbabu81 in configure-backup.py, with repository names such as Satyam-Database-2026-27. Update the owner for your deployment.

After building the JAR, run the configuration script from build/libs/ so it can find templates/ and create the helpers beside database.db:

cd build/libs
python3 configure-backup.py

Enter a financial year such as 2026-27 when prompted. On Windows, use python configure-backup.py from the same directory. The script generates upload.sh/download.sh on macOS/Linux or upload.bat/download.bat on Windows. Run the generated helpers from that directory.

Review the templates before use: the shell upload template currently uses a Windows-style separator in its database copy destination, which needs adjusting for macOS/Linux. The download helper replaces the local database.db with the repository copy. Backup scheduling is managed separately.

CI/CD

GitHub Actions builds and tests every push/PR (.github/workflows/build.yml). Pushing a v* tag builds and publishes a shadow JAR to a GitHub Release (.github/workflows/release.yml).

License

GPL-3.0

About

Consignment Software built using JavaFX, SQLite, Jasper reports

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages