diff --git a/src/main/java/de/deadlocker8/budgetmaster/filter/FilterConfiguration.java b/src/main/java/de/deadlocker8/budgetmaster/filter/FilterConfiguration.java index 2868fe82f954c14e2266378866413dc9264f6fe1..6a11a43429e00571c8e80600cc7d1a78317727a8 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/filter/FilterConfiguration.java +++ b/src/main/java/de/deadlocker8/budgetmaster/filter/FilterConfiguration.java @@ -7,22 +7,24 @@ public class FilterConfiguration { private boolean includeIncome; private boolean includeExpenditure; + private boolean includeTransfer; private boolean includeNotRepeating; private boolean includeRepeating; private List<FilterObject> filterCategories; private List<FilterObject> filterTags; private String name; - public static final FilterConfiguration DEFAULT = new FilterConfiguration(true, true, true, true, null, null, ""); + public static final FilterConfiguration DEFAULT = new FilterConfiguration(true, true, true, true, true, null, null, ""); public FilterConfiguration() { } - public FilterConfiguration(boolean includeIncome, boolean includeExpenditure, boolean includeNotRepeating, boolean includeRepeating, List<FilterObject> filterCategories, List<FilterObject> filterTags, String name) + public FilterConfiguration(boolean includeIncome, boolean includeExpenditure, boolean includeTransfer, boolean includeNotRepeating, boolean includeRepeating, List<FilterObject> filterCategories, List<FilterObject> filterTags, String name) { this.includeIncome = includeIncome; this.includeExpenditure = includeExpenditure; + this.includeTransfer = includeTransfer; this.includeNotRepeating = includeNotRepeating; this.includeRepeating = includeRepeating; this.filterCategories = filterCategories; @@ -50,6 +52,16 @@ public class FilterConfiguration this.includeExpenditure = includeExpenditure; } + public boolean isIncludeTransfer() + { + return includeTransfer; + } + + public void setIncludeTransfer(boolean includeTransfer) + { + this.includeTransfer = includeTransfer; + } + public boolean isIncludeNotRepeating() { return includeNotRepeating; @@ -156,6 +168,11 @@ public class FilterConfiguration return true; } + if(defaultConfiguration.isIncludeTransfer() != isIncludeTransfer()) + { + return true; + } + if(defaultConfiguration.isIncludeNotRepeating() != isIncludeNotRepeating()) { return true; @@ -197,6 +214,7 @@ public class FilterConfiguration "includeIncome=" + includeIncome + ", includeExpenditure=" + includeExpenditure + ", includeNotRepeating=" + includeNotRepeating + + ", includeTransfer=" + includeTransfer + ", includeRepeating=" + includeRepeating + ", filterCategories=" + filterCategories + ", filterTags=" + filterTags + diff --git a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java index 31d3e4234fbb28cfa3977757a6db785cfb7133bd..ee5089e75a8807c3563d00b2996c572cefcfac2b 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionService.java @@ -2,11 +2,11 @@ package de.deadlocker8.budgetmaster.transactions; import de.deadlocker8.budgetmaster.accounts.Account; import de.deadlocker8.budgetmaster.accounts.AccountType; +import de.deadlocker8.budgetmaster.categories.CategoryRepository; import de.deadlocker8.budgetmaster.categories.CategoryType; -import de.deadlocker8.budgetmaster.services.Resetable; import de.deadlocker8.budgetmaster.filter.FilterConfiguration; -import de.deadlocker8.budgetmaster.categories.CategoryRepository; import de.deadlocker8.budgetmaster.repeating.RepeatingOptionRepository; +import de.deadlocker8.budgetmaster.services.Resetable; import de.deadlocker8.budgetmaster.utils.Strings; import de.thecodelabs.utils.util.Localization; import org.joda.time.DateTime; @@ -95,11 +95,11 @@ public class TransactionService implements Resetable if(account.getType().equals(AccountType.ALL)) { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, endDate, null, filterConfiguration.isIncludeIncome(), filterConfiguration.isIncludeExpenditure(), filterConfiguration.isIncludeRepeatingAndNotRepeating(), filterConfiguration.getIncludedCategoryIDs(), filterConfiguration.getIncludedTagIDs(), filterConfiguration.getName()); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, endDate, null, filterConfiguration.isIncludeIncome(), filterConfiguration.isIncludeExpenditure(), filterConfiguration.isIncludeTransfer(), filterConfiguration.isIncludeRepeatingAndNotRepeating(), filterConfiguration.getIncludedCategoryIDs(), filterConfiguration.getIncludedTagIDs(), filterConfiguration.getName()); return transactionRepository.findAll(spec); } - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, endDate, account, filterConfiguration.isIncludeIncome(), filterConfiguration.isIncludeExpenditure(), filterConfiguration.isIncludeRepeatingAndNotRepeating(), filterConfiguration.getIncludedCategoryIDs(), filterConfiguration.getIncludedTagIDs(), filterConfiguration.getName()); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, endDate, account, filterConfiguration.isIncludeIncome(), filterConfiguration.isIncludeExpenditure(), filterConfiguration.isIncludeTransfer(), filterConfiguration.isIncludeRepeatingAndNotRepeating(), filterConfiguration.getIncludedCategoryIDs(), filterConfiguration.getIncludedTagIDs(), filterConfiguration.getName()); return transactionRepository.findAll(spec); } diff --git a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java index 44828251b13abb57070be7278defb970c7113da5..699c35e65c53c49bab592c2655f269a7032512b7 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java +++ b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java @@ -15,7 +15,7 @@ public class TransactionSpecifications { public static Specification<Transaction> withDynamicQuery(final DateTime startDate, final DateTime endDate, Account account, - final boolean isIncome, boolean isExpenditure, + final boolean isIncome, boolean isExpenditure, boolean isTransfer, final Boolean isRepeating, final List<Integer> categoryIDs, final List<Integer> tagIDs, @@ -52,6 +52,18 @@ public class TransactionSpecifications } } + if(isTransfer) + { + if(!isIncome && !isExpenditure) + { + predicates.add(builder.and(builder.isNotNull(transaction.get(Transaction_.transferAccount)))); + } + } + else + { + predicates.add(builder.and(builder.isNull(transaction.get(Transaction_.transferAccount)))); + } + if(categoryIDs != null) { predicates.add(builder.and(transaction.get(Transaction_.category).get("ID").in(categoryIDs))); diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties index 3cb168077fce1f16804c6d98d74738ee3cb93928..71269633e0ed8875861bb84a18e4479ea67386dc 100644 --- a/src/main/resources/languages/_de.properties +++ b/src/main/resources/languages/_de.properties @@ -257,6 +257,7 @@ filter.reset=Zur filter.type=Art filter.type.income=Einnahme filter.type.expenditure=Ausgabe +filter.type.transfer=Umbuchung filter.repeating=Wiederholung filter.repeating.false=nicht wiederholend filter.repeating.true=wiederholend diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties index cd6e3064b66e94375dfd9f8c8e2645483681209b..69c38477c861a2c471d0308bd8d22fe65db71dd3 100644 --- a/src/main/resources/languages/_en.properties +++ b/src/main/resources/languages/_en.properties @@ -258,6 +258,7 @@ filter.reset=Reset filter.type=Type filter.type.income=Income filter.type.expenditure=Expenditure +filter.type.transfer=Transfer filter.repeating=Repeating filter.repeating.false=not repeating filter.repeating.true=repeating diff --git a/src/main/resources/templates/filter/filterMacros.ftl b/src/main/resources/templates/filter/filterMacros.ftl index 64540d6559b32c07faf9371525ce5121c2b5dd32..0afbff9906773173fdd53e9c79120a165df41969 100644 --- a/src/main/resources/templates/filter/filterMacros.ftl +++ b/src/main/resources/templates/filter/filterMacros.ftl @@ -64,18 +64,24 @@ </div> <div class="collapsible-body"> <div class="row no-margin"> - <div class="col s6 m6 l6"> + <div class="col s12 m4 l4"> <label> <input type="checkbox" name="includeIncome" <#if filterConfiguration.isIncludeIncome()>checked="checked"</#if>> <span class="text-color">${locale.getString('filter.type.income')}</span> </label> </div> - <div class="col s6 m6 l6"> + <div class="col s12 m4 l4"> <label> <input type="checkbox" name="includeExpenditure" <#if filterConfiguration.isIncludeExpenditure()>checked="checked"</#if>> <span class="text-color">${locale.getString('filter.type.expenditure')}</span> </label> </div> + <div class="col s12 m4 l4"> + <label> + <input type="checkbox" name="includeTransfer" <#if filterConfiguration.isIncludeTransfer()>checked="checked"</#if>> + <span class="text-color">${locale.getString('filter.type.transfer')}</span> + </label> + </div> </div> </div> </li> diff --git a/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java b/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java index 9769bb21a35247696ef0744b64884d63b1f2ad36..a06e6d143d302097450dd86e5095e53cd26b4634 100644 --- a/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java +++ b/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java @@ -40,6 +40,7 @@ public class TransactionRepositoryTest private Transaction transaction1; private Transaction transaction2; private Transaction repeatingTransaction; + private Transaction transferTransaction; @Autowired private CategoryRepository categoryRepository; @@ -50,6 +51,7 @@ public class TransactionRepositoryTest @Autowired private AccountRepository accountRepository; private Account account; + private Account account2; @Autowired private TagRepository tagRepository; @@ -68,6 +70,7 @@ public class TransactionRepositoryTest public void init() { account = accountRepository.save(new Account("TestAccount", AccountType.CUSTOM)); + account2 = accountRepository.save(new Account("TestAccount2", AccountType.CUSTOM)); categoryUnused = categoryRepository.save(new Category("CategoryUnused", "#00ff00", CategoryType.CUSTOM)); category1 = categoryRepository.save(new Category("Category1", "#ff0000", CategoryType.CUSTOM)); @@ -96,7 +99,6 @@ public class TransactionRepositoryTest transaction2.setAccount(account); transaction2 = transactionRepository.save(transaction2); - DateTime repeatingTransactionDate = DateTime.parse("2018-03-13", DateTimeFormat.forPattern("yyyy-MM-dd")); repeatingOption = new RepeatingOption(); repeatingOption.setModifier(new RepeatingModifierDays(10)); @@ -116,72 +118,111 @@ public class TransactionRepositoryTest tags2.add(tag2); repeatingTransaction.setTags(tags2); repeatingTransaction = transactionRepository.save(repeatingTransaction); + + transferTransaction = new Transaction(); + transferTransaction.setName("TransferTransaction"); + transferTransaction.setAmount(-500); + transferTransaction.setDate(new DateTime(2018, 10, 3, 12, 0, 0, 0)); + transferTransaction.setCategory(category2); + transferTransaction.setAccount(account); + transferTransaction.setTransferAccount(account2); + transferTransaction = transactionRepository.save(transferTransaction); + } + + @Test + public void getIncomesAndExpendituresAndTransfers() + { + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, null, null, null); + + List<Transaction> results = transactionRepository.findAll(spec); + assertTrue(results.contains(transaction1)); + assertTrue(results.contains(transaction2)); + assertTrue(results.contains(repeatingTransaction)); + assertTrue(results.contains(transferTransaction)); } @Test public void getIncomesAndExpenditures() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, false, null, null, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertTrue(results.contains(transaction1)); assertTrue(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test public void getIncomes() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, false, null, null, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, false, false, null, null, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertTrue(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertFalse(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test public void getExpenditures() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, true, null, null, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, true, false, null, null, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertFalse(results.contains(transaction1)); assertTrue(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); + } + + @Test + public void getTransfers() + { + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, false, true, null, null, null, null); + + List<Transaction> results = transactionRepository.findAll(spec); + assertFalse(results.contains(transaction1)); + assertFalse(results.contains(transaction2)); + assertFalse(results.contains(repeatingTransaction)); + assertTrue(results.contains(transferTransaction)); } @Test public void incomesAndExpendituresFalse() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, false, null, null, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, false, false, null, null, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertTrue(results.contains(transaction1)); assertTrue(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test public void getRepeating() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, false, true, null, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertFalse(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test public void noRepeating() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, false, null, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, false, null, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertTrue(results.contains(transaction1)); assertTrue(results.contains(transaction2)); assertFalse(results.contains(repeatingTransaction)); + assertTrue(results.contains(transferTransaction)); } @Test @@ -189,12 +230,13 @@ public class TransactionRepositoryTest { List<Integer> categoryIDs = new ArrayList<>(); categoryIDs.add(categoryUnused.getID()); - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, categoryIDs, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, categoryIDs, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertFalse(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertFalse(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test @@ -202,34 +244,37 @@ public class TransactionRepositoryTest { List<Integer> categoryIDs = new ArrayList<>(); categoryIDs.add(category1.getID()); - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, categoryIDs, null, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, categoryIDs, null, null); List<Transaction> results = transactionRepository.findAll(spec); assertTrue(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test public void getByFullName() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, null, "Repeating"); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, null, null, "Repeating"); List<Transaction> results = transactionRepository.findAll(spec); assertFalse(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test public void getByPartialName() { - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, null, "tin"); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, null, null, "tin"); List<Transaction> results = transactionRepository.findAll(spec); assertFalse(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test @@ -238,12 +283,13 @@ public class TransactionRepositoryTest List<Integer> tagIDs = new ArrayList<>(); tagIDs.add(tag1.getID()); - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, tagIDs, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, null, tagIDs, null); List<Transaction> results = transactionRepository.findAll(spec); assertTrue(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertFalse(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test @@ -253,12 +299,13 @@ public class TransactionRepositoryTest tagIDs.add(tag1.getID()); tagIDs.add(tag2.getID()); - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, tagIDs, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true,null, null, tagIDs, null); List<Transaction> results = transactionRepository.findAll(spec); assertTrue(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @@ -268,12 +315,13 @@ public class TransactionRepositoryTest List<Integer> tagIDs = new ArrayList<>(); tagIDs.add(tagUnused.getID()); - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, tagIDs, null); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, true, null, null, tagIDs, null); List<Transaction> results = transactionRepository.findAll(spec); assertFalse(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertFalse(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } @Test @@ -286,11 +334,12 @@ public class TransactionRepositoryTest tagIDs.add(tag1.getID()); tagIDs.add(tag2.getID()); - Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, true, true, categoryIDs, tagIDs, "Repeating"); + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, true, true, true, categoryIDs, tagIDs, "Repeating"); List<Transaction> results = transactionRepository.findAll(spec); assertFalse(results.contains(transaction1)); assertFalse(results.contains(transaction2)); assertTrue(results.contains(repeatingTransaction)); + assertFalse(results.contains(transferTransaction)); } } \ No newline at end of file