Finish implemention of budgets.

This commit is contained in:
Steve Schafer 2026-01-19 11:04:50 -07:00
parent 09c3d932c2
commit 2ff60ad985
8 changed files with 87 additions and 10 deletions

View file

@ -4,6 +4,8 @@ import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@ -20,4 +22,15 @@ public class BudgetAmounts {
public void setMonthBudget(final int monthNum, final BigDecimal amount) { public void setMonthBudget(final int monthNum, final BigDecimal amount) {
monthBudgets.put(Integer.valueOf(monthNum), 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;
}
} }

View file

@ -16,7 +16,7 @@ public class CatRegex {
this.id = id; this.id = id;
this.pattern = pattern; this.pattern = pattern;
this.category = category; this.category = category;
this.source = source; this.source = source != null && source.length() == 0 ? null : source;
this.priority = priority; this.priority = priority;
this.extraDescription = extraDescription; this.extraDescription = extraDescription;
this.year = year; this.year = year;

View file

@ -13,11 +13,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@ToString
public class ReportCategory { public class ReportCategory {
private final Integer id; private final Integer id;
private final Integer parentId; private final Integer parentId;
@ -229,4 +227,28 @@ public class ReportCategory {
public void setIncluded(final boolean include) { public void setIncluded(final boolean include) {
this.included = 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();
}
} }

View file

@ -45,14 +45,47 @@ public class ReportController {
@PutMapping("/budget") @PutMapping("/budget")
@ResponseBody @ResponseBody
public ApiResponse<Report> putBudget(@RequestBody final Map<String, Report> reports, public ApiResponse<Integer> putBudget(
final HttpServletRequest request) { @RequestBody final Map<String, Map<Integer, Map<Integer, BigDecimal>>> yearMap,
final HttpServletRequest request) throws IOException {
if (!userService.isAuthorized(request)) { if (!userService.isAuthorized(request)) {
return new ApiResponse<>(HttpStatus.UNAUTHORIZED.value(), return new ApiResponse<>(HttpStatus.UNAUTHORIZED.value(),
"You are not authorized to do this", null); "You are not authorized to do this", null);
} }
categoryDao.update(report); for (final String year : yearMap.keySet()) {
return new ApiResponse<>(HttpStatus.OK.value(), "Category updated successfully", report); 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<Integer, Map<Integer, BigDecimal>> categoryMap = yearMap.get(year);
for (final Integer categoryId : categoryMap.keySet()) {
final Map<Integer, BigDecimal> 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") @GetMapping("/report")
@ -134,9 +167,12 @@ public class ReportController {
final var categoryMap = loadCategories(year, includeIncome, includePayments, final var categoryMap = loadCategories(year, includeIncome, includePayments,
includeInvestments, includeExpenses, monthCount); includeInvestments, includeExpenses, monthCount);
final String createBudgetTableSql = Util.getResourceAsString( final String createBudgetTableSql = Util.getResourceAsString(
"createIfNotExistBudgetAmount.sql"); "createBudgetAmountsTable.sql") //
.replace("${ifNotExists}", "if not exists ") //
.replace("${databaseName}", "budget_" + year);
jdbcTemplate.update(createBudgetTableSql); 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[] {}, jdbcTemplate.query(getBudgetAmountsSql, new Object[] {}, new int[] {},
(RowCallbackHandler) rs -> { (RowCallbackHandler) rs -> {
var i = 0; var i = 0;
@ -189,6 +225,7 @@ public class ReportController {
final Report report = new Report(year, monthCount, rootCategory); final Report report = new Report(year, monthCount, rootCategory);
response.put(year, report); response.put(year, report);
} }
log.debug("response = " + response);
return new ApiResponse<>(HttpStatus.OK.value(), "Report fetched successfully", response); return new ApiResponse<>(HttpStatus.OK.value(), "Report fetched successfully", response);
} }

View file

@ -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, category_id int not null primary key,
year_amount decimal(10,2), year_amount decimal(10,2),
jan_amount decimal(10,2), jan_amount decimal(10,2),

View file

@ -0,0 +1 @@
drop table if exists ${databaseName}.budget_amount

View file

@ -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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)