Allow filtering by category to also filter by child categories.
Build and Deploy API / build-and-deploy (push) Successful in 1m44s
Details
Build and Deploy API / build-and-deploy (push) Successful in 1m44s
Details
This commit is contained in:
parent
6415311925
commit
3368cfa96c
|
|
@ -223,9 +223,8 @@ class SqliteTransactionRepository : TransactionRepository {
|
||||||
|
|
||||||
// 1. Get the total count of transactions that match the search filters.
|
// 1. Get the total count of transactions that match the search filters.
|
||||||
qb.select("COUNT (DISTINCT txn.id)");
|
qb.select("COUNT (DISTINCT txn.id)");
|
||||||
applyFilters(qb, request);
|
applyFilters(qb, request, new SqliteTransactionCategoryRepository(db));
|
||||||
string countQuery = qb.build();
|
string countQuery = qb.build();
|
||||||
// writeln(countQuery);
|
|
||||||
Statement countStmt = db.prepare(countQuery);
|
Statement countStmt = db.prepare(countQuery);
|
||||||
qb.applyArgBindings(countStmt);
|
qb.applyArgBindings(countStmt);
|
||||||
auto countResult = countStmt.execute();
|
auto countResult = countStmt.execute();
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,23 @@ import std.uri;
|
||||||
import std.uni;
|
import std.uni;
|
||||||
|
|
||||||
import util.sqlite;
|
import util.sqlite;
|
||||||
|
import transaction.data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a set of filters to a query builder for searching over transactions.
|
* Applies a set of filters to a query builder for searching over transactions.
|
||||||
* Params:
|
* Params:
|
||||||
* qb = The query builder to add WHERE clauses and argument bindings to.
|
* qb = The query builder to add WHERE clauses and argument bindings to.
|
||||||
* request = The request to get filter options from.
|
* request = The request to get filter options from.
|
||||||
|
* categoryRepo = Repository for fetching category data, which might be
|
||||||
|
* needed if the user is filtering by a parent category.
|
||||||
*/
|
*/
|
||||||
void applyFilters(ref QueryBuilder qb, in ServerHttpRequest request) {
|
void applyFilters(
|
||||||
|
ref QueryBuilder qb,
|
||||||
|
in ServerHttpRequest request,
|
||||||
|
TransactionCategoryRepository categoryRepo
|
||||||
|
) {
|
||||||
applyPropertyInFilter!string(qb, request, "tags.tag", "tag");
|
applyPropertyInFilter!string(qb, request, "tags.tag", "tag");
|
||||||
applyPropertyInFilter!ulong(qb, request, "vendor.id", "vendor");
|
applyPropertyInFilter!ulong(qb, request, "vendor.id", "vendor");
|
||||||
applyPropertyInFilter!ulong(qb, request, "category.id", "category");
|
|
||||||
applyPropertyInFilter!string(qb, request, "txn.currency", "currency");
|
applyPropertyInFilter!string(qb, request, "txn.currency", "currency");
|
||||||
applyPropertyInFilter!ulong(qb, request, "account_credit.id", "credited-account");
|
applyPropertyInFilter!ulong(qb, request, "account_credit.id", "credited-account");
|
||||||
applyPropertyInFilter!ulong(qb, request, "account_debit.id", "debited-account");
|
applyPropertyInFilter!ulong(qb, request, "account_debit.id", "debited-account");
|
||||||
|
|
@ -45,6 +51,25 @@ void applyFilters(ref QueryBuilder qb, in ServerHttpRequest request) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Separate filter that handles the hierarchical category relationship, so
|
||||||
|
// if a parent category is filtered, all children are also included.
|
||||||
|
if (request.hasParam("category")) {
|
||||||
|
ulong[] categoryIds = request.getParamValues!ulong("category");
|
||||||
|
auto app = appender!(ulong[]);
|
||||||
|
foreach (id; categoryIds) {
|
||||||
|
app ~= getAllPossibleCategoryIds(id, categoryRepo);
|
||||||
|
}
|
||||||
|
ulong[] allPossibleIds = app[];
|
||||||
|
if (allPossibleIds.length > 0) {
|
||||||
|
qb.where("(" ~ "txn.category_id = ?".repeat(allPossibleIds.length).join(" OR ") ~ ")");
|
||||||
|
qb.withArgBinding((ref stmt, ref idx) {
|
||||||
|
foreach (value; allPossibleIds) {
|
||||||
|
stmt.bind(idx++, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (request.hasParam("min-amount")) {
|
if (request.hasParam("min-amount")) {
|
||||||
ulong[] values = request.getParamValues!ulong("min-amount");
|
ulong[] values = request.getParamValues!ulong("min-amount");
|
||||||
if (values.length > 0) {
|
if (values.length > 0) {
|
||||||
|
|
@ -140,3 +165,13 @@ private T[] getParamValues(T = string)(in ServerHttpRequest request, string key)
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ulong[] getAllPossibleCategoryIds(ulong parentId, TransactionCategoryRepository categoryRepo) {
|
||||||
|
auto app = appender!(ulong[]);
|
||||||
|
app ~= parentId;
|
||||||
|
foreach (child; categoryRepo.findAllByParentId(Optional!ulong.of(parentId))) {
|
||||||
|
app ~= child.id;
|
||||||
|
app ~= getAllPossibleCategoryIds(child.id, categoryRepo);
|
||||||
|
}
|
||||||
|
return app[];
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue