From f72980f63b397571c8c9f783efbb9a2651906e88 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Tue, 10 Nov 2026 22:06:57 +0530 Subject: [PATCH 01/13] feat: added jgit as dependency Signed-off-by: Rajdeep Roy Chowdhury --- .github/workflows/build.yml | 62 ++--- build.gradle.kts | 2 + gradle/libs.versions.toml | 113 ++++---- .../openconsignment/common/AppConfig.java | 5 +- .../controller/MainController.java | 60 ++++- .../controller/WelcomeScreenController.java | 2 +- .../service/BackupService.java | 63 +++++ .../openconsignment/service/BuyerService.java | 2 +- .../service/SupplierService.java | 2 +- .../service/TransportService.java | 2 +- src/main/resources/fxml/Main.fxml | 241 +++++++++++------- .../resources/fxml/report/BuyerLedger.fxml | 9 +- .../resources/fxml/report/SupplierLedger.fxml | 9 +- .../fxml/report/TransportLedger.fxml | 9 +- .../di/ConfigurationModuleTest.java | 12 +- 15 files changed, 376 insertions(+), 217 deletions(-) create mode 100644 src/main/java/openconsignment/service/BackupService.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 210b5af..47cd00f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,32 +1,32 @@ -name: JavaFX Build (Gradle) - -on: - push: - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up JDK - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 17 - cache: gradle - - - name: Make Gradle executable - run: chmod +x gradlew - - - name: Build using Gradle - run: ./gradlew clean build - - - name: Upload JAR artifact - uses: actions/upload-artifact@v4 - with: - name: satyam-consignment +name: JavaFX Build (Gradle) + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: gradle + + - name: Make Gradle executable + run: chmod +x gradlew + + - name: Build using Gradle + run: ./gradlew clean build + + - name: Upload JAR artifact + uses: actions/upload-artifact@v4 + with: + name: OpenConsignment path: build/libs/* \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 3e918a1..9d055b4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,6 +32,8 @@ dependencies { implementation(libs.javafx.graphics) implementation(libs.javafx.fxml) + implementation(libs.jgit) + compileOnly(libs.lombok) annotationProcessor(libs.lombok) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 92efa9f..77afec8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,65 +1,68 @@ -[versions] -javafx = "17.0.18" -controlsfx = "11.2.2" -jasperreports = "6.21.5" -sqlite = "3.34.0" -olap4j = "1.2.0" -#itext = "2.1.7" -lombok = "1.18.20" -dagger = "2.52" -testfx = "4.0.18" -testfxCore = "4.0.17" -monocle = "17.0.10" -hamcrest = "2.2" -#junit = "5.10.1" -junitbom = "5.10.2" +[versions] +javafx = "17.0.18" +controlsfx = "11.2.2" +jasperreports = "6.21.5" +sqlite = "3.34.0" +olap4j = "1.2.0" +#itext = "2.1.7" +lombok = "1.18.20" +dagger = "2.52" +testfx = "4.0.18" +testfxCore = "4.0.17" +monocle = "17.0.10" +hamcrest = "2.2" +#junit = "5.10.1" +junitbom = "5.10.2" mockito = "5.14.2" slf4j = "2.0.17" log4j = "2.24.3" snakeyaml = "2.3" - -spotless = "7.0.2" -shadow = "7.1.2" -javafxPlugin = "0.1.0" - -[libraries] -controlsfx = { module = "org.controlsfx:controlsfx", version.ref = "controlsfx" } -jasperreports = { module = "net.sf.jasperreports:jasperreports", version.ref = "jasperreports" } -sqlite = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" } +jgit = "7.8.1.202611041320-r" + +spotless = "7.0.2" +shadow = "7.1.2" +javafxPlugin = "0.1.0" + +[libraries] +controlsfx = { module = "org.controlsfx:controlsfx", version.ref = "controlsfx" } +jasperreports = { module = "net.sf.jasperreports:jasperreports", version.ref = "jasperreports" } +sqlite = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" } olap4j = { module = "org.olap4j:olap4j", version.ref = "olap4j" } slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } snakeyaml = { module = "org.yaml:snakeyaml", version.ref = "snakeyaml" } log4j-slf4j2-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.ref = "log4j" } log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" } -#itext = { module = "com.lowagie:itext", version.ref = "itext" } - -javafx-controls = { module = "org.openjfx:javafx-controls", version.ref = "javafx" } -javafx-base = { module = "org.openjfx:javafx-base", version.ref = "javafx" } -javafx-graphics = { module = "org.openjfx:javafx-graphics", version.ref = "javafx" } -javafx-fxml = { module = "org.openjfx:javafx-fxml", version.ref = "javafx" } - -lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } - -dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } -dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" } - -testfx-junit5 = { module = "org.testfx:testfx-junit5", version.ref = "testfx" } -testfx-core = { module = "org.testfx:testfx-core", version.ref = "testfxCore" } -testfx-monocle = { module = "org.testfx:openjfx-monocle", version.ref = "monocle" } - -hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "hamcrest" } - -#junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } -#junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } -junit-bom = { module = "org.junit:junit-bom", version.ref = "junitbom" } -junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } -junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } - -mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } -mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } - -[plugins] -javafx = { id = "org.openjfx.javafxplugin", version.ref = "javafxPlugin" } -spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } -#shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } +#itext = { module = "com.lowagie:itext", version.ref = "itext" } + +javafx-controls = { module = "org.openjfx:javafx-controls", version.ref = "javafx" } +javafx-base = { module = "org.openjfx:javafx-base", version.ref = "javafx" } +javafx-graphics = { module = "org.openjfx:javafx-graphics", version.ref = "javafx" } +javafx-fxml = { module = "org.openjfx:javafx-fxml", version.ref = "javafx" } + +jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version.ref = "jgit"} + +lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } + +dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } +dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" } + +testfx-junit5 = { module = "org.testfx:testfx-junit5", version.ref = "testfx" } +testfx-core = { module = "org.testfx:testfx-core", version.ref = "testfxCore" } +testfx-monocle = { module = "org.testfx:openjfx-monocle", version.ref = "monocle" } + +hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "hamcrest" } + +#junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } +#junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } +junit-bom = { module = "org.junit:junit-bom", version.ref = "junitbom" } +junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } +junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } + +mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } +mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } + +[plugins] +javafx = { id = "org.openjfx.javafxplugin", version.ref = "javafxPlugin" } +spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } +#shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } diff --git a/src/main/java/openconsignment/common/AppConfig.java b/src/main/java/openconsignment/common/AppConfig.java index 91fce8b..939bb6e 100644 --- a/src/main/java/openconsignment/common/AppConfig.java +++ b/src/main/java/openconsignment/common/AppConfig.java @@ -10,6 +10,7 @@ @NoArgsConstructor public class AppConfig { private String organizationName; + private String githubPAT; public static AppConfig forOrganization(String organizationName) { AppConfig configuration = new AppConfig(); @@ -18,10 +19,6 @@ public static AppConfig forOrganization(String organizationName) { return configuration; } - public String organizationName() { - return organizationName; - } - public void validate() { if (organizationName == null || organizationName.isBlank()) { throw new IllegalArgumentException("organizationName must not be blank"); diff --git a/src/main/java/openconsignment/controller/MainController.java b/src/main/java/openconsignment/controller/MainController.java index 73a0e4e..4b9457c 100644 --- a/src/main/java/openconsignment/controller/MainController.java +++ b/src/main/java/openconsignment/controller/MainController.java @@ -6,11 +6,12 @@ import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; -import javafx.scene.control.MenuItem; import javafx.scene.layout.BorderPane; import javax.inject.Inject; import openconsignment.common.ViewLoader; +import openconsignment.service.BackupService; +@SuppressWarnings("unused") public class MainController implements Initializable { @FXML @@ -25,14 +26,13 @@ public class MainController implements Initializable { @FXML private Button master_btn; - @FXML - private MenuItem welcome_screen; - private final ViewLoader viewLoader; + private final BackupService backupService; @Inject - public MainController(ViewLoader viewLoader) { + public MainController(ViewLoader viewLoader, BackupService backupService) { this.viewLoader = viewLoader; + this.backupService = backupService; } @Override @@ -74,4 +74,54 @@ private void showCollectionHistory(ActionEvent event) { private void showPaymentHistory(ActionEvent event) { viewLoader.loadCenter("/fxml/history/PaymentHistory.fxml", root); } + + @FXML + private void showBillEntryScreen(ActionEvent event) { + viewLoader.loadCenter("/fxml/entry/BillEntry.fxml", root); + } + + @FXML + private void showCollectionEntryScreen(ActionEvent event) { + viewLoader.loadCenter("/fxml/entry/CollectionEntry.fxml", root); + } + + @FXML + private void showPaymentEntryScreen(ActionEvent event) { + viewLoader.loadCenter("/fxml/entry/PaymentEntry.fxml", root); + } + + @FXML + private void showSupplierLedger(ActionEvent event) { + viewLoader.loadCenter("/fxml/report/SupplierLedger.fxml", root); + } + + @FXML + private void showBuyerLedger(ActionEvent event) { + viewLoader.loadCenter("/fxml/report/BuyerLedger.fxml", root); + } + + @FXML + private void showTransportLedger(ActionEvent event) { + viewLoader.loadCenter("/fxml/report/TransportLedger.fxml", root); + } + + @FXML + private void showSupplierMaster(ActionEvent event) { + viewLoader.loadCenter("/fxml/master/MasterSupplier.fxml", root); + } + + @FXML + private void showBuyerMaster(ActionEvent event) { + viewLoader.loadCenter("/fxml/master/MasterBuyer.fxml", root); + } + + @FXML + private void showTransportMaster(ActionEvent event) { + viewLoader.loadCenter("/fxml/master/MasterTransport.fxml", root); + } + + @FXML + private void checkSync(ActionEvent event) { + backupService.checkSync(); + } } diff --git a/src/main/java/openconsignment/controller/WelcomeScreenController.java b/src/main/java/openconsignment/controller/WelcomeScreenController.java index 73e0d70..2f46b9c 100644 --- a/src/main/java/openconsignment/controller/WelcomeScreenController.java +++ b/src/main/java/openconsignment/controller/WelcomeScreenController.java @@ -41,6 +41,6 @@ private void handleOpenGithub(ActionEvent event) { @Override public void initialize(URL url, ResourceBundle rb) { - organization_name.setText(configuration.organizationName()); + organization_name.setText(configuration.getOrganizationName()); } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java new file mode 100644 index 0000000..760e611 --- /dev/null +++ b/src/main/java/openconsignment/service/BackupService.java @@ -0,0 +1,63 @@ +package openconsignment.service; + +import java.io.File; +import java.io.IOException; +import javax.inject.Inject; +import javax.inject.Singleton; +import openconsignment.common.AppConfig; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.PullResult; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Singleton +public class BackupService { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private AppConfig appConfig; + + @Inject + public BackupService(AppConfig appConfig) { + this.appConfig = appConfig; + } + + public boolean checkSync() { + // Implementation for checking sync + logger.info("executing called"); + try { + pull(); + } catch (IOException | GitAPIException e) { + logger.error("Error during git pull", e); + return false; + } + logger.info("checkSync called"); + return true; + } + + public void pull() throws IOException, GitAPIException { + logger.info("executing git pull"); + String repoPath = "Satyam-Database-2026-27"; + String branchName = "main"; + String username = "drcbabu81"; + String token = appConfig.getGithubPAT(); + + logger.info("token is {}", token); + + try (Git git = Git.open(new File(repoPath))) { + + PullResult result = git.pull() + .setRemote("origin") + .setRemoteBranchName(branchName) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, token)) + .call(); + + if (result.isSuccessful()) { + logger.info("Successfully pulled: {}", branchName); + } else { + throw new IllegalStateException("Pull failed for branch: " + branchName); + } + } + } +} diff --git a/src/main/java/openconsignment/service/BuyerService.java b/src/main/java/openconsignment/service/BuyerService.java index 823f1e6..fb2c33d 100644 --- a/src/main/java/openconsignment/service/BuyerService.java +++ b/src/main/java/openconsignment/service/BuyerService.java @@ -49,7 +49,7 @@ public void renameBuyer(String oldName, String newName) throws SQLException { public void generatePdf(String buyerName, boolean isAgewise) throws SQLException, JRException { Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.organizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganizationName()); payload.put("buyerName", buyerName); if (isAgewise) { diff --git a/src/main/java/openconsignment/service/SupplierService.java b/src/main/java/openconsignment/service/SupplierService.java index 7f8eb0e..9f8175f 100644 --- a/src/main/java/openconsignment/service/SupplierService.java +++ b/src/main/java/openconsignment/service/SupplierService.java @@ -50,7 +50,7 @@ public void renameSupplier(String oldName, String newName) throws SQLException { public void generatePdf(String supplierName, boolean isAgewise) throws SQLException, JRException { Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.organizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganizationName()); payload.put("supplierName", supplierName); if (isAgewise) { diff --git a/src/main/java/openconsignment/service/TransportService.java b/src/main/java/openconsignment/service/TransportService.java index 8007adc..dfe86e0 100644 --- a/src/main/java/openconsignment/service/TransportService.java +++ b/src/main/java/openconsignment/service/TransportService.java @@ -46,7 +46,7 @@ public void generatePdf(String transportName, String fromDate, String toDate) th transportRepository.getTransportReportFor(transportName, fromDate, toDate); Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.organizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganizationName()); payload.put("transportName", transportName); payload.put("fromDate", fromDate); payload.put("toDate", toDate); diff --git a/src/main/resources/fxml/Main.fxml b/src/main/resources/fxml/Main.fxml index 6357a76..3990073 100644 --- a/src/main/resources/fxml/Main.fxml +++ b/src/main/resources/fxml/Main.fxml @@ -1,97 +1,144 @@ - - - - - - - - - - - -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/fxml/report/BuyerLedger.fxml b/src/main/resources/fxml/report/BuyerLedger.fxml index d01305e..47ea9e7 100644 --- a/src/main/resources/fxml/report/BuyerLedger.fxml +++ b/src/main/resources/fxml/report/BuyerLedger.fxml @@ -3,12 +3,11 @@ - - + + @@ -50,4 +49,4 @@ - + diff --git a/src/main/resources/fxml/report/SupplierLedger.fxml b/src/main/resources/fxml/report/SupplierLedger.fxml index 4745eb1..3e8c83c 100644 --- a/src/main/resources/fxml/report/SupplierLedger.fxml +++ b/src/main/resources/fxml/report/SupplierLedger.fxml @@ -3,12 +3,11 @@ - - + + @@ -51,4 +50,4 @@ - + diff --git a/src/main/resources/fxml/report/TransportLedger.fxml b/src/main/resources/fxml/report/TransportLedger.fxml index 01aa234..02caf53 100644 --- a/src/main/resources/fxml/report/TransportLedger.fxml +++ b/src/main/resources/fxml/report/TransportLedger.fxml @@ -3,12 +3,11 @@ - - + + @@ -48,4 +47,4 @@ - + diff --git a/src/test/java/openconsignment/di/ConfigurationModuleTest.java b/src/test/java/openconsignment/di/ConfigurationModuleTest.java index 0a09125..63e681e 100644 --- a/src/test/java/openconsignment/di/ConfigurationModuleTest.java +++ b/src/test/java/openconsignment/di/ConfigurationModuleTest.java @@ -30,7 +30,7 @@ void missingFileIsCopiedFromBundledResourceAndLoaded() throws IOException { AppConfig configuration = load(file); assertEquals(bundled, Files.readString(file)); - assertEquals(configuration.organizationName(), load(file).organizationName()); + assertEquals(configuration.getOrganizationName(), load(file).getOrganizationName()); } @Test @@ -45,7 +45,7 @@ void emptyExistingFileIsRejectedAndPreserved() throws IOException { void loadsUtf8OrganizationNameAndTrimsWhitespace() throws IOException { Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: \" Café Agencies \"\n"); - assertEquals("Café Agencies", load(file).organizationName()); + assertEquals("Café Agencies", load(file).getOrganizationName()); } @Test @@ -55,8 +55,8 @@ void loadedConfigurationDoesNotChangeWhenFileIsEdited() throws IOException { Files.writeString(file, "organizationName: Second\n"); - assertEquals("First", configuration.organizationName()); - assertEquals("Second", load(file).organizationName()); + assertEquals("First", configuration.getOrganizationName()); + assertEquals("Second", load(file).getOrganizationName()); } @Test @@ -86,7 +86,7 @@ void existingConfigurationIsLoadedWithoutBeingOverwritten() throws IOException { String content = "# Custom settings\norganizationName: External Organization\n"; Path file = Files.writeString(tempDir.resolve("application.yaml"), content); - assertEquals("External Organization", load(file).organizationName()); + assertEquals("External Organization", load(file).getOrganizationName()); assertEquals(content, Files.readString(file)); } @@ -136,7 +136,7 @@ void developmentRunUsesConfigurationInWorkingDirectory() throws IOException { void bindsNumericScalarToStringProperty() throws IOException { Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: 123\n"); - assertEquals("123", load(file).organizationName()); + assertEquals("123", load(file).getOrganizationName()); } @Test From 95acf0ebb8516f1697c6745c57c288f74acefa40 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Wed, 11 Nov 2026 00:10:11 +0530 Subject: [PATCH 02/13] feat: improved application.yaml Signed-off-by: Rajdeep Roy Chowdhury --- .../java/openconsignment/common/AppConfig.java | 14 +++++++++++++- .../openconsignment/service/BackupService.java | 13 ++++++++----- src/main/resources/application.yaml | 6 ++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/java/openconsignment/common/AppConfig.java b/src/main/java/openconsignment/common/AppConfig.java index 939bb6e..35bf0db 100644 --- a/src/main/java/openconsignment/common/AppConfig.java +++ b/src/main/java/openconsignment/common/AppConfig.java @@ -10,7 +10,8 @@ @NoArgsConstructor public class AppConfig { private String organizationName; - private String githubPAT; + private String financialYear; + private Github github; public static AppConfig forOrganization(String organizationName) { AppConfig configuration = new AppConfig(); @@ -19,6 +20,17 @@ public static AppConfig forOrganization(String organizationName) { return configuration; } + @Getter + @Setter + @NoArgsConstructor + public static class Github { + private String repoName; + private String token; + private String username; + private String branchName; + private String remoteName; + } + public void validate() { if (organizationName == null || organizationName.isBlank()) { throw new IllegalArgumentException("organizationName must not be blank"); diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index 760e611..c273187 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -38,17 +38,20 @@ public boolean checkSync() { public void pull() throws IOException, GitAPIException { logger.info("executing git pull"); - String repoPath = "Satyam-Database-2026-27"; - String branchName = "main"; - String username = "drcbabu81"; - String token = appConfig.getGithubPAT(); + + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepoName(); + String username = github.getUsername(); + String token = github.getToken(); + String branchName = github.getBranchName(); + String remoteName = github.getRemoteName(); logger.info("token is {}", token); try (Git git = Git.open(new File(repoPath))) { PullResult result = git.pull() - .setRemote("origin") + .setRemote(remoteName) .setRemoteBranchName(branchName) .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, token)) .call(); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index aada7ee..a239e1c 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1 +1,7 @@ organizationName: "SATYAM AGENCIES" +github: + token: "" + username: "drcbabu81" + branchName: "main" + remoteName: "origin-https" + repoName: "Satyam-Database-2026-27" \ No newline at end of file From b8e636ddb1a4af844a118bb8c2d9deb7a152cb81 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Wed, 11 Nov 2026 18:19:19 +0530 Subject: [PATCH 03/13] feat: added code related hash compare Signed-off-by: Rajdeep Roy Chowdhury --- scripts/configure-backup.py | 9 +++++++++ .../java/openconsignment/common/Utils.java | 20 +++++++++++++++++++ .../service/BackupService.java | 20 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/scripts/configure-backup.py b/scripts/configure-backup.py index 28a5ce9..df7b9ae 100755 --- a/scripts/configure-backup.py +++ b/scripts/configure-backup.py @@ -69,6 +69,7 @@ def init_github_repository(): return github_username = "drcbabu81" repo_url = f"git@github.com:{github_username}/{repo_name}.git" + repo_url_https = f"https://github.com/{github_username}/{repo_name}.git" try: logger.info(f"cloning {repo_name}") @@ -76,6 +77,14 @@ def init_github_repository(): ["git", "clone", repo_url], check=True, capture_output=True, text=True ) + repo_path = os.path.abspath(repo_name) + + subprocess.run( + ["git", "remote", "add", "origin-https", repo_url_https], + cwd=repo_path, + check=True, capture_output=True, text=True + ) + if (Path(repo_name) / ".git").is_dir(): logger.info("clone successful") else: diff --git a/src/main/java/openconsignment/common/Utils.java b/src/main/java/openconsignment/common/Utils.java index a1f3a42..81d56b0 100644 --- a/src/main/java/openconsignment/common/Utils.java +++ b/src/main/java/openconsignment/common/Utils.java @@ -3,11 +3,16 @@ import java.awt.*; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.util.HexFormat; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -118,4 +123,19 @@ public static String nextVoucherNumber(String lastVoucher) { return "0"; } } + + public static String md5sum(Path path) throws Exception { + MessageDigest digest = MessageDigest.getInstance("MD5"); + + try (InputStream input = Files.newInputStream(path)) { + byte[] buffer = new byte[8192]; + int bytesRead; + + while ((bytesRead = input.read(buffer)) != -1) { + digest.update(buffer, 0, bytesRead); + } + } + + return HexFormat.of().formatHex(digest.digest()); + } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index c273187..a09a5a7 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -2,9 +2,12 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; import javax.inject.Inject; import javax.inject.Singleton; import openconsignment.common.AppConfig; +import openconsignment.common.Constants; +import openconsignment.common.Utils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PullResult; import org.eclipse.jgit.api.errors.GitAPIException; @@ -33,7 +36,22 @@ public boolean checkSync() { return false; } logger.info("checkSync called"); - return true; + + try { + String localFileHash = Utils.md5sum(Path.of(Constants.DATABASE_FILE_NAME)); + String repoFileHash = + Utils.md5sum(Path.of(appConfig.getGithub().getRepoName() + "/" + Constants.DATABASE_FILE_NAME)); + boolean result = 0 == localFileHash.compareTo(repoFileHash); + logger.info( + "Checksync result = {}, localFileHash = {}, repoFileHash = {}", + result, + localFileHash, + repoFileHash); + return result; + } catch (Exception ex) { + logger.error(ex.toString()); + return false; + } } public void pull() throws IOException, GitAPIException { From 39ab2f9c8ab52ec48d1eeec05a391b60c665faf9 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Thu, 12 Nov 2026 10:37:08 +0530 Subject: [PATCH 04/13] feat: ui feedback added Signed-off-by: Rajdeep Roy Chowdhury --- .../controller/MainController.java | 15 ++++++++- .../report/SupplierLedgerController.java | 11 +++---- .../service/BackupService.java | 31 +++++++++---------- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/main/java/openconsignment/controller/MainController.java b/src/main/java/openconsignment/controller/MainController.java index 4b9457c..eab93cb 100644 --- a/src/main/java/openconsignment/controller/MainController.java +++ b/src/main/java/openconsignment/controller/MainController.java @@ -5,9 +5,11 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.layout.BorderPane; import javax.inject.Inject; +import openconsignment.common.Utils; import openconsignment.common.ViewLoader; import openconsignment.service.BackupService; @@ -122,6 +124,17 @@ private void showTransportMaster(ActionEvent event) { @FXML private void checkSync(ActionEvent event) { - backupService.checkSync(); + boolean synced = false; + try { + synced = backupService.checkSync(); + } catch (Exception e) { + Utils.showAlert("Error", Alert.AlertType.ERROR); + } + + if (synced) { + Utils.showAlert("Data is Synced", Alert.AlertType.INFORMATION); + } else { + Utils.showAlert("Not Synced", Alert.AlertType.WARNING); + } } } diff --git a/src/main/java/openconsignment/controller/report/SupplierLedgerController.java b/src/main/java/openconsignment/controller/report/SupplierLedgerController.java index 340d15c..7f552c8 100644 --- a/src/main/java/openconsignment/controller/report/SupplierLedgerController.java +++ b/src/main/java/openconsignment/controller/report/SupplierLedgerController.java @@ -15,15 +15,14 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.ToggleGroup; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import net.sf.jasperreports.engine.*; import openconsignment.common.Constants; import openconsignment.common.Utils; import openconsignment.service.SupplierService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class SupplierLedgerController implements Initializable { - private static final Logger logger = LoggerFactory.getLogger(SupplierLedgerController.class); @FXML private ComboBox supplier_name_combo; @@ -57,7 +56,7 @@ public void initialize(URL url, ResourceBundle rb) { supplier_name_combo.setItems(FXCollections.observableArrayList(supplierList)); } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } @@ -70,7 +69,7 @@ private void generatePDF(ActionEvent event) { Utils.showAlert("Report Successfully Generated", AlertType.INFORMATION); } catch (IOException | SQLException | JRException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } @@ -81,7 +80,7 @@ private void launchPdf(ActionEvent event) { Utils.showAlert("PDF opened successfully.", AlertType.INFORMATION); } catch (IOException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index a09a5a7..ef95c25 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -5,6 +5,7 @@ import java.nio.file.Path; import javax.inject.Inject; import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.AppConfig; import openconsignment.common.Constants; import openconsignment.common.Utils; @@ -12,50 +13,48 @@ import org.eclipse.jgit.api.PullResult; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j @Singleton public class BackupService { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private AppConfig appConfig; + private final AppConfig appConfig; @Inject public BackupService(AppConfig appConfig) { this.appConfig = appConfig; } - public boolean checkSync() { + public boolean checkSync() throws Exception { // Implementation for checking sync - logger.info("executing called"); + log.info("executing called"); try { pull(); } catch (IOException | GitAPIException e) { - logger.error("Error during git pull", e); - return false; + log.error("Error during git pull", e); + throw e; } - logger.info("checkSync called"); + log.info("checkSync called"); try { String localFileHash = Utils.md5sum(Path.of(Constants.DATABASE_FILE_NAME)); String repoFileHash = Utils.md5sum(Path.of(appConfig.getGithub().getRepoName() + "/" + Constants.DATABASE_FILE_NAME)); boolean result = 0 == localFileHash.compareTo(repoFileHash); - logger.info( - "Checksync result = {}, localFileHash = {}, repoFileHash = {}", + log.info( + "CheckSync result = {}, localFileHash = {}, repoFileHash = {}", result, localFileHash, repoFileHash); return result; } catch (Exception ex) { - logger.error(ex.toString()); - return false; + log.error(ex.toString()); + throw ex; } } public void pull() throws IOException, GitAPIException { - logger.info("executing git pull"); + log.info("executing git pull"); AppConfig.Github github = appConfig.getGithub(); String repoPath = github.getRepoName(); @@ -64,7 +63,7 @@ public void pull() throws IOException, GitAPIException { String branchName = github.getBranchName(); String remoteName = github.getRemoteName(); - logger.info("token is {}", token); + log.info("token is {}", token); try (Git git = Git.open(new File(repoPath))) { @@ -75,7 +74,7 @@ public void pull() throws IOException, GitAPIException { .call(); if (result.isSuccessful()) { - logger.info("Successfully pulled: {}", branchName); + log.info("Successfully pulled: {}", branchName); } else { throw new IllegalStateException("Pull failed for branch: " + branchName); } From 1dcc03aa853d939087471a9bfff1f1ca4a1fce84 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Thu, 12 Nov 2026 11:04:59 +0530 Subject: [PATCH 05/13] feat: partially implemented upload Signed-off-by: Rajdeep Roy Chowdhury --- .../controller/MainController.java | 16 ++++++ .../service/BackupService.java | 53 ++++++++++++------- src/main/resources/fxml/Main.fxml | 2 +- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/main/java/openconsignment/controller/MainController.java b/src/main/java/openconsignment/controller/MainController.java index eab93cb..f79a285 100644 --- a/src/main/java/openconsignment/controller/MainController.java +++ b/src/main/java/openconsignment/controller/MainController.java @@ -7,6 +7,7 @@ import javafx.fxml.Initializable; import javafx.scene.control.Alert; import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; import javafx.scene.layout.BorderPane; import javax.inject.Inject; import openconsignment.common.Utils; @@ -137,4 +138,19 @@ private void checkSync(ActionEvent event) { Utils.showAlert("Not Synced", Alert.AlertType.WARNING); } } + + @FXML + private void upload(ActionEvent event) { + try { + Alert alert = + new Alert(Alert.AlertType.CONFIRMATION, "Do you want to upload?", ButtonType.YES, ButtonType.NO); + if (alert.showAndWait().orElse(ButtonType.NO) != ButtonType.YES) { + return; + } + backupService.push(); + Utils.showAlert("Successfully uploaded", Alert.AlertType.INFORMATION); + } catch (Exception e) { + Utils.showAlert("Error", Alert.AlertType.ERROR); + } + } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index ef95c25..7011c06 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -12,6 +12,7 @@ import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PullResult; import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; @Slf4j @@ -26,31 +27,23 @@ public BackupService(AppConfig appConfig) { } public boolean checkSync() throws Exception { - // Implementation for checking sync log.info("executing called"); try { pull(); - } catch (IOException | GitAPIException e) { + return compareDatabaseHashes(); + } catch (Exception e) { log.error("Error during git pull", e); throw e; } - log.info("checkSync called"); + } - try { - String localFileHash = Utils.md5sum(Path.of(Constants.DATABASE_FILE_NAME)); - String repoFileHash = - Utils.md5sum(Path.of(appConfig.getGithub().getRepoName() + "/" + Constants.DATABASE_FILE_NAME)); - boolean result = 0 == localFileHash.compareTo(repoFileHash); - log.info( - "CheckSync result = {}, localFileHash = {}, repoFileHash = {}", - result, - localFileHash, - repoFileHash); - return result; - } catch (Exception ex) { - log.error(ex.toString()); - throw ex; - } + public boolean compareDatabaseHashes() throws Exception { + String localFileHash = Utils.md5sum(Path.of(Constants.DATABASE_FILE_NAME)); + String repoFileHash = + Utils.md5sum(Path.of(appConfig.getGithub().getRepoName() + "/" + Constants.DATABASE_FILE_NAME)); + boolean result = 0 == localFileHash.compareTo(repoFileHash); + log.info("CheckSync result = {}, localFileHash = {}, repoFileHash = {}", result, localFileHash, repoFileHash); + return result; } public void pull() throws IOException, GitAPIException { @@ -80,4 +73,28 @@ public void pull() throws IOException, GitAPIException { } } } + + public void push() throws IOException, GitAPIException { + log.info("executing git push"); + + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepoName(); + String username = github.getUsername(); + String token = github.getToken(); + String branchName = github.getBranchName(); + String remoteName = github.getRemoteName(); + + log.info("token is {}", token); + + try (Git git = Git.open(new File(repoPath))) { + Iterable results = git.push() + .setRemote(remoteName) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, token)) + .call(); + + for (PushResult result : results) { + log.info(result.getMessages()); + } + } + } } diff --git a/src/main/resources/fxml/Main.fxml b/src/main/resources/fxml/Main.fxml index 3990073..b3a5781 100644 --- a/src/main/resources/fxml/Main.fxml +++ b/src/main/resources/fxml/Main.fxml @@ -64,7 +64,7 @@ - + From abb8ba2d78e072f2e4ae978a24ffe1fc48acb878 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Thu, 12 Nov 2026 11:28:33 +0530 Subject: [PATCH 06/13] test: test repo added Signed-off-by: Rajdeep Roy Chowdhury --- src/main/resources/application.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index a239e1c..f87a711 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,7 +1,7 @@ organizationName: "SATYAM AGENCIES" github: token: "" - username: "drcbabu81" + username: "razdeep" branchName: "main" remoteName: "origin-https" - repoName: "Satyam-Database-2026-27" \ No newline at end of file + repoName: "Satyam-Database-2001-02" \ No newline at end of file From 78826516a18e6e7cb51600a6270b8d990a0bac28 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Fri, 13 Nov 2026 10:21:47 +0530 Subject: [PATCH 07/13] feat: download feature added Signed-off-by: Rajdeep Roy Chowdhury --- .../controller/MainController.java | 22 ++++++- .../service/BackupService.java | 61 ++++++++++++++++++- src/main/resources/fxml/Main.fxml | 2 +- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/src/main/java/openconsignment/controller/MainController.java b/src/main/java/openconsignment/controller/MainController.java index f79a285..80a3151 100644 --- a/src/main/java/openconsignment/controller/MainController.java +++ b/src/main/java/openconsignment/controller/MainController.java @@ -10,10 +10,12 @@ import javafx.scene.control.ButtonType; import javafx.scene.layout.BorderPane; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.Utils; import openconsignment.common.ViewLoader; import openconsignment.service.BackupService; +@Slf4j @SuppressWarnings("unused") public class MainController implements Initializable { @@ -147,10 +149,26 @@ private void upload(ActionEvent event) { if (alert.showAndWait().orElse(ButtonType.NO) != ButtonType.YES) { return; } - backupService.push(); + backupService.upload(); Utils.showAlert("Successfully uploaded", Alert.AlertType.INFORMATION); } catch (Exception e) { - Utils.showAlert("Error", Alert.AlertType.ERROR); + log.error(e.toString()); + Utils.showAlert(e.toString(), Alert.AlertType.ERROR); + } + } + + public void download(ActionEvent actionEvent) { + try { + Alert alert = + new Alert(Alert.AlertType.CONFIRMATION, "Do you want to download?", ButtonType.YES, ButtonType.NO); + if (alert.showAndWait().orElse(ButtonType.NO) != ButtonType.YES) { + return; + } + backupService.download(); + Utils.showAlert("Successfully downloaded", Alert.AlertType.INFORMATION); + } catch (Exception e) { + log.error(e.toString()); + Utils.showAlert(e.toString(), Alert.AlertType.ERROR); } } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index 7011c06..d11dd1c 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -2,7 +2,9 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -12,6 +14,7 @@ import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PullResult; import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; @@ -46,7 +49,19 @@ public boolean compareDatabaseHashes() throws Exception { return result; } - public void pull() throws IOException, GitAPIException { + private void copyRepoToLocal() throws IOException { + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepoName(); + + log.info("Copying {} to {}", repoPath, Constants.DATABASE_FILE_NAME); + Files.copy( + Path.of(new File(repoPath + "/" + Constants.DATABASE_FILE_NAME).toURI()), + Path.of(new File(Constants.DATABASE_FILE_NAME).toURI()), + StandardCopyOption.REPLACE_EXISTING); + log.info("Copied {} to {}", repoPath, Constants.DATABASE_FILE_NAME); + } + + private void pull() throws IOException, GitAPIException { log.info("executing git pull"); AppConfig.Github github = appConfig.getGithub(); @@ -74,7 +89,43 @@ public void pull() throws IOException, GitAPIException { } } - public void push() throws IOException, GitAPIException { + public void download() throws GitAPIException, IOException { + pull(); + copyRepoToLocal(); + } + + private void copyLocalToRepo() throws IOException { + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepoName(); + + log.info("Copying {} to {}", Constants.DATABASE_FILE_NAME, repoPath); + Files.copy( + Path.of(new File(Constants.DATABASE_FILE_NAME).toURI()), + Path.of(new File(repoPath + "/" + Constants.DATABASE_FILE_NAME).toURI()), + StandardCopyOption.REPLACE_EXISTING); + log.info("Copied {} to {}", Constants.DATABASE_FILE_NAME, repoPath); + } + + private void addAndCommit() throws IOException, GitAPIException { + + log.info("executing add and commit"); + + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepoName(); + + try (Git git = Git.open(new File(repoPath))) { + + // Stage changes + git.add().addFilepattern(".").call(); + + // Commit changes + RevCommit commit = git.commit().setMessage("Automated backup").call(); + + log.info("Commit: " + commit.getId().getName()); + } + } + + private void push() throws IOException, GitAPIException { log.info("executing git push"); AppConfig.Github github = appConfig.getGithub(); @@ -97,4 +148,10 @@ public void push() throws IOException, GitAPIException { } } } + + public void upload() throws GitAPIException, IOException { + copyLocalToRepo(); + addAndCommit(); + push(); + } } diff --git a/src/main/resources/fxml/Main.fxml b/src/main/resources/fxml/Main.fxml index b3a5781..2f6c3a9 100644 --- a/src/main/resources/fxml/Main.fxml +++ b/src/main/resources/fxml/Main.fxml @@ -65,7 +65,7 @@ - + From 3b2fcea982887e7a802b4c92ed3ce6f6f60c608d Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Sat, 14 Nov 2026 19:41:17 +0530 Subject: [PATCH 08/13] fix: empty commit bug fixed Signed-off-by: Rajdeep Roy Chowdhury --- .../controller/MainController.java | 4 +++ .../service/BackupService.java | 25 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/openconsignment/controller/MainController.java b/src/main/java/openconsignment/controller/MainController.java index 80a3151..b3420d8 100644 --- a/src/main/java/openconsignment/controller/MainController.java +++ b/src/main/java/openconsignment/controller/MainController.java @@ -14,6 +14,7 @@ import openconsignment.common.Utils; import openconsignment.common.ViewLoader; import openconsignment.service.BackupService; +import org.eclipse.jgit.api.errors.EmptyCommitException; @Slf4j @SuppressWarnings("unused") @@ -151,6 +152,9 @@ private void upload(ActionEvent event) { } backupService.upload(); Utils.showAlert("Successfully uploaded", Alert.AlertType.INFORMATION); + } catch (EmptyCommitException e) { + log.info(e.toString()); + Utils.showAlert("Data is already synced. " + e, Alert.AlertType.INFORMATION); } catch (Exception e) { log.error(e.toString()); Utils.showAlert(e.toString(), Alert.AlertType.ERROR); diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index d11dd1c..87d8b1a 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -5,6 +5,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; @@ -40,10 +42,14 @@ public boolean checkSync() throws Exception { } } + private String getRepoFileHash() throws Exception { + return Utils.md5sum(Path.of(appConfig.getGithub().getRepoName() + "/" + Constants.DATABASE_FILE_NAME)); + } + public boolean compareDatabaseHashes() throws Exception { String localFileHash = Utils.md5sum(Path.of(Constants.DATABASE_FILE_NAME)); - String repoFileHash = - Utils.md5sum(Path.of(appConfig.getGithub().getRepoName() + "/" + Constants.DATABASE_FILE_NAME)); + String repoFileHash = getRepoFileHash(); + boolean result = 0 == localFileHash.compareTo(repoFileHash); log.info("CheckSync result = {}, localFileHash = {}, repoFileHash = {}", result, localFileHash, repoFileHash); return result; @@ -118,8 +124,21 @@ private void addAndCommit() throws IOException, GitAPIException { // Stage changes git.add().addFilepattern(".").call(); + // Current time in string + String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + + String repoFileHash = "null"; + try { + repoFileHash = getRepoFileHash(); + } catch (Exception e) { + log.error(e.toString()); + } + + String message = "Backed up at " + currentTime + "; database hash = " + repoFileHash; + // Commit changes - RevCommit commit = git.commit().setMessage("Automated backup").call(); + RevCommit commit = + git.commit().setMessage(message).setAllowEmpty(false).call(); log.info("Commit: " + commit.getId().getName()); } From 4b35edd912a58d05d293a88b69f7f0277cb6817e Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Sat, 14 Nov 2026 20:00:58 +0530 Subject: [PATCH 09/13] feat: yaml config formalized Signed-off-by: Rajdeep Roy Chowdhury --- .../openconsignment/common/AppConfig.java | 18 ++++---- .../controller/WelcomeScreenController.java | 9 ++-- .../service/BackupService.java | 20 ++++----- .../openconsignment/service/BuyerService.java | 2 +- .../service/SupplierService.java | 2 +- .../service/TransportService.java | 2 +- src/main/resources/application.yaml | 9 ++-- .../di/ConfigurationModuleTest.java | 42 +++++++++---------- 8 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/main/java/openconsignment/common/AppConfig.java b/src/main/java/openconsignment/common/AppConfig.java index 35bf0db..ec59801 100644 --- a/src/main/java/openconsignment/common/AppConfig.java +++ b/src/main/java/openconsignment/common/AppConfig.java @@ -9,13 +9,13 @@ @Setter @NoArgsConstructor public class AppConfig { - private String organizationName; - private String financialYear; + private String organization; + private String year; private Github github; public static AppConfig forOrganization(String organizationName) { AppConfig configuration = new AppConfig(); - configuration.setOrganizationName(organizationName); + configuration.setOrganization(organizationName); configuration.validate(); return configuration; } @@ -24,17 +24,17 @@ public static AppConfig forOrganization(String organizationName) { @Setter @NoArgsConstructor public static class Github { - private String repoName; + private String repository; private String token; private String username; - private String branchName; - private String remoteName; + private String branch; + private String remote; } public void validate() { - if (organizationName == null || organizationName.isBlank()) { - throw new IllegalArgumentException("organizationName must not be blank"); + if (organization == null || organization.isBlank()) { + throw new IllegalArgumentException("organization must not be blank"); } - organizationName = organizationName.strip(); + organization = organization.strip(); } } diff --git a/src/main/java/openconsignment/controller/WelcomeScreenController.java b/src/main/java/openconsignment/controller/WelcomeScreenController.java index 2f46b9c..937816d 100644 --- a/src/main/java/openconsignment/controller/WelcomeScreenController.java +++ b/src/main/java/openconsignment/controller/WelcomeScreenController.java @@ -9,13 +9,12 @@ import javafx.scene.control.Hyperlink; import javafx.scene.text.Text; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.AppConfig; import openconsignment.common.Utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class WelcomeScreenController implements Initializable { - private static final Logger logger = LoggerFactory.getLogger(WelcomeScreenController.class); private final AppConfig configuration; @FXML @@ -35,12 +34,12 @@ private void handleOpenGithub(ActionEvent event) { Utils.launchBrowser(url); } catch (IOException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } @Override public void initialize(URL url, ResourceBundle rb) { - organization_name.setText(configuration.getOrganizationName()); + organization_name.setText(configuration.getOrganization()); } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index 87d8b1a..a0fb714 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -43,7 +43,7 @@ public boolean checkSync() throws Exception { } private String getRepoFileHash() throws Exception { - return Utils.md5sum(Path.of(appConfig.getGithub().getRepoName() + "/" + Constants.DATABASE_FILE_NAME)); + return Utils.md5sum(Path.of(appConfig.getGithub().getRepository() + "/" + Constants.DATABASE_FILE_NAME)); } public boolean compareDatabaseHashes() throws Exception { @@ -57,7 +57,7 @@ public boolean compareDatabaseHashes() throws Exception { private void copyRepoToLocal() throws IOException { AppConfig.Github github = appConfig.getGithub(); - String repoPath = github.getRepoName(); + String repoPath = github.getRepository(); log.info("Copying {} to {}", repoPath, Constants.DATABASE_FILE_NAME); Files.copy( @@ -71,11 +71,11 @@ private void pull() throws IOException, GitAPIException { log.info("executing git pull"); AppConfig.Github github = appConfig.getGithub(); - String repoPath = github.getRepoName(); + String repoPath = github.getRepository(); String username = github.getUsername(); String token = github.getToken(); - String branchName = github.getBranchName(); - String remoteName = github.getRemoteName(); + String branchName = github.getBranch(); + String remoteName = github.getRemote(); log.info("token is {}", token); @@ -102,7 +102,7 @@ public void download() throws GitAPIException, IOException { private void copyLocalToRepo() throws IOException { AppConfig.Github github = appConfig.getGithub(); - String repoPath = github.getRepoName(); + String repoPath = github.getRepository(); log.info("Copying {} to {}", Constants.DATABASE_FILE_NAME, repoPath); Files.copy( @@ -117,7 +117,7 @@ private void addAndCommit() throws IOException, GitAPIException { log.info("executing add and commit"); AppConfig.Github github = appConfig.getGithub(); - String repoPath = github.getRepoName(); + String repoPath = github.getRepository(); try (Git git = Git.open(new File(repoPath))) { @@ -148,11 +148,11 @@ private void push() throws IOException, GitAPIException { log.info("executing git push"); AppConfig.Github github = appConfig.getGithub(); - String repoPath = github.getRepoName(); + String repoPath = github.getRepository(); String username = github.getUsername(); String token = github.getToken(); - String branchName = github.getBranchName(); - String remoteName = github.getRemoteName(); + String branchName = github.getBranch(); + String remoteName = github.getRemote(); log.info("token is {}", token); diff --git a/src/main/java/openconsignment/service/BuyerService.java b/src/main/java/openconsignment/service/BuyerService.java index fb2c33d..7eb6aa4 100644 --- a/src/main/java/openconsignment/service/BuyerService.java +++ b/src/main/java/openconsignment/service/BuyerService.java @@ -49,7 +49,7 @@ public void renameBuyer(String oldName, String newName) throws SQLException { public void generatePdf(String buyerName, boolean isAgewise) throws SQLException, JRException { Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganization()); payload.put("buyerName", buyerName); if (isAgewise) { diff --git a/src/main/java/openconsignment/service/SupplierService.java b/src/main/java/openconsignment/service/SupplierService.java index 9f8175f..a476ff3 100644 --- a/src/main/java/openconsignment/service/SupplierService.java +++ b/src/main/java/openconsignment/service/SupplierService.java @@ -50,7 +50,7 @@ public void renameSupplier(String oldName, String newName) throws SQLException { public void generatePdf(String supplierName, boolean isAgewise) throws SQLException, JRException { Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganization()); payload.put("supplierName", supplierName); if (isAgewise) { diff --git a/src/main/java/openconsignment/service/TransportService.java b/src/main/java/openconsignment/service/TransportService.java index dfe86e0..4785790 100644 --- a/src/main/java/openconsignment/service/TransportService.java +++ b/src/main/java/openconsignment/service/TransportService.java @@ -46,7 +46,7 @@ public void generatePdf(String transportName, String fromDate, String toDate) th transportRepository.getTransportReportFor(transportName, fromDate, toDate); Map payload = new HashMap<>(); - payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganizationName()); + payload.put(Constants.ORGANIZATION_NAME_KEY, configuration.getOrganization()); payload.put("transportName", transportName); payload.put("fromDate", fromDate); payload.put("toDate", toDate); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index f87a711..e147632 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,7 +1,8 @@ -organizationName: "SATYAM AGENCIES" +organization: "SATYAM AGENCIES" +#year: 2001-02 github: token: "" username: "razdeep" - branchName: "main" - remoteName: "origin-https" - repoName: "Satyam-Database-2001-02" \ No newline at end of file + branch: "main" + remote: "origin-https" + repository: "Satyam-Database-2001-02" \ No newline at end of file diff --git a/src/test/java/openconsignment/di/ConfigurationModuleTest.java b/src/test/java/openconsignment/di/ConfigurationModuleTest.java index 63e681e..ee15ee2 100644 --- a/src/test/java/openconsignment/di/ConfigurationModuleTest.java +++ b/src/test/java/openconsignment/di/ConfigurationModuleTest.java @@ -30,7 +30,7 @@ void missingFileIsCopiedFromBundledResourceAndLoaded() throws IOException { AppConfig configuration = load(file); assertEquals(bundled, Files.readString(file)); - assertEquals(configuration.getOrganizationName(), load(file).getOrganizationName()); + assertEquals(configuration.getOrganization(), load(file).getOrganization()); } @Test @@ -42,33 +42,33 @@ void emptyExistingFileIsRejectedAndPreserved() throws IOException { } @Test - void loadsUtf8OrganizationNameAndTrimsWhitespace() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: \" Café Agencies \"\n"); + void loadsUtf8OrganizationAndTrimsWhitespace() throws IOException { + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: \" Café Agencies \"\n"); - assertEquals("Café Agencies", load(file).getOrganizationName()); + assertEquals("Café Agencies", load(file).getOrganization()); } @Test void loadedConfigurationDoesNotChangeWhenFileIsEdited() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: First\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: First\n"); AppConfig configuration = load(file); - Files.writeString(file, "organizationName: Second\n"); + Files.writeString(file, "organization: Second\n"); - assertEquals("First", configuration.getOrganizationName()); - assertEquals("Second", load(file).getOrganizationName()); + assertEquals("First", configuration.getOrganization()); + assertEquals("Second", load(file).getOrganization()); } @Test - void rejectsBlankOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: \" \"\n"); + void rejectsBlankOrganization() throws IOException { + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: \" \"\n"); assertThrows(IllegalArgumentException.class, () -> load(file)); } @Test void rejectsMalformedYaml() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: [\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: [\n"); assertThrows(YAMLException.class, () -> load(file)); } @@ -83,16 +83,16 @@ void missingOrganizationNameIsRejectedWithoutBundledFallback() throws IOExceptio @Test void existingConfigurationIsLoadedWithoutBeingOverwritten() throws IOException { - String content = "# Custom settings\norganizationName: External Organization\n"; + String content = "# Custom settings\norganization: External Organization\n"; Path file = Files.writeString(tempDir.resolve("application.yaml"), content); - assertEquals("External Organization", load(file).getOrganizationName()); + assertEquals("External Organization", load(file).getOrganization()); assertEquals(content, Files.readString(file)); } @Test void malformedConfigurationErrorIdentifiesSourceFile() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: [\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: [\n"); YAMLException error = assertThrows(YAMLException.class, () -> load(file)); @@ -134,14 +134,14 @@ void developmentRunUsesConfigurationInWorkingDirectory() throws IOException { @Test void bindsNumericScalarToStringProperty() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: 123\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: 123\n"); - assertEquals("123", load(file).getOrganizationName()); + assertEquals("123", load(file).getOrganization()); } @Test void rejectsMappingOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: {name: Example}\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: {name: Example}\n"); assertThrows(YAMLException.class, () -> load(file)); } @@ -155,22 +155,22 @@ void rejectsNonMappingDocument() throws IOException { @Test void rejectsNullOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: null\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: null\n"); assertThrows(IllegalArgumentException.class, () -> load(file)); } @Test void rejectsEmptyOrganizationName() throws IOException { - Path file = Files.writeString(tempDir.resolve("application.yaml"), "organizationName: \"\"\n"); + Path file = Files.writeString(tempDir.resolve("application.yaml"), "organization: \"\"\n"); assertThrows(IllegalArgumentException.class, () -> load(file)); } @Test void rejectsDuplicateKeys() throws IOException { - Path file = Files.writeString( - tempDir.resolve("application.yaml"), "organizationName: First\norganizationName: Second\n"); + Path file = + Files.writeString(tempDir.resolve("application.yaml"), "organization: First\norganization: Second\n"); assertThrows(YAMLException.class, () -> load(file)); } From 69d4a4565687a5d61fa6e3227d4c055904a864b3 Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Sat, 14 Nov 2026 20:15:32 +0530 Subject: [PATCH 10/13] feat: year mentioned in banner Signed-off-by: Rajdeep Roy Chowdhury --- .../controller/WelcomeScreenController.java | 4 + src/main/resources/application.yaml | 2 +- src/main/resources/fxml/WelcomeScreen.fxml | 122 ++++++++++-------- 3 files changed, 73 insertions(+), 55 deletions(-) diff --git a/src/main/java/openconsignment/controller/WelcomeScreenController.java b/src/main/java/openconsignment/controller/WelcomeScreenController.java index 937816d..68f870d 100644 --- a/src/main/java/openconsignment/controller/WelcomeScreenController.java +++ b/src/main/java/openconsignment/controller/WelcomeScreenController.java @@ -20,6 +20,9 @@ public class WelcomeScreenController implements Initializable { @FXML private Text organization_name; + @FXML + private Text year; + @Inject public WelcomeScreenController(AppConfig configuration) { this.configuration = configuration; @@ -41,5 +44,6 @@ private void handleOpenGithub(ActionEvent event) { @Override public void initialize(URL url, ResourceBundle rb) { organization_name.setText(configuration.getOrganization()); + year.setText(configuration.getYear()); } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index e147632..8167cdc 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,5 +1,5 @@ organization: "SATYAM AGENCIES" -#year: 2001-02 +year: 2001-02 github: token: "" username: "razdeep" diff --git a/src/main/resources/fxml/WelcomeScreen.fxml b/src/main/resources/fxml/WelcomeScreen.fxml index 645c681..ad21a09 100644 --- a/src/main/resources/fxml/WelcomeScreen.fxml +++ b/src/main/resources/fxml/WelcomeScreen.fxml @@ -1,54 +1,68 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3c2d68c03b168584ad3b9bbe3987f35cf95e5f9b Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Sat, 14 Nov 2026 22:03:53 +0530 Subject: [PATCH 11/13] feat: implemented git clone on absent repo Signed-off-by: Rajdeep Roy Chowdhury --- .../service/BackupService.java | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index a0fb714..4c7a4b9 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -18,6 +19,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.transport.PushResult; +import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; @Slf4j @@ -31,6 +33,49 @@ public BackupService(AppConfig appConfig) { this.appConfig = appConfig; } + private void cloneRepo() throws GitAPIException, IOException, URISyntaxException { + + log.info("executing git clone"); + + AppConfig.Github github = appConfig.getGithub(); + String repoPath = github.getRepository(); + String username = github.getUsername(); + String token = github.getToken(); + String branchName = github.getBranch(); + String remoteName = github.getRemote(); + + if (Files.exists(Path.of(repoPath))) { + log.info("skipping git clone as repo already exist"); + return; + } + + String repoUrl = "https://github.com/" + username + "/" + repoPath + ".git"; + + try (Git ignored = Git.cloneRepository() + .setURI(repoUrl) + .setDirectory(new File(repoPath)) + .setBranch(branchName) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, token)) + .call()) { + + log.info("Authenticated clone successful"); + } + + try (Git git = Git.open(new File(repoPath))) { + + // HTTPS remote + git.remoteAdd() + .setName(remoteName) + .setUri(new URIish("https://github.com/" + username + "/" + repoPath + ".git")) + .call(); + + git.remoteSetUrl() + .setRemoteName("origin") + .setRemoteUri(new URIish("git@github.com:" + username + "/" + repoPath + ".git")) + .call(); + } + } + public boolean checkSync() throws Exception { log.info("executing called"); try { @@ -67,7 +112,7 @@ private void copyRepoToLocal() throws IOException { log.info("Copied {} to {}", repoPath, Constants.DATABASE_FILE_NAME); } - private void pull() throws IOException, GitAPIException { + private void pull() throws IOException, GitAPIException, URISyntaxException { log.info("executing git pull"); AppConfig.Github github = appConfig.getGithub(); @@ -77,6 +122,11 @@ private void pull() throws IOException, GitAPIException { String branchName = github.getBranch(); String remoteName = github.getRemote(); + if (!Files.exists(Path.of(repoPath))) { + log.info("cloning {}", repoPath); + cloneRepo(); + } + log.info("token is {}", token); try (Git git = Git.open(new File(repoPath))) { @@ -95,7 +145,7 @@ private void pull() throws IOException, GitAPIException { } } - public void download() throws GitAPIException, IOException { + public void download() throws GitAPIException, IOException, URISyntaxException { pull(); copyRepoToLocal(); } From b883dbe3aad0e20f256de7abb241cd11ca3ca8da Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Sun, 15 Nov 2026 17:53:40 +0530 Subject: [PATCH 12/13] feat: implemented DatabaseManager to provide abstraction over connection Signed-off-by: Rajdeep Roy Chowdhury --- .../di/ConfigurationModule.java | 8 +- .../openconsignment/di/DatabaseManager.java | 77 +++++++++++++++++++ .../openconsignment/di/DatabaseModule.java | 57 +------------- .../repository/BillRepository.java | 50 ++++++------ .../repository/BuyerRepository.java | 31 ++++---- .../repository/CollectionRepository.java | 70 +++++++++-------- .../repository/PaymentRepository.java | 69 +++++++++-------- .../repository/SupplierRepository.java | 31 ++++---- .../repository/TransportRepository.java | 35 +++++---- .../service/BackupService.java | 9 ++- .../repository/BillRepositoryTest.java | 3 +- .../repository/BuyerRepositoryTest.java | 3 +- .../repository/CollectionRepositoryTest.java | 5 +- .../repository/PaymentRepositoryTest.java | 5 +- .../repository/SupplierRepositoryTest.java | 3 +- .../repository/TransportRepositoryTest.java | 5 +- 16 files changed, 255 insertions(+), 206 deletions(-) create mode 100644 src/main/java/openconsignment/di/DatabaseManager.java diff --git a/src/main/java/openconsignment/di/ConfigurationModule.java b/src/main/java/openconsignment/di/ConfigurationModule.java index eb43f6c..5cc1d76 100644 --- a/src/main/java/openconsignment/di/ConfigurationModule.java +++ b/src/main/java/openconsignment/di/ConfigurationModule.java @@ -11,20 +11,18 @@ import java.nio.file.Files; import java.nio.file.Path; import javax.inject.Singleton; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.AppConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.error.YAMLException; /** Creates the external configuration on first startup and provides validated settings from it. */ +@Slf4j @Module public final class ConfigurationModule { - private static final Logger logger = LoggerFactory.getLogger(ConfigurationModule.class); - private static final String CONFIGURATION_FILE = "application.yaml"; private static final String DEFAULTS_RESOURCE = "/" + CONFIGURATION_FILE; @@ -77,7 +75,7 @@ private static void initializeConfiguration(Path path) throws IOException { } try { Files.copy(defaults, path); - logger.info("Generated new application.yaml as it was missing at {}", path); + log.info("Generated new application.yaml as it was missing at {}", path); } catch (FileAlreadyExistsException ex) { // Another startup created the file; preserve it and load its contents. } diff --git a/src/main/java/openconsignment/di/DatabaseManager.java b/src/main/java/openconsignment/di/DatabaseManager.java new file mode 100644 index 0000000..fbcf1ca --- /dev/null +++ b/src/main/java/openconsignment/di/DatabaseManager.java @@ -0,0 +1,77 @@ +package openconsignment.di; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import openconsignment.common.Constants; + +@Slf4j +public class DatabaseManager { + + private Connection connection; + + public DatabaseManager(Connection connection) { + this.connection = connection; + } + + public synchronized Connection getConnection() throws SQLException { + + if (connection == null || connection.isClosed()) { + connection = DriverManager.getConnection("jdbc:sqlite:" + Constants.DATABASE_FILE_NAME); + initDatabase(connection); + } + + return connection; + } + + public synchronized void closeConnection() throws SQLException { + + if (connection != null && !connection.isClosed()) { + connection.close(); + } + + connection = null; + } + + public synchronized void reopenConnection() throws SQLException { + closeConnection(); + getConnection(); + } + + private static void initDatabase(Connection conn) { + try { + String initSQL = getInitSQL(); + try (Statement st = conn.createStatement()) { + conn.setAutoCommit(false); + + for (String statement : initSQL.split(";")) { + String cleanedStatement = statement.trim(); + if (!cleanedStatement.isEmpty()) { + st.execute(cleanedStatement); + } + } + + conn.commit(); + } catch (Exception e) { + conn.rollback(); + throw e; + } finally { + conn.setAutoCommit(true); + } + } catch (Exception ex) { + log.error(ex.toString(), ex); + } + } + + private static String getInitSQL() throws IOException { + return new String( + Objects.requireNonNull(DatabaseModule.class.getResourceAsStream("/sql/init.sql")) + .readAllBytes(), + StandardCharsets.UTF_8); + } +} diff --git a/src/main/java/openconsignment/di/DatabaseModule.java b/src/main/java/openconsignment/di/DatabaseModule.java index c6ae947..29008b0 100644 --- a/src/main/java/openconsignment/di/DatabaseModule.java +++ b/src/main/java/openconsignment/di/DatabaseModule.java @@ -2,68 +2,15 @@ import dagger.Module; import dagger.Provides; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Objects; import javax.inject.Singleton; -import openconsignment.common.Constants; -import openconsignment.common.Utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @Module @SuppressWarnings("unused") public class DatabaseModule { - private static final Logger logger = LoggerFactory.getLogger(DatabaseModule.class); @Provides @Singleton - static Connection provideConnection() { - try { - Class.forName("org.sqlite.JDBC"); - Connection conn = DriverManager.getConnection("jdbc:sqlite:" + Constants.DATABASE_FILE_NAME); - initDatabase(conn); - return conn; - } catch (ClassNotFoundException | SQLException ex) { - Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); - throw new RuntimeException(ex); - } - } - - private static void initDatabase(Connection conn) { - try { - String initSQL = getInitSQL(); - try (Statement st = conn.createStatement()) { - conn.setAutoCommit(false); - - for (String statement : initSQL.split(";")) { - String cleanedStatement = statement.trim(); - if (!cleanedStatement.isEmpty()) { - st.execute(cleanedStatement); - } - } - - conn.commit(); - } catch (Exception e) { - conn.rollback(); - throw e; - } finally { - conn.setAutoCommit(true); - } - } catch (Exception ex) { - logger.error(ex.toString(), ex); - } - } - - private static String getInitSQL() throws IOException { - return new String( - Objects.requireNonNull(DatabaseModule.class.getResourceAsStream("/sql/init.sql")) - .readAllBytes(), - StandardCharsets.UTF_8); + static DatabaseManager provideDatabaseManager() { + return new DatabaseManager(null); } } diff --git a/src/main/java/openconsignment/repository/BillRepository.java b/src/main/java/openconsignment/repository/BillRepository.java index a1a5971..7c54187 100644 --- a/src/main/java/openconsignment/repository/BillRepository.java +++ b/src/main/java/openconsignment/repository/BillRepository.java @@ -1,38 +1,38 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.LREntity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class BillRepository { - private static final Logger logger = LoggerFactory.getLogger(BillRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public BillRepository(Connection conn) { - this.conn = conn; + public BillRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void save(BillEntity billEntity) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BILL_SAVE); - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); deleteBill(billEntity.getBillNo()); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billEntity.getSupplierName()); preparedStatement.setString(2, billEntity.getBuyerName()); preparedStatement.setString(3, billEntity.getBillNo()); @@ -47,17 +47,17 @@ public void save(BillEntity billEntity) throws SQLException { if (null != billEntity.getLrEntities()) { for (LREntity lr : billEntity.getLrEntities()) { sql = SqlLoader.load(SqlQuery.BILL_SAVE_LR); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billEntity.getBillNo()); preparedStatement.setString(2, lr.getLrNo()); preparedStatement.setString(3, lr.getPm()); preparedStatement.execute(); } } - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); throw ex; } } @@ -65,7 +65,8 @@ public void save(BillEntity billEntity) throws SQLException { public BillEntity getBill(String billNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BILL_GET); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet billResultSet = preparedStatement.executeQuery(); @@ -84,7 +85,7 @@ public BillEntity getBill(String billNo) throws SQLException { .build(); sql = SqlLoader.load(SqlQuery.BILL_GET_LRS); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet lrPmResultSet = preparedStatement.executeQuery(); @@ -99,28 +100,29 @@ public BillEntity getBill(String billNo) throws SQLException { billEntity.setLrEntities(lrpmList); return billEntity; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void deleteBill(String billNo) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); String sql = SqlLoader.load(SqlQuery.BILL_DELETE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); preparedStatement.execute(); String sql2 = SqlLoader.load(SqlQuery.BILL_DELETE_LRS); - preparedStatement = conn.prepareStatement(sql2); + preparedStatement = databaseManager.getConnection().prepareStatement(sql2); preparedStatement.setString(1, billNo); preparedStatement.execute(); - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); throw ex; } } @@ -129,7 +131,7 @@ public List getBills() throws SQLException { List res = new ArrayList<>(); try { String sql = SqlLoader.load(SqlQuery.BILL_GET_ALL); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { res.add(BillEntity.builder() @@ -145,7 +147,7 @@ public List getBills() throws SQLException { } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/BuyerRepository.java b/src/main/java/openconsignment/repository/BuyerRepository.java index 8e4d23f..1bcfd9b 100644 --- a/src/main/java/openconsignment/repository/BuyerRepository.java +++ b/src/main/java/openconsignment/repository/BuyerRepository.java @@ -1,35 +1,34 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import openconsignment.di.DatabaseManager; +@Slf4j public class BuyerRepository { - private static final Logger logger = LoggerFactory.getLogger(BuyerRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public BuyerRepository(Connection conn) { - this.conn = conn; + public BuyerRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void saveBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BUYER_SAVE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, buyerName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -37,11 +36,11 @@ public void saveBuyer(String buyerName) throws SQLException { public void deleteBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BUYER_DELETE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, buyerName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -49,12 +48,12 @@ public void deleteBuyer(String buyerName) throws SQLException { public void renameBuyer(String oldName, String newName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.BUYER_RENAME); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, newName); ps.setString(2, oldName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -62,14 +61,16 @@ public void renameBuyer(String oldName, String newName) throws SQLException { public List getAllBuyers() throws SQLException { try { List buyerList = new ArrayList<>(); - ResultSet buyerResultSet = conn.prepareStatement(SqlLoader.load(SqlQuery.BUYER_GET_ALL)) + ResultSet buyerResultSet = databaseManager + .getConnection() + .prepareStatement(SqlLoader.load(SqlQuery.BUYER_GET_ALL)) .executeQuery(); while (buyerResultSet.next()) { buyerList.add(buyerResultSet.getString("name")); } return buyerList; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/CollectionRepository.java b/src/main/java/openconsignment/repository/CollectionRepository.java index 41daf5c..81f9a36 100644 --- a/src/main/java/openconsignment/repository/CollectionRepository.java +++ b/src/main/java/openconsignment/repository/CollectionRepository.java @@ -1,36 +1,36 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; import openconsignment.common.Utils; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.CollectionEntity; import openconsignment.entity.CollectionItemEntity; import openconsignment.model.BuyerLedgerRow; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class CollectionRepository { - private static final Logger logger = LoggerFactory.getLogger(CollectionRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public CollectionRepository(Connection conn) { - this.conn = conn; + public CollectionRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public List fetchPendingBillsForBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_PENDING_BILLS_FOR_BUYER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, buyerName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -45,7 +45,7 @@ public List fetchPendingBillsForBuyer(String buyerName) throws SQLEx } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -53,7 +53,8 @@ public List fetchPendingBillsForBuyer(String buyerName) throws SQLEx public int fetchPendingAmountForBillNo(String billNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_PENDING_AMOUNT_FOR_BILL); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet resultSet = preparedStatement.executeQuery(); @@ -63,17 +64,18 @@ public int fetchPendingAmountForBillNo(String billNo) throws SQLException { return resultSet.getInt("pending_amount"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void saveCollection(CollectionEntity collectionEntity) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); deleteCollection(collectionEntity.getVoucherNo()); String sql = SqlLoader.load(SqlQuery.COLLECTION_SAVE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, collectionEntity.getVoucherNo()); preparedStatement.setString(2, collectionEntity.getVoucherDate()); preparedStatement.setString(3, collectionEntity.getBuyerName()); @@ -85,7 +87,7 @@ public void saveCollection(CollectionEntity collectionEntity) throws SQLExceptio if (null != collectionEntity.getItems()) { for (CollectionItemEntity collectionItem : collectionEntity.getItems()) { - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, collectionEntity.getVoucherNo()); preparedStatement.setString(2, collectionItem.getSupplierName()); preparedStatement.setString(3, collectionItem.getBillNo()); @@ -101,11 +103,11 @@ public void saveCollection(CollectionEntity collectionEntity) throws SQLExceptio } } - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); throw ex; } } @@ -113,11 +115,12 @@ public void saveCollection(CollectionEntity collectionEntity) throws SQLExceptio public String getLastVoucher() throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_LAST_VOUCHER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); return resultSet.getString("Max(`Voucher No.`)"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -126,7 +129,8 @@ public CollectionEntity getCollection(String voucherNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_GET_ITEMS); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); ResultSet collectionResultSet = preparedStatement.executeQuery(); @@ -146,7 +150,7 @@ public CollectionEntity getCollection(String voucherNo) throws SQLException { } sql = SqlLoader.load(SqlQuery.COLLECTION_GET); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); collectionResultSet = preparedStatement.executeQuery(); if (collectionResultSet.isClosed()) { @@ -161,31 +165,32 @@ public CollectionEntity getCollection(String voucherNo) throws SQLException { .items(collectionItemList) .build(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void deleteCollection(String voucherNo) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); String sql = SqlLoader.load(SqlQuery.COLLECTION_DELETE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); sql = SqlLoader.load(SqlQuery.COLLECTION_DELETE_ITEMS); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); - conn.rollback(); + log.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); } } @@ -193,7 +198,7 @@ public List getCollections() throws SQLException { try { List res = new ArrayList<>(); String sql = SqlLoader.load(SqlQuery.COLLECTION_GET_ALL); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { res.add(CollectionEntity.builder() @@ -206,7 +211,7 @@ public List getCollections() throws SQLException { } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -214,7 +219,8 @@ public List getCollections() throws SQLException { public List getCollectionDetailsForBuyer(String buyerName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.COLLECTION_DETAILS_FOR_BUYER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, buyerName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -235,7 +241,7 @@ public List getCollectionDetailsForBuyer(String buyerName) throw } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/PaymentRepository.java b/src/main/java/openconsignment/repository/PaymentRepository.java index 89c1b11..0907049 100644 --- a/src/main/java/openconsignment/repository/PaymentRepository.java +++ b/src/main/java/openconsignment/repository/PaymentRepository.java @@ -1,38 +1,38 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; import openconsignment.common.Utils; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.PaymentEntity; import openconsignment.entity.PaymentItemEntity; import openconsignment.model.SupplierLedgerRow; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class PaymentRepository { - private static final Logger logger = LoggerFactory.getLogger(PaymentRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public PaymentRepository(Connection conn) { - this.conn = conn; + public PaymentRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void savePayment(PaymentEntity paymentEntity) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); deletePayment(paymentEntity.getVoucherNo()); String sql = SqlLoader.load(SqlQuery.PAYMENT_SAVE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, paymentEntity.getVoucherNo()); preparedStatement.setString(2, paymentEntity.getVoucherDate()); preparedStatement.setString(3, paymentEntity.getSupplierName()); @@ -44,7 +44,7 @@ public void savePayment(PaymentEntity paymentEntity) throws SQLException { if (null != paymentEntity.getItems()) { for (PaymentItemEntity paymentItem : paymentEntity.getItems()) { - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, paymentEntity.getVoucherNo()); preparedStatement.setString(2, paymentItem.getBuyerName()); preparedStatement.setString(3, paymentItem.getBillNo()); @@ -59,17 +59,18 @@ public void savePayment(PaymentEntity paymentEntity) throws SQLException { preparedStatement.execute(); } } - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { - conn.rollback(); - logger.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); + log.error(ex.toString(), ex); } } public List fetchPendingBillsForSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_PENDING_BILLS_FOR_SUPPLIER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, supplierName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -84,7 +85,7 @@ public List fetchPendingBillsForSupplier(String supplierName) throws } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -92,7 +93,8 @@ public List fetchPendingBillsForSupplier(String supplierName) throws public int fetchPendingAmountForBillNo(String billNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_PENDING_AMOUNT_FOR_BILL); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, billNo); ResultSet resultSet = preparedStatement.executeQuery(); @@ -102,7 +104,7 @@ public int fetchPendingAmountForBillNo(String billNo) throws SQLException { return resultSet.getInt("pending_amount"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -110,11 +112,12 @@ public int fetchPendingAmountForBillNo(String billNo) throws SQLException { public String getLastVoucher() throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_LAST_VOUCHER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); return resultSet.getString("Max(`Voucher No.`)"); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -122,7 +125,7 @@ public String getLastVoucher() throws SQLException { public PaymentEntity getPayment(String voucherNo) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_GET_ITEMS); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, voucherNo); ResultSet rs = ps.executeQuery(); @@ -145,7 +148,7 @@ public PaymentEntity getPayment(String voucherNo) throws SQLException { sql = SqlLoader.load(SqlQuery.PAYMENT_GET); - ps = conn.prepareStatement(sql); + ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, voucherNo); rs = ps.executeQuery(); @@ -163,31 +166,32 @@ public PaymentEntity getPayment(String voucherNo) throws SQLException { } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } public void deletePayment(String voucherNo) throws SQLException { try { - conn.setAutoCommit(false); + databaseManager.getConnection().setAutoCommit(false); String sql = SqlLoader.load(SqlQuery.PAYMENT_DELETE); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); sql = SqlLoader.load(SqlQuery.PAYMENT_DELETE_ITEMS); - preparedStatement = conn.prepareStatement(sql); + preparedStatement = databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, voucherNo); preparedStatement.execute(); - conn.commit(); + databaseManager.getConnection().commit(); } catch (SQLException ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); - conn.rollback(); + log.error(ex.toString(), ex); + databaseManager.getConnection().rollback(); } } @@ -195,7 +199,7 @@ public List getPayments() throws SQLException { try { List res = new ArrayList<>(); String sql = SqlLoader.load(SqlQuery.PAYMENT_GET_ALL); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { res.add(PaymentEntity.builder() @@ -208,7 +212,7 @@ public List getPayments() throws SQLException { } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -216,7 +220,8 @@ public List getPayments() throws SQLException { public List getPaymentDetailsForSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.PAYMENT_DETAILS_FOR_SUPPLIER); - PreparedStatement preparedStatement = conn.prepareStatement(sql); + PreparedStatement preparedStatement = + databaseManager.getConnection().prepareStatement(sql); preparedStatement.setString(1, supplierName); ResultSet resultSet = preparedStatement.executeQuery(); @@ -237,7 +242,7 @@ public List getPaymentDetailsForSupplier(String supplierName) } return res; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/SupplierRepository.java b/src/main/java/openconsignment/repository/SupplierRepository.java index 9534dbd..556a3a1 100644 --- a/src/main/java/openconsignment/repository/SupplierRepository.java +++ b/src/main/java/openconsignment/repository/SupplierRepository.java @@ -1,35 +1,34 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import openconsignment.di.DatabaseManager; +@Slf4j public class SupplierRepository { - private static final Logger logger = LoggerFactory.getLogger(SupplierRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public SupplierRepository(Connection conn) { - this.conn = conn; + public SupplierRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void saveSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.SUPPLIER_SAVE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, supplierName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -37,11 +36,11 @@ public void saveSupplier(String supplierName) throws SQLException { public void deleteSupplier(String supplierName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.SUPPLIER_DELETE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, supplierName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -49,12 +48,12 @@ public void deleteSupplier(String supplierName) throws SQLException { public void renameSupplier(String oldName, String newName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.SUPPLIER_RENAME); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, newName); ps.setString(2, oldName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -62,14 +61,16 @@ public void renameSupplier(String oldName, String newName) throws SQLException { public List getAllSuppliers() throws SQLException { try { List supplierList = new ArrayList<>(); - ResultSet supplierResultSet = conn.prepareStatement(SqlLoader.load(SqlQuery.SUPPLIER_GET_ALL)) + ResultSet supplierResultSet = databaseManager + .getConnection() + .prepareStatement(SqlLoader.load(SqlQuery.SUPPLIER_GET_ALL)) .executeQuery(); while (supplierResultSet.next()) { supplierList.add(supplierResultSet.getString("name")); } return supplierList; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/repository/TransportRepository.java b/src/main/java/openconsignment/repository/TransportRepository.java index b2679b1..44a5e9c 100644 --- a/src/main/java/openconsignment/repository/TransportRepository.java +++ b/src/main/java/openconsignment/repository/TransportRepository.java @@ -1,36 +1,35 @@ package openconsignment.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.SqlLoader; import openconsignment.common.SqlQuery; +import openconsignment.di.DatabaseManager; import openconsignment.model.TransportLedgerRow; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class TransportRepository { - private static final Logger logger = LoggerFactory.getLogger(TransportRepository.class); - private final Connection conn; + private final DatabaseManager databaseManager; @Inject - public TransportRepository(Connection conn) { - this.conn = conn; + public TransportRepository(DatabaseManager databaseManager) { + this.databaseManager = databaseManager; } public void saveTransport(String transportName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.TRANSPORT_SAVE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, transportName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -38,11 +37,11 @@ public void saveTransport(String transportName) throws SQLException { public void deleteTransport(String transportName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.TRANSPORT_DELETE); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, transportName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -50,12 +49,12 @@ public void deleteTransport(String transportName) throws SQLException { public void renameTransport(String oldName, String newName) throws SQLException { try { String sql = SqlLoader.load(SqlQuery.TRANSPORT_RENAME); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, newName); ps.setString(2, oldName); ps.execute(); } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -63,14 +62,16 @@ public void renameTransport(String oldName, String newName) throws SQLException public List getAllTransports() throws SQLException { try { List transportList = new ArrayList<>(); - ResultSet transportResultSet = conn.prepareStatement(SqlLoader.load(SqlQuery.TRANSPORT_GET_ALL)) + ResultSet transportResultSet = databaseManager + .getConnection() + .prepareStatement(SqlLoader.load(SqlQuery.TRANSPORT_GET_ALL)) .executeQuery(); while (transportResultSet.next()) { transportList.add(transportResultSet.getString("name")); } return transportList; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } @@ -82,7 +83,7 @@ public List getTransportReportFor(String transportName, Stri String sql = SqlLoader.load(SqlQuery.TRANSPORT_REPORT); - PreparedStatement ps = conn.prepareStatement(sql); + PreparedStatement ps = databaseManager.getConnection().prepareStatement(sql); ps.setString(1, transportName); ps.setString(2, fromDate); ps.setString(3, fromDate); @@ -105,7 +106,7 @@ public List getTransportReportFor(String transportName, Stri } return result; } catch (SQLException ex) { - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); throw ex; } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index 4c7a4b9..a9559e8 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -6,6 +6,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.sql.SQLException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import javax.inject.Inject; @@ -14,6 +15,7 @@ import openconsignment.common.AppConfig; import openconsignment.common.Constants; import openconsignment.common.Utils; +import openconsignment.di.DatabaseManager; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PullResult; import org.eclipse.jgit.api.errors.GitAPIException; @@ -27,10 +29,12 @@ public class BackupService { private final AppConfig appConfig; + private final DatabaseManager databaseManager; @Inject - public BackupService(AppConfig appConfig) { + public BackupService(AppConfig appConfig, DatabaseManager databaseManager) { this.appConfig = appConfig; + this.databaseManager = databaseManager; } private void cloneRepo() throws GitAPIException, IOException, URISyntaxException { @@ -145,9 +149,10 @@ private void pull() throws IOException, GitAPIException, URISyntaxException { } } - public void download() throws GitAPIException, IOException, URISyntaxException { + public void download() throws GitAPIException, IOException, URISyntaxException, SQLException { pull(); copyRepoToLocal(); + databaseManager.reopenConnection(); } private void copyLocalToRepo() throws IOException { diff --git a/src/test/java/openconsignment/repository/BillRepositoryTest.java b/src/test/java/openconsignment/repository/BillRepositoryTest.java index 8347eae..19a8895 100644 --- a/src/test/java/openconsignment/repository/BillRepositoryTest.java +++ b/src/test/java/openconsignment/repository/BillRepositoryTest.java @@ -6,6 +6,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.LREntity; import org.junit.jupiter.api.AfterEach; @@ -20,7 +21,7 @@ class BillRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - billRepository = new BillRepository(conn); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/BuyerRepositoryTest.java b/src/test/java/openconsignment/repository/BuyerRepositoryTest.java index 5cf9329..fa66dc6 100644 --- a/src/test/java/openconsignment/repository/BuyerRepositoryTest.java +++ b/src/test/java/openconsignment/repository/BuyerRepositoryTest.java @@ -5,6 +5,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -17,7 +18,7 @@ class BuyerRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - buyerRepository = new BuyerRepository(conn); + buyerRepository = new BuyerRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/CollectionRepositoryTest.java b/src/test/java/openconsignment/repository/CollectionRepositoryTest.java index 31cf046..1b25160 100644 --- a/src/test/java/openconsignment/repository/CollectionRepositoryTest.java +++ b/src/test/java/openconsignment/repository/CollectionRepositoryTest.java @@ -6,6 +6,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.CollectionEntity; import openconsignment.entity.CollectionItemEntity; @@ -23,8 +24,8 @@ class CollectionRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - collectionRepository = new CollectionRepository(conn); - billRepository = new BillRepository(conn); + collectionRepository = new CollectionRepository(new DatabaseManager(conn)); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/PaymentRepositoryTest.java b/src/test/java/openconsignment/repository/PaymentRepositoryTest.java index cbf797d..5e903ad 100644 --- a/src/test/java/openconsignment/repository/PaymentRepositoryTest.java +++ b/src/test/java/openconsignment/repository/PaymentRepositoryTest.java @@ -6,6 +6,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.PaymentEntity; import openconsignment.entity.PaymentItemEntity; @@ -23,8 +24,8 @@ class PaymentRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - paymentRepository = new PaymentRepository(conn); - billRepository = new BillRepository(conn); + paymentRepository = new PaymentRepository(new DatabaseManager(conn)); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/SupplierRepositoryTest.java b/src/test/java/openconsignment/repository/SupplierRepositoryTest.java index e5efdfc..eaa5fb4 100644 --- a/src/test/java/openconsignment/repository/SupplierRepositoryTest.java +++ b/src/test/java/openconsignment/repository/SupplierRepositoryTest.java @@ -5,6 +5,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -17,7 +18,7 @@ class SupplierRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - supplierRepository = new SupplierRepository(conn); + supplierRepository = new SupplierRepository(new DatabaseManager(conn)); } @AfterEach diff --git a/src/test/java/openconsignment/repository/TransportRepositoryTest.java b/src/test/java/openconsignment/repository/TransportRepositoryTest.java index b0b1165..3f480db 100644 --- a/src/test/java/openconsignment/repository/TransportRepositoryTest.java +++ b/src/test/java/openconsignment/repository/TransportRepositoryTest.java @@ -5,6 +5,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.List; +import openconsignment.di.DatabaseManager; import openconsignment.entity.BillEntity; import openconsignment.entity.LREntity; import openconsignment.model.TransportLedgerRow; @@ -21,8 +22,8 @@ class TransportRepositoryTest { @BeforeEach void setUp() throws Exception { conn = RepositoryTestSupport.newInMemoryConnection(); - transportRepository = new TransportRepository(conn); - billRepository = new BillRepository(conn); + transportRepository = new TransportRepository(new DatabaseManager(conn)); + billRepository = new BillRepository(new DatabaseManager(conn)); } @AfterEach From 8f1f27673c9504cb1c2d1a603485f3f329f4133c Mon Sep 17 00:00:00 2001 From: Rajdeep Roy Chowdhury Date: Sun, 15 Nov 2026 23:32:06 +0530 Subject: [PATCH 13/13] fix: fixed backup upload when empty remote initial repository Signed-off-by: Rajdeep Roy Chowdhury --- src/main/java/openconsignment/Launcher.java | 9 ++- .../controller/MainController.java | 4 -- .../controller/WelcomeScreenController.java | 12 +++- .../service/BackupService.java | 59 +++++++++++-------- .../java/functional/WelcomeScreenTest.java | 15 ++++- .../repository/RepositoryTestSupport.java | 4 +- 6 files changed, 63 insertions(+), 40 deletions(-) diff --git a/src/main/java/openconsignment/Launcher.java b/src/main/java/openconsignment/Launcher.java index 27773ab..4431331 100644 --- a/src/main/java/openconsignment/Launcher.java +++ b/src/main/java/openconsignment/Launcher.java @@ -8,14 +8,13 @@ import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.stage.Stage; +import lombok.extern.slf4j.Slf4j; import openconsignment.common.Utils; import openconsignment.di.AppComponent; import openconsignment.di.DaggerAppComponent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +@Slf4j public class Launcher extends Application { - private static final Logger logger = LoggerFactory.getLogger(Launcher.class); public static void main(String[] args) { launch(args); @@ -43,10 +42,10 @@ public void start(Stage stage) { stage.getIcons().add(new Image(resourceAsStream)); } stage.setTitle("OpenConsignment"); - logger.info("OpenConsignment started at {}", java.time.LocalDateTime.now()); + log.info("OpenConsignment started at {}", java.time.LocalDateTime.now()); } catch (Exception ex) { Utils.showAlert(ex.toString()); - logger.error(ex.toString(), ex); + log.error(ex.toString(), ex); } } } diff --git a/src/main/java/openconsignment/controller/MainController.java b/src/main/java/openconsignment/controller/MainController.java index b3420d8..80a3151 100644 --- a/src/main/java/openconsignment/controller/MainController.java +++ b/src/main/java/openconsignment/controller/MainController.java @@ -14,7 +14,6 @@ import openconsignment.common.Utils; import openconsignment.common.ViewLoader; import openconsignment.service.BackupService; -import org.eclipse.jgit.api.errors.EmptyCommitException; @Slf4j @SuppressWarnings("unused") @@ -152,9 +151,6 @@ private void upload(ActionEvent event) { } backupService.upload(); Utils.showAlert("Successfully uploaded", Alert.AlertType.INFORMATION); - } catch (EmptyCommitException e) { - log.info(e.toString()); - Utils.showAlert("Data is already synced. " + e, Alert.AlertType.INFORMATION); } catch (Exception e) { log.error(e.toString()); Utils.showAlert(e.toString(), Alert.AlertType.ERROR); diff --git a/src/main/java/openconsignment/controller/WelcomeScreenController.java b/src/main/java/openconsignment/controller/WelcomeScreenController.java index 68f870d..ba1f82e 100644 --- a/src/main/java/openconsignment/controller/WelcomeScreenController.java +++ b/src/main/java/openconsignment/controller/WelcomeScreenController.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.net.URL; +import java.sql.SQLException; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -12,10 +13,12 @@ import lombok.extern.slf4j.Slf4j; import openconsignment.common.AppConfig; import openconsignment.common.Utils; +import openconsignment.di.DatabaseManager; @Slf4j public class WelcomeScreenController implements Initializable { private final AppConfig configuration; + private final DatabaseManager databaseManager; @FXML private Text organization_name; @@ -24,8 +27,9 @@ public class WelcomeScreenController implements Initializable { private Text year; @Inject - public WelcomeScreenController(AppConfig configuration) { + public WelcomeScreenController(AppConfig configuration, DatabaseManager databaseManager) { this.configuration = configuration; + this.databaseManager = databaseManager; } @FXML @@ -45,5 +49,11 @@ private void handleOpenGithub(ActionEvent event) { public void initialize(URL url, ResourceBundle rb) { organization_name.setText(configuration.getOrganization()); year.setText(configuration.getYear()); + try { + databaseManager.getConnection(); + } catch (SQLException e) { + log.error(e.toString()); + Utils.showAlert(e.toString()); + } } } diff --git a/src/main/java/openconsignment/service/BackupService.java b/src/main/java/openconsignment/service/BackupService.java index a9559e8..f3530e7 100644 --- a/src/main/java/openconsignment/service/BackupService.java +++ b/src/main/java/openconsignment/service/BackupService.java @@ -18,6 +18,7 @@ import openconsignment.di.DatabaseManager; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PullResult; +import org.eclipse.jgit.api.errors.EmptyCommitException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.transport.PushResult; @@ -77,6 +78,10 @@ private void cloneRepo() throws GitAPIException, IOException, URISyntaxException .setRemoteName("origin") .setRemoteUri(new URIish("git@github.com:" + username + "/" + repoPath + ".git")) .call(); + + if (null == git.getRepository().resolve("HEAD")) { + git.getRepository().updateRef("HEAD").link("refs/heads/" + branchName); + } } } @@ -92,7 +97,11 @@ public boolean checkSync() throws Exception { } private String getRepoFileHash() throws Exception { - return Utils.md5sum(Path.of(appConfig.getGithub().getRepository() + "/" + Constants.DATABASE_FILE_NAME)); + Path remotePath = Path.of(appConfig.getGithub().getRepository() + "/" + Constants.DATABASE_FILE_NAME); + if (!Files.exists(remotePath)) { + return ""; + } + return Utils.md5sum(remotePath); } public boolean compareDatabaseHashes() throws Exception { @@ -120,31 +129,29 @@ private void pull() throws IOException, GitAPIException, URISyntaxException { log.info("executing git pull"); AppConfig.Github github = appConfig.getGithub(); - String repoPath = github.getRepository(); - String username = github.getUsername(); - String token = github.getToken(); - String branchName = github.getBranch(); - String remoteName = github.getRemote(); - if (!Files.exists(Path.of(repoPath))) { - log.info("cloning {}", repoPath); + log.info("token is {}", github.getToken()); + + if (!Files.exists(Path.of(github.getRepository()))) { + log.info("cloning {}", github.getRepository()); cloneRepo(); + log.info("cloned {}", github.getRepository()); + return; } - log.info("token is {}", token); - - try (Git git = Git.open(new File(repoPath))) { + try (Git git = Git.open(new File(github.getRepository()))) { PullResult result = git.pull() - .setRemote(remoteName) - .setRemoteBranchName(branchName) - .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, token)) + .setRemote(github.getRemote()) + .setRemoteBranchName(github.getBranch()) + .setCredentialsProvider( + new UsernamePasswordCredentialsProvider(github.getUsername(), github.getToken())) .call(); if (result.isSuccessful()) { - log.info("Successfully pulled: {}", branchName); + log.info("Successfully pulled: {}", github.getBranch()); } else { - throw new IllegalStateException("Pull failed for branch: " + branchName); + throw new IllegalStateException("Pull failed for branch: " + github.getBranch()); } } } @@ -203,18 +210,14 @@ private void push() throws IOException, GitAPIException { log.info("executing git push"); AppConfig.Github github = appConfig.getGithub(); - String repoPath = github.getRepository(); - String username = github.getUsername(); - String token = github.getToken(); - String branchName = github.getBranch(); - String remoteName = github.getRemote(); - log.info("token is {}", token); + log.info("pushing with token {}", github.getToken()); - try (Git git = Git.open(new File(repoPath))) { + try (Git git = Git.open(new File(github.getRepository()))) { Iterable results = git.push() - .setRemote(remoteName) - .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, token)) + .setRemote(github.getRemote()) + .setCredentialsProvider( + new UsernamePasswordCredentialsProvider(github.getUsername(), github.getToken())) .call(); for (PushResult result : results) { @@ -225,7 +228,11 @@ private void push() throws IOException, GitAPIException { public void upload() throws GitAPIException, IOException { copyLocalToRepo(); - addAndCommit(); + try { + addAndCommit(); + } catch (EmptyCommitException ex) { + log.info("swallowing EmptyCommitException"); + } push(); } } diff --git a/src/test/java/functional/WelcomeScreenTest.java b/src/test/java/functional/WelcomeScreenTest.java index 125cdca..406b6c5 100644 --- a/src/test/java/functional/WelcomeScreenTest.java +++ b/src/test/java/functional/WelcomeScreenTest.java @@ -2,6 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.io.IOException; +import java.sql.SQLException; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; @@ -9,6 +11,8 @@ import javafx.stage.Stage; import openconsignment.common.AppConfig; import openconsignment.controller.WelcomeScreenController; +import openconsignment.di.DatabaseManager; +import openconsignment.repository.RepositoryTestSupport; import org.junit.jupiter.api.Test; import org.testfx.framework.junit5.ApplicationTest; @@ -16,8 +20,15 @@ class WelcomeScreenTest extends ApplicationTest { @Override public void start(Stage stage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/WelcomeScreen.fxml")); - loader.setControllerFactory( - type -> new WelcomeScreenController(AppConfig.forOrganization("Configured Organization"))); + loader.setControllerFactory(type -> { + try { + return new WelcomeScreenController( + AppConfig.forOrganization("Configured Organization"), + new DatabaseManager(RepositoryTestSupport.newInMemoryConnection())); + } catch (ClassNotFoundException | IOException | SQLException e) { + throw new RuntimeException(e); + } + }); Parent root = loader.load(); stage.setScene(new Scene(root)); stage.show(); diff --git a/src/test/java/openconsignment/repository/RepositoryTestSupport.java b/src/test/java/openconsignment/repository/RepositoryTestSupport.java index 0fb52a2..4b892e6 100644 --- a/src/test/java/openconsignment/repository/RepositoryTestSupport.java +++ b/src/test/java/openconsignment/repository/RepositoryTestSupport.java @@ -8,11 +8,11 @@ import java.sql.Statement; import java.util.Objects; -final class RepositoryTestSupport { +public final class RepositoryTestSupport { private RepositoryTestSupport() {} - static Connection newInMemoryConnection() throws ClassNotFoundException, SQLException, IOException { + public static Connection newInMemoryConnection() throws ClassNotFoundException, SQLException, IOException { Class.forName("org.sqlite.JDBC"); Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:"); try (Statement st = conn.createStatement()) {