From 2ff60ad9852ee06cca3892d4647e0340738b3575 Mon Sep 17 00:00:00 2001 From: Steve Schafer Date: Mon, 19 Jan 2026 11:04:50 -0700 Subject: [PATCH] Finish implemention of budgets. --- .../stephenschafer/budget/BudgetAmounts.java | 13 +++++ .../com/stephenschafer/budget/CatRegex.java | 2 +- .../stephenschafer/budget/ReportCategory.java | 26 +++++++++- .../budget/ReportController.java | 49 ++++++++++++++++--- ...mount.sql => createBudgetAmountsTable.sql} | 2 +- src/main/resources/dropBudgetAmountsTable.sql | 1 + .../budget => resources}/getBudgetAmounts.sql | 0 src/main/resources/insertBudgetAmounts.sql | 4 ++ 8 files changed, 87 insertions(+), 10 deletions(-) rename src/main/resources/{createIfNotExistBudgetAmount.sql => createBudgetAmountsTable.sql} (86%) create mode 100644 src/main/resources/dropBudgetAmountsTable.sql rename src/main/{java/com/stephenschafer/budget => resources}/getBudgetAmounts.sql (100%) create mode 100644 src/main/resources/insertBudgetAmounts.sql diff --git a/src/main/java/com/stephenschafer/budget/BudgetAmounts.java b/src/main/java/com/stephenschafer/budget/BudgetAmounts.java index d110a3f..7a2af27 100644 --- a/src/main/java/com/stephenschafer/budget/BudgetAmounts.java +++ b/src/main/java/com/stephenschafer/budget/BudgetAmounts.java @@ -4,6 +4,8 @@ import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; +import com.fasterxml.jackson.annotation.JsonIgnore; + import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -20,4 +22,15 @@ public class BudgetAmounts { public void setMonthBudget(final int monthNum, final BigDecimal amount) { monthBudgets.put(Integer.valueOf(monthNum), amount); } + + @JsonIgnore + public Object[] getInsertObjects() { + final Object[] objects = new Object[14]; + objects[0] = Integer.valueOf(categoryId); + objects[1] = yearBudget; + for (int i = 0; i < 12; i++) { + objects[2 + i] = monthBudgets.get(Integer.valueOf(i)); + } + return objects; + } } diff --git a/src/main/java/com/stephenschafer/budget/CatRegex.java b/src/main/java/com/stephenschafer/budget/CatRegex.java index 98aa0b7..cd20fbb 100644 --- a/src/main/java/com/stephenschafer/budget/CatRegex.java +++ b/src/main/java/com/stephenschafer/budget/CatRegex.java @@ -16,7 +16,7 @@ public class CatRegex { this.id = id; this.pattern = pattern; this.category = category; - this.source = source; + this.source = source != null && source.length() == 0 ? null : source; this.priority = priority; this.extraDescription = extraDescription; this.year = year; diff --git a/src/main/java/com/stephenschafer/budget/ReportCategory.java b/src/main/java/com/stephenschafer/budget/ReportCategory.java index 5f91022..fc94919 100644 --- a/src/main/java/com/stephenschafer/budget/ReportCategory.java +++ b/src/main/java/com/stephenschafer/budget/ReportCategory.java @@ -13,11 +13,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.Setter; -import lombok.ToString; @Getter @Setter -@ToString public class ReportCategory { private final Integer id; private final Integer parentId; @@ -229,4 +227,28 @@ public class ReportCategory { public void setIncluded(final boolean include) { this.included = include; } + + @Override + public String toString() { + return toString(0); + } + + private String toString(final int level) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < level; i++) { + sb.append(" "); + } + sb.append("category: "); + sb.append(this.id); + sb.append(" "); + sb.append(this.name); + sb.append(" "); + sb.append(this.parentId); + for (final Integer childId : this.children.keySet()) { + final ReportCategory childCategory = this.children.get(childId); + sb.append("\n"); + sb.append(childCategory.toString(level + 1)); + } + return sb.toString(); + } } diff --git a/src/main/java/com/stephenschafer/budget/ReportController.java b/src/main/java/com/stephenschafer/budget/ReportController.java index f6f8e48..082fe2f 100644 --- a/src/main/java/com/stephenschafer/budget/ReportController.java +++ b/src/main/java/com/stephenschafer/budget/ReportController.java @@ -45,14 +45,47 @@ public class ReportController { @PutMapping("/budget") @ResponseBody - public ApiResponse putBudget(@RequestBody final Map reports, - final HttpServletRequest request) { + public ApiResponse putBudget( + @RequestBody final Map>> yearMap, + final HttpServletRequest request) throws IOException { if (!userService.isAuthorized(request)) { return new ApiResponse<>(HttpStatus.UNAUTHORIZED.value(), "You are not authorized to do this", null); } - categoryDao.update(report); - return new ApiResponse<>(HttpStatus.OK.value(), "Category updated successfully", report); + for (final String year : yearMap.keySet()) { + final String dropBudgetTableSql = Util.getResourceAsString("dropBudgetAmountsTable.sql") // + .replace("${databaseName}", "budget_" + year); + jdbcTemplate.update(dropBudgetTableSql); + final String createBudgetTableSql = Util.getResourceAsString( + "createBudgetAmountsTable.sql") // + .replace("${ifNotExists}", "") // + .replace("${databaseName}", "budget_" + year); + jdbcTemplate.update(createBudgetTableSql); + final Map> categoryMap = yearMap.get(year); + for (final Integer categoryId : categoryMap.keySet()) { + final Map monthMap = categoryMap.get(categoryId); + final BigDecimal yearBudget = monthMap.get(Integer.valueOf(-1)); + final BigDecimal monthBudgets[] = new BigDecimal[12]; + for (int i = 0; i < 12; i++) { + monthBudgets[i] = monthMap.get(Integer.valueOf(i)); + } + saveBudgets(year, categoryId, yearBudget, monthBudgets); + } + } + return new ApiResponse<>(HttpStatus.OK.value(), "Category updated successfully", 0); + } + + private void saveBudgets(final String year, final Integer categoryId, + final BigDecimal yearBudget, final BigDecimal[] monthBudgets) throws IOException { + final String insertBudgetTableSql = Util.getResourceAsString("insertBudgetAmounts.sql") // + .replace("${databaseName}", "budget_" + year); + final Object[] insertObjects = new Object[14]; + insertObjects[0] = categoryId; + insertObjects[1] = yearBudget; + for (int i = 0; i < 12; i++) { + insertObjects[i + 2] = monthBudgets[i]; + } + jdbcTemplate.update(insertBudgetTableSql, insertObjects); } @GetMapping("/report") @@ -134,9 +167,12 @@ public class ReportController { final var categoryMap = loadCategories(year, includeIncome, includePayments, includeInvestments, includeExpenses, monthCount); final String createBudgetTableSql = Util.getResourceAsString( - "createIfNotExistBudgetAmount.sql"); + "createBudgetAmountsTable.sql") // + .replace("${ifNotExists}", "if not exists ") // + .replace("${databaseName}", "budget_" + year); jdbcTemplate.update(createBudgetTableSql); - final String getBudgetAmountsSql = Util.getResourceAsString("getBudgetAmounts.sql"); + final String getBudgetAmountsSql = Util.getResourceAsString("getBudgetAmounts.sql") // + .replace("${databaseName}", "budget_" + year); jdbcTemplate.query(getBudgetAmountsSql, new Object[] {}, new int[] {}, (RowCallbackHandler) rs -> { var i = 0; @@ -189,6 +225,7 @@ public class ReportController { final Report report = new Report(year, monthCount, rootCategory); response.put(year, report); } + log.debug("response = " + response); return new ApiResponse<>(HttpStatus.OK.value(), "Report fetched successfully", response); } diff --git a/src/main/resources/createIfNotExistBudgetAmount.sql b/src/main/resources/createBudgetAmountsTable.sql similarity index 86% rename from src/main/resources/createIfNotExistBudgetAmount.sql rename to src/main/resources/createBudgetAmountsTable.sql index 4f347b3..32d7196 100644 --- a/src/main/resources/createIfNotExistBudgetAmount.sql +++ b/src/main/resources/createBudgetAmountsTable.sql @@ -1,4 +1,4 @@ -create table if not exists ${databaseName}.budget_amount ( +create table ${ifNotExists}${databaseName}.budget_amount ( category_id int not null primary key, year_amount decimal(10,2), jan_amount decimal(10,2), diff --git a/src/main/resources/dropBudgetAmountsTable.sql b/src/main/resources/dropBudgetAmountsTable.sql new file mode 100644 index 0000000..ed8258f --- /dev/null +++ b/src/main/resources/dropBudgetAmountsTable.sql @@ -0,0 +1 @@ +drop table if exists ${databaseName}.budget_amount \ No newline at end of file diff --git a/src/main/java/com/stephenschafer/budget/getBudgetAmounts.sql b/src/main/resources/getBudgetAmounts.sql similarity index 100% rename from src/main/java/com/stephenschafer/budget/getBudgetAmounts.sql rename to src/main/resources/getBudgetAmounts.sql diff --git a/src/main/resources/insertBudgetAmounts.sql b/src/main/resources/insertBudgetAmounts.sql new file mode 100644 index 0000000..b7ab966 --- /dev/null +++ b/src/main/resources/insertBudgetAmounts.sql @@ -0,0 +1,4 @@ +insert into ${databaseName}.budget_amount +(category_id, year_amount, jan_amount, feb_amount, mar_amount, apr_amount, may_amount, + jun_amount, jul_amount, aug_amount, sep_amount, oct_amount, nov_amount, dec_amount) +values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)