From 8490c3d2ac1468245727c422e5bd2122820e2317 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Sun, 3 Mar 2019 18:03:10 +0100 Subject: [PATCH] Fixed #293 - fixed filtering by tags --- .../deadlocker8/budgetmaster/tags/Tag_.java | 13 +++++ .../TransactionSpecifications.java | 16 ++++- .../transactions/Transaction_.java | 2 +- src/main/resources/static/js/transactions.js | 1 - .../TransactionRepositoryTest.java | 58 ++++++++++++++++++- 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/main/java/de/deadlocker8/budgetmaster/tags/Tag_.java diff --git a/src/main/java/de/deadlocker8/budgetmaster/tags/Tag_.java b/src/main/java/de/deadlocker8/budgetmaster/tags/Tag_.java new file mode 100644 index 000000000..f93592e78 --- /dev/null +++ b/src/main/java/de/deadlocker8/budgetmaster/tags/Tag_.java @@ -0,0 +1,13 @@ +package de.deadlocker8.budgetmaster.tags; + +import de.deadlocker8.budgetmaster.transactions.Transaction; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(Tag.class) +public class Tag_ +{ + public static volatile SingularAttribute<Tag, Integer> ID; + public static volatile SingularAttribute<Tag, Integer> amount; +} diff --git a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java index 2a3999bb5..44828251b 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java +++ b/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionSpecifications.java @@ -1,11 +1,14 @@ package de.deadlocker8.budgetmaster.transactions; import de.deadlocker8.budgetmaster.accounts.Account; +import de.deadlocker8.budgetmaster.tags.Tag; +import de.deadlocker8.budgetmaster.tags.Tag_; import org.joda.time.DateTime; import org.springframework.data.jpa.domain.Specification; -import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.*; import java.util.ArrayList; +import java.util.Collection; import java.util.List; public class TransactionSpecifications @@ -56,12 +59,19 @@ public class TransactionSpecifications if(tagIDs != null) { -// predicates.add(builder.and(transaction.get(Transaction_.tags).in(tagIDs))); + Join<Transaction, Tag> join = transaction.join(Transaction_.tags); + Predicate actorIdPredicate = builder.disjunction(); + for(Integer tagID : tagIDs) + { + actorIdPredicate.getExpressions().add(builder.equal(join.get(Tag_.ID), tagID)); + } + + predicates.add(actorIdPredicate); } if(name != null && name.length() > 0) { - predicates.add(builder.and(builder.like(builder.lower(transaction.get(Transaction_.name)), "%"+name.toLowerCase()+"%"))); + predicates.add(builder.and(builder.like(builder.lower(transaction.get(Transaction_.name)), "%" + name.toLowerCase() + "%"))); } query.orderBy(builder.desc(transaction.get(Transaction_.date))); diff --git a/src/main/java/de/deadlocker8/budgetmaster/transactions/Transaction_.java b/src/main/java/de/deadlocker8/budgetmaster/transactions/Transaction_.java index 38498990a..68a4c071a 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/transactions/Transaction_.java +++ b/src/main/java/de/deadlocker8/budgetmaster/transactions/Transaction_.java @@ -21,6 +21,6 @@ public class Transaction_ public static volatile SingularAttribute<Transaction, Category> category; public static volatile SingularAttribute<Transaction, String> name; public static volatile SingularAttribute<Transaction, String> description; - public static volatile ListAttribute<Transaction, List<Tag>> tags; + public static volatile ListAttribute<Transaction, Tag> tags; public static volatile SingularAttribute<Transaction, RepeatingOption> repeatingOption; } diff --git a/src/main/resources/static/js/transactions.js b/src/main/resources/static/js/transactions.js index 6a4803f43..4b7b89f09 100644 --- a/src/main/resources/static/js/transactions.js +++ b/src/main/resources/static/js/transactions.js @@ -142,7 +142,6 @@ $( document ).ready(function() { // prevent form submit on enter (otherwise tag functionality will be hard to use) $(document).on("keypress", 'form', function (e) { - var code = e.keyCode || e.which; if((code === 13) && e.target.nodeName!=='TEXTAREA') { e.preventDefault(); diff --git a/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java b/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java index 0c702d24e..9769bb21a 100644 --- a/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java +++ b/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java @@ -54,6 +54,8 @@ public class TransactionRepositoryTest @Autowired private TagRepository tagRepository; private Tag tag1; + private Tag tag2; + private Tag tagUnused; @Autowired private RepeatingOptionRepository repeatingOptionRepository; @@ -72,6 +74,8 @@ public class TransactionRepositoryTest category2 = categoryRepository.save(new Category("Category2", "#ff0000", CategoryType.CUSTOM)); tag1 = tagRepository.save(new Tag("MyAwesomeTag")); + tag2 = tagRepository.save(new Tag("TagMaster_2")); + tagUnused = tagRepository.save(new Tag("Unused")); transaction1 = new Transaction(); transaction1.setName("Test"); @@ -79,6 +83,9 @@ public class TransactionRepositoryTest transaction1.setDate(new DateTime(2018, 10, 3, 12, 0, 0, 0)); transaction1.setCategory(category1); transaction1.setAccount(account); + ArrayList<Tag> tags = new ArrayList<>(); + tags.add(tag1); + transaction1.setTags(tags); transaction1 = transactionRepository.save(transaction1); transaction2 = new Transaction(); @@ -105,9 +112,9 @@ public class TransactionRepositoryTest repeatingTransaction.setDescription(""); repeatingTransaction.setAccount(account); repeatingTransaction.setRepeatingOption(repeatingOption); - ArrayList<Tag> tags = new ArrayList<>(); - tags.add(tag1); - repeatingTransaction.setTags(tags); + ArrayList<Tag> tags2 = new ArrayList<>(); + tags2.add(tag2); + repeatingTransaction.setTags(tags2); repeatingTransaction = transactionRepository.save(repeatingTransaction); } @@ -225,6 +232,50 @@ public class TransactionRepositoryTest assertTrue(results.contains(repeatingTransaction)); } + @Test + public void getByTags() + { + List<Integer> tagIDs = new ArrayList<>(); + tagIDs.add(tag1.getID()); + + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, tagIDs, null); + + List<Transaction> results = transactionRepository.findAll(spec); + assertTrue(results.contains(transaction1)); + assertFalse(results.contains(transaction2)); + assertFalse(results.contains(repeatingTransaction)); + } + + @Test + public void getByMultipleTags() + { + List<Integer> tagIDs = new ArrayList<>(); + tagIDs.add(tag1.getID()); + tagIDs.add(tag2.getID()); + + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, tagIDs, null); + + List<Transaction> results = transactionRepository.findAll(spec); + assertTrue(results.contains(transaction1)); + assertFalse(results.contains(transaction2)); + assertTrue(results.contains(repeatingTransaction)); + } + + + @Test + public void getByUnusedTags() + { + List<Integer> tagIDs = new ArrayList<>(); + tagIDs.add(tagUnused.getID()); + + Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, true, true, null, null, tagIDs, null); + + List<Transaction> results = transactionRepository.findAll(spec); + assertFalse(results.contains(transaction1)); + assertFalse(results.contains(transaction2)); + assertFalse(results.contains(repeatingTransaction)); + } + @Test public void getRepeatingExpenditureByCategoryAndTagsAndName() { @@ -233,6 +284,7 @@ public class TransactionRepositoryTest List<Integer> tagIDs = new ArrayList<>(); tagIDs.add(tag1.getID()); + tagIDs.add(tag2.getID()); Specification spec = TransactionSpecifications.withDynamicQuery(startDate, DateTime.now(), account, false, true, true, categoryIDs, tagIDs, "Repeating"); -- GitLab