Implement category archiving
Archiving is a step below deleting. It represents categories that may no longer be relevant to your current budget, but are still useful to keep around for historical reasons.
This commit is contained in:
parent
fd517cb2f8
commit
05f203a56f
6 changed files with 41 additions and 15 deletions
|
@ -16,6 +16,8 @@ public class Category implements Comparable<Category> {
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private Budget budget;
|
private Budget budget;
|
||||||
private boolean expense;
|
private boolean expense;
|
||||||
|
@Column(nullable = false, columnDefinition = "boolean default false")
|
||||||
|
private boolean archived;
|
||||||
|
|
||||||
public Category() {
|
public Category() {
|
||||||
this(null, null, 0L, null, true);
|
this(null, null, 0L, null, true);
|
||||||
|
@ -83,4 +85,12 @@ public class Category implements Comparable<Category> {
|
||||||
public void setExpense(boolean expense) {
|
public void setExpense(boolean expense) {
|
||||||
this.expense = expense;
|
this.expense = expense;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isArchived() {
|
||||||
|
return archived;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArchived(boolean archived) {
|
||||||
|
this.archived = archived;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ import com.wbrawner.budgetserver.transaction.TransactionRepository;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import io.swagger.annotations.Authorization;
|
import io.swagger.annotations.Authorization;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Example;
|
||||||
|
import org.springframework.data.domain.ExampleMatcher;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
@ -44,6 +47,7 @@ class CategoryController {
|
||||||
ResponseEntity<List<CategoryResponse>> getCategories(
|
ResponseEntity<List<CategoryResponse>> getCategories(
|
||||||
@RequestParam(name = "budgetIds", required = false) List<Long> budgetIds,
|
@RequestParam(name = "budgetIds", required = false) List<Long> budgetIds,
|
||||||
@RequestParam(name = "isExpense", required = false) Boolean isExpense,
|
@RequestParam(name = "isExpense", required = false) Boolean isExpense,
|
||||||
|
@RequestParam(name = "includeArchived", required = false) Boolean includeArchived,
|
||||||
@RequestParam(name = "count", required = false) Integer count,
|
@RequestParam(name = "count", required = false) Integer count,
|
||||||
@RequestParam(name = "page", required = false) Integer page,
|
@RequestParam(name = "page", required = false) Integer page,
|
||||||
@RequestParam(name = "false", required = false) String sortBy,
|
@RequestParam(name = "false", required = false) String sortBy,
|
||||||
|
@ -69,13 +73,8 @@ class CategoryController {
|
||||||
sortOrder != null ? sortOrder : Sort.Direction.ASC,
|
sortOrder != null ? sortOrder : Sort.Direction.ASC,
|
||||||
sortBy != null ? sortBy : "title"
|
sortBy != null ? sortBy : "title"
|
||||||
);
|
);
|
||||||
List<Category> categories;
|
Boolean archived = includeArchived == null || includeArchived == false ? false : null;
|
||||||
if (isExpense == null) {
|
List<Category> categories = categoryRepository.findAllByBudgetIn(budgets, isExpense, archived, pageRequest);
|
||||||
categories = categoryRepository.findAllByBudgetIn(budgets, pageRequest);
|
|
||||||
} else {
|
|
||||||
categories = categoryRepository.findAllByBudgetInAndExpense(budgets, isExpense, pageRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResponseEntity.ok(
|
return ResponseEntity.ok(
|
||||||
categories.stream()
|
categories.stream()
|
||||||
.map(CategoryResponse::new)
|
.map(CategoryResponse::new)
|
||||||
|
@ -153,6 +152,9 @@ class CategoryController {
|
||||||
if (request.getExpense() != null) {
|
if (request.getExpense() != null) {
|
||||||
category.setExpense(request.getExpense());
|
category.setExpense(request.getExpense());
|
||||||
}
|
}
|
||||||
|
if (request.getArchived() != null) {
|
||||||
|
category.setArchived(request.getArchived());
|
||||||
|
}
|
||||||
return ResponseEntity.ok(new CategoryResponse(categoryRepository.save(category)));
|
return ResponseEntity.ok(new CategoryResponse(categoryRepository.save(category)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package com.wbrawner.budgetserver.category;
|
package com.wbrawner.budgetserver.category;
|
||||||
|
|
||||||
import com.wbrawner.budgetserver.budget.Budget;
|
import com.wbrawner.budgetserver.budget.Budget;
|
||||||
|
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -10,12 +12,11 @@ import java.util.Optional;
|
||||||
public interface CategoryRepository extends PagingAndSortingRepository<Category, Long> {
|
public interface CategoryRepository extends PagingAndSortingRepository<Category, Long> {
|
||||||
List<Category> findAllByBudget(Budget budget, Pageable pageable);
|
List<Category> findAllByBudget(Budget budget, Pageable pageable);
|
||||||
|
|
||||||
List<Category> findAllByBudgetIn(List<Budget> budgets, Pageable pageable);
|
@Query("SELECT c FROM Category c where c.budget IN (:budgets) AND (:expense IS NULL OR c.expense = :expense) AND (:archived IS NULL OR c.archived = :archived)")
|
||||||
|
List<Category> findAllByBudgetIn(List<Budget> budgets, Boolean expense, Boolean archived, Pageable pageable);
|
||||||
|
|
||||||
Optional<Category> findByBudgetInAndId(List<Budget> budgets, Long id);
|
Optional<Category> findByBudgetInAndId(List<Budget> budgets, Long id);
|
||||||
|
|
||||||
List<Category> findAllByBudgetInAndExpense(List<Budget> budgets, Boolean isExpense, Pageable pageable);
|
|
||||||
|
|
||||||
Optional<Category> findByBudgetAndId(Budget budget, Long id);
|
Optional<Category> findByBudgetAndId(Budget budget, Long id);
|
||||||
|
|
||||||
List<Category> findAllByBudgetInAndIdIn(List<Budget> budgets, List<Long> ids, Pageable pageable);
|
List<Category> findAllByBudgetInAndIdIn(List<Budget> budgets, List<Long> ids, Pageable pageable);
|
||||||
|
|
|
@ -9,6 +9,7 @@ public class CategoryResponse {
|
||||||
private final long amount;
|
private final long amount;
|
||||||
private final long budgetId;
|
private final long budgetId;
|
||||||
private final boolean expense;
|
private final boolean expense;
|
||||||
|
private final boolean archived;
|
||||||
|
|
||||||
public CategoryResponse(Category category) {
|
public CategoryResponse(Category category) {
|
||||||
this(
|
this(
|
||||||
|
@ -17,17 +18,19 @@ public class CategoryResponse {
|
||||||
category.getDescription(),
|
category.getDescription(),
|
||||||
category.getAmount(),
|
category.getAmount(),
|
||||||
Objects.requireNonNull(category.getBudget()).getId(),
|
Objects.requireNonNull(category.getBudget()).getId(),
|
||||||
category.isExpense()
|
category.isExpense(),
|
||||||
|
category.isArchived()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CategoryResponse(long id, String title, String description, long amount, long budgetId, boolean expense) {
|
public CategoryResponse(long id, String title, String description, long amount, long budgetId, boolean expense, boolean archived) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.budgetId = budgetId;
|
this.budgetId = budgetId;
|
||||||
this.expense = expense;
|
this.expense = expense;
|
||||||
|
this.archived = archived;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getId() {
|
public long getId() {
|
||||||
|
@ -53,4 +56,8 @@ public class CategoryResponse {
|
||||||
public boolean isExpense() {
|
public boolean isExpense() {
|
||||||
return expense;
|
return expense;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isArchived() {
|
||||||
|
return archived;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,18 @@ public class UpdateCategoryRequest {
|
||||||
private final String description;
|
private final String description;
|
||||||
private final Long amount;
|
private final Long amount;
|
||||||
private final Boolean expense;
|
private final Boolean expense;
|
||||||
|
private final Boolean archived;
|
||||||
|
|
||||||
public UpdateCategoryRequest() {
|
public UpdateCategoryRequest() {
|
||||||
this(null, null, null, null);
|
this(null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UpdateCategoryRequest(String title, String description, Long amount, Boolean expense) {
|
public UpdateCategoryRequest(String title, String description, Long amount, Boolean expense, Boolean archived) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.expense = expense;
|
this.expense = expense;
|
||||||
|
this.archived = archived;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
|
@ -32,4 +34,8 @@ public class UpdateCategoryRequest {
|
||||||
public Boolean getExpense() {
|
public Boolean getExpense() {
|
||||||
return expense;
|
return expense;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getArchived() {
|
||||||
|
return archived;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class TransactionController {
|
||||||
if (categoryIds != null && !categoryIds.isEmpty()) {
|
if (categoryIds != null && !categoryIds.isEmpty()) {
|
||||||
categories = categoryRepository.findAllByBudgetInAndIdIn(budgets, categoryIds, null);
|
categories = categoryRepository.findAllByBudgetInAndIdIn(budgets, categoryIds, null);
|
||||||
} else {
|
} else {
|
||||||
categories = categoryRepository.findAllByBudgetIn(budgets, null);
|
categories = categoryRepository.findAllByBudgetIn(budgets, null, null, null);
|
||||||
}
|
}
|
||||||
var pageRequest = PageRequest.of(
|
var pageRequest = PageRequest.of(
|
||||||
Math.min(0, page != null ? page - 1 : 0),
|
Math.min(0, page != null ? page - 1 : 0),
|
||||||
|
|
Loading…
Reference in a new issue