Skip to content
Snippets Groups Projects
Commit 4216427f authored by Robert Goldmann's avatar Robert Goldmann
Browse files

#760 - order transaction name suggestions alphabetically or by frequency of use

parent 7dc349af
Branches
Tags
No related merge requests found
...@@ -35,7 +35,7 @@ public interface TransactionRepository extends JpaRepository<Transaction, Intege ...@@ -35,7 +35,7 @@ public interface TransactionRepository extends JpaRepository<Transaction, Intege
List<Transaction> findAllByTransferAccount(Account account); List<Transaction> findAllByTransferAccount(Account account);
List<Transaction> findAllByOrderByDateDesc(); List<Transaction> findAllByOrderByNameAsc();
Transaction findFirstByOrderByDate(); Transaction findFirstByOrderByDate();
......
...@@ -28,7 +28,9 @@ import java.text.MessageFormat; ...@@ -28,7 +28,9 @@ import java.text.MessageFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import static java.time.temporal.TemporalAdjusters.lastDayOfMonth; import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
...@@ -44,6 +46,7 @@ public class TransactionService implements Resettable ...@@ -44,6 +46,7 @@ public class TransactionService implements Resettable
private final RepeatingOptionRepository repeatingOptionRepository; private final RepeatingOptionRepository repeatingOptionRepository;
private final CategoryService categoryService; private final CategoryService categoryService;
private final TagService tagService; private final TagService tagService;
private final SettingsService settingsService;
@Autowired @Autowired
public TransactionService(TransactionRepository transactionRepository, RepeatingOptionRepository repeatingOptionRepository, CategoryService categoryService, TagService tagService, SettingsService settingsService) public TransactionService(TransactionRepository transactionRepository, RepeatingOptionRepository repeatingOptionRepository, CategoryService categoryService, TagService tagService, SettingsService settingsService)
...@@ -52,6 +55,7 @@ public class TransactionService implements Resettable ...@@ -52,6 +55,7 @@ public class TransactionService implements Resettable
this.repeatingOptionRepository = repeatingOptionRepository; this.repeatingOptionRepository = repeatingOptionRepository;
this.categoryService = categoryService; this.categoryService = categoryService;
this.tagService = tagService; this.tagService = tagService;
this.settingsService = settingsService;
} }
public TransactionRepository getRepository() public TransactionRepository getRepository()
...@@ -300,11 +304,24 @@ public class TransactionService implements Resettable ...@@ -300,11 +304,24 @@ public class TransactionService implements Resettable
public String getNameSuggestionsJson() public String getNameSuggestionsJson()
{ {
final List<Transaction> allByOrderByDateDesc = getRepository().findAllByOrderByDateDesc(); final List<Transaction> allOrderedByNameAsc = getRepository().findAllByOrderByNameAsc();
final List<String> nameSuggestions = allByOrderByDateDesc.stream() final List<String> names = allOrderedByNameAsc.stream()
.map(Transaction::getName) .map(Transaction::getName)
.distinct()
.toList(); .toList();
return GSON.toJson(nameSuggestions);
List<String> nameSuggestions = names;
if(!settingsService.getSettings().getOrderTransactionNameSuggestionsAlphabetically())
{
nameSuggestions = names.stream()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()))
.entrySet()
.stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed().thenComparing(Map.Entry.comparingByKey()))
.map(Map.Entry::getKey)
.toList();
}
return GSON.toJson(nameSuggestions.stream().distinct().toList());
} }
} }
...@@ -13,6 +13,7 @@ $(document).ready(function() ...@@ -13,6 +13,7 @@ $(document).ready(function()
let elements = document.querySelectorAll('#transaction-name'); let elements = document.querySelectorAll('#transaction-name');
let autoCompleteInstances = M.Autocomplete.init(elements, { let autoCompleteInstances = M.Autocomplete.init(elements, {
data: transactionNameSuggestions, data: transactionNameSuggestions,
sortFunction: function(a,b, inputString) {return false;}
}); });
// prevent tab traversal for dropdown (otherwise "tab" needs to be hit twice to jump from name input to amount input) // prevent tab traversal for dropdown (otherwise "tab" needs to be hit twice to jump from name input to amount input)
......
...@@ -4,6 +4,8 @@ import de.deadlocker8.budgetmaster.accounts.Account; ...@@ -4,6 +4,8 @@ import de.deadlocker8.budgetmaster.accounts.Account;
import de.deadlocker8.budgetmaster.accounts.AccountType; import de.deadlocker8.budgetmaster.accounts.AccountType;
import de.deadlocker8.budgetmaster.categories.Category; import de.deadlocker8.budgetmaster.categories.Category;
import de.deadlocker8.budgetmaster.categories.CategoryType; import de.deadlocker8.budgetmaster.categories.CategoryType;
import de.deadlocker8.budgetmaster.settings.Settings;
import de.deadlocker8.budgetmaster.settings.SettingsService;
import de.deadlocker8.budgetmaster.transactions.Transaction; import de.deadlocker8.budgetmaster.transactions.Transaction;
import de.deadlocker8.budgetmaster.transactions.TransactionRepository; import de.deadlocker8.budgetmaster.transactions.TransactionRepository;
import de.deadlocker8.budgetmaster.transactions.TransactionService; import de.deadlocker8.budgetmaster.transactions.TransactionService;
...@@ -15,6 +17,7 @@ import org.mockito.Mock; ...@@ -15,6 +17,7 @@ import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
...@@ -31,6 +34,9 @@ class TransactionServiceTest ...@@ -31,6 +34,9 @@ class TransactionServiceTest
@Mock @Mock
private TransactionRepository transactionRepository; private TransactionRepository transactionRepository;
@Mock
private SettingsService settingsService;
@InjectMocks @InjectMocks
private TransactionService transactionService; private TransactionService transactionService;
...@@ -104,4 +110,85 @@ class TransactionServiceTest ...@@ -104,4 +110,85 @@ class TransactionServiceTest
assertThat(transaction).hasFieldOrPropertyWithValue("amount", 500) assertThat(transaction).hasFieldOrPropertyWithValue("amount", 500)
.hasFieldOrPropertyWithValue("isExpenditure", false); .hasFieldOrPropertyWithValue("isExpenditure", false);
} }
@Test
void test_getNameSuggestionsJson_sortAlphabetically()
{
final Settings settings = Settings.getDefault();
Mockito.when(settingsService.getSettings()).thenReturn(settings);
final Transaction transaction1 = new Transaction();
transaction1.setID(1);
transaction1.setName("ABC");
transaction1.setAmount(700);
transaction1.setCategory(CATEGORY_CUSTOM);
transaction1.setAccount(ACCOUNT);
transaction1.setIsExpenditure(false);
final Transaction transaction2 = new Transaction();
transaction2.setID(1);
transaction2.setName("XYZ");
transaction2.setAmount(700);
transaction2.setCategory(CATEGORY_CUSTOM);
transaction2.setAccount(ACCOUNT);
transaction2.setIsExpenditure(false);
final Transaction transaction3 = new Transaction();
transaction3.setID(1);
transaction3.setName("XYZ");
transaction3.setAmount(700);
transaction3.setCategory(CATEGORY_CUSTOM);
transaction3.setAccount(ACCOUNT);
transaction3.setIsExpenditure(false);
Mockito.when(transactionRepository.findAllByOrderByNameAsc()).thenReturn(List.of(transaction1, transaction2, transaction3));
assertThat(transactionService.getNameSuggestionsJson()).isEqualTo("[\"ABC\",\"XYZ\"]");
}
@Test
void test_getNameSuggestionsJson_sortByFrequencyOfUse()
{
final Settings settings = Settings.getDefault();
settings.setOrderTransactionNameSuggestionsAlphabetically(false);
Mockito.when(settingsService.getSettings()).thenReturn(settings);
final Transaction transaction1 = new Transaction();
transaction1.setID(1);
transaction1.setName("ABC");
transaction1.setAmount(700);
transaction1.setCategory(CATEGORY_CUSTOM);
transaction1.setAccount(ACCOUNT);
transaction1.setIsExpenditure(false);
final Transaction transaction2 = new Transaction();
transaction2.setID(1);
transaction2.setName("XYZ");
transaction2.setAmount(700);
transaction2.setCategory(CATEGORY_CUSTOM);
transaction2.setAccount(ACCOUNT);
transaction2.setIsExpenditure(false);
final Transaction transaction3 = new Transaction();
transaction3.setID(1);
transaction3.setName("XYZ");
transaction3.setAmount(700);
transaction3.setCategory(CATEGORY_CUSTOM);
transaction3.setAccount(ACCOUNT);
transaction3.setIsExpenditure(false);
final Transaction transaction4 = new Transaction();
transaction4.setID(1);
transaction4.setName("LOREM");
transaction4.setAmount(700);
transaction4.setCategory(CATEGORY_CUSTOM);
transaction4.setAccount(ACCOUNT);
transaction4.setIsExpenditure(false);
Mockito.when(transactionRepository.findAllByOrderByNameAsc()).thenReturn(List.of(transaction1, transaction2, transaction3, transaction4));
assertThat(transactionService.getNameSuggestionsJson()).isEqualTo("[\"XYZ\",\"ABC\",\"LOREM\"]");
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment