improving usability by proposing tags
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -12,6 +12,8 @@ public interface AccountDb {
|
||||
|
||||
Collection<Account> listAccounts(long userId);
|
||||
|
||||
Collection<String> listTags(long accountId, String source, String destination);
|
||||
|
||||
Account loadAccount(long accountId);
|
||||
|
||||
Transaction loadTransaction(long transactionId);
|
||||
|
||||
@@ -156,6 +156,25 @@ public class AccountingModule extends BaseHandler implements AccountingService {
|
||||
return sendContent(ex, transaction);
|
||||
}
|
||||
|
||||
private List<String> egalize(Set<String> tags, String key) {
|
||||
var result = new HashSet<String>();
|
||||
var lower = key.toLowerCase();
|
||||
var len = key.length();
|
||||
for (var tag : tags) {
|
||||
if (tag.length() == key.length()) continue;
|
||||
result.add(tag.toLowerCase().startsWith(lower) ? key + tag.substring(len) : tag);
|
||||
}
|
||||
return result.stream().sorted(String.CASE_INSENSITIVE_ORDER).toList();
|
||||
}
|
||||
|
||||
private String extractParty(String field, JSONObject json){
|
||||
if (!json.has(field)) return null;
|
||||
if (!(json.get(field) instanceof JSONObject data)) return null;
|
||||
if (data.has(Field.ID)) return data.get(Field.ID).toString();
|
||||
if (data.has(Field.DISPLAY)) return data.get(Field.DISPLAY).toString();
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean getAccount(UmbrellaUser user, long accountId, HttpExchange ex) throws IOException {
|
||||
LOG.log(WARNING,"Missing authorization check in AccountingModule.getAccount(…)!");
|
||||
var account = accountDb.loadAccount(accountId);
|
||||
@@ -294,20 +313,17 @@ public class AccountingModule extends BaseHandler implements AccountingService {
|
||||
private boolean postSearchTags(long accountId, UmbrellaUser user, HttpExchange ex) throws IOException {
|
||||
LOG.log(WARNING,"Missing authorization check in AccountingModule.getAccount(…)!");
|
||||
var key = body(ex);
|
||||
var tags = accountDb.searchTagsContaining(key,accountId);
|
||||
if (tags.size()<10) tags.addAll(tagService().search(key,user));
|
||||
return sendContent(ex,egalize(tags,key));
|
||||
}
|
||||
|
||||
private List<String> egalize(Set<String> tags, String key) {
|
||||
var result = new HashSet<String>();
|
||||
var lower = key.toLowerCase();
|
||||
var len = key.length();
|
||||
for (var tag : tags) {
|
||||
if (tag.length() == key.length()) continue;
|
||||
result.add(tag.toLowerCase().startsWith(lower) ? key + tag.substring(len) : tag);
|
||||
if (!key.trim().startsWith("{")) { // search tags that contain value of body
|
||||
var tags = accountDb.searchTagsContaining(key, accountId);
|
||||
if (tags.size() < 10) tags.addAll(tagService().search(key, user));
|
||||
return sendContent(ex, egalize(tags, key));
|
||||
}
|
||||
return result.stream().sorted(String.CASE_INSENSITIVE_ORDER).toList();
|
||||
// search tags for account with specified source and destination
|
||||
var json = new JSONObject(key);
|
||||
var src = extractParty(Field.SOURCE, json);
|
||||
var dst = extractParty(Field.DESTINATION, json);
|
||||
var tags = accountDb.listTags(accountId,src,dst);
|
||||
return sendContent(ex,tags);
|
||||
}
|
||||
|
||||
private boolean postToAccount(long accountId, Path path, UmbrellaUser user, HttpExchange ex) throws IOException {
|
||||
|
||||
@@ -150,6 +150,45 @@ public class SqliteDb extends BaseDb implements AccountDb {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> listTags(long accountId, String source, String destination) {
|
||||
try {
|
||||
var rs = select(TRANSACTION_ID,Field.TAG)
|
||||
.from(TABLE_TRANSACTIONS)
|
||||
.leftJoin(ID,TABLE_TAGS_TRANSACTIONS, TRANSACTION_ID)
|
||||
.leftJoin(TAG_ID,TABLE_TAGS,ID)
|
||||
.where(ACCOUNT,equal(accountId))
|
||||
.where(SOURCE,equal(source))
|
||||
.where(DESTINATION,equal(destination))
|
||||
.sort(TRANSACTION_ID).exec(db);
|
||||
Set<String> set = null;
|
||||
Set<String> transactionTags = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
|
||||
Long lastTransaction = null;
|
||||
while (rs.next()){
|
||||
var currentTransaction = rs.getLong(TRANSACTION_ID);
|
||||
if (lastTransaction == null) { // first row
|
||||
transactionTags.add(rs.getString(TAG));
|
||||
lastTransaction = currentTransaction;
|
||||
} else if (lastTransaction == currentTransaction) {
|
||||
transactionTags.add(rs.getString(TAG));
|
||||
} else {
|
||||
if (set == null) {
|
||||
set = transactionTags;
|
||||
} else {
|
||||
set.retainAll(transactionTags);
|
||||
}
|
||||
transactionTags = new HashSet<>();
|
||||
transactionTags.add(rs.getString(TAG));
|
||||
lastTransaction = currentTransaction;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
return set;
|
||||
} catch (SQLException e){
|
||||
throw failedToLoadMembers(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account loadAccount(long accountId) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user