finnow/finnow-api/source/analytics/modules/category_spend.d

49 lines
1.6 KiB
D

module analytics.modules.category_spend;
import handy_http_primitives : Optional;
import std.algorithm;
import std.array;
import analytics.data;
import profile.data;
import util.money : Currency;
import util.data : TimeRange;
CategorySpendData[] computeCategorySpend(
ProfileDataSource ds,
in Currency currency,
in TimeRange timeRange,
in Optional!ulong parentId
) {
AnalyticsRepository repo = ds.getAnalyticsRepository();
CategorySpendData[] allCategories = repo.getCategorySpendData(currency, timeRange);
return allCategories
.filter!(d => (
parentId
? d.parentCategoryId && d.parentCategoryId.value == parentId.value
: d.parentCategoryId.isNull
))
.map!((category) {
// For each category that we're reporting on, recursively sum up
// the amount of the category and all its children.
long totalRecursiveSum = sumAllChildCategoriesRecursive(category, allCategories);
return CategorySpendData(
category.categoryId,
category.categoryName,
category.categoryColor,
category.parentCategoryId,
totalRecursiveSum
);
})
.array();
}
private long sumAllChildCategoriesRecursive(in CategorySpendData parentCategory, in CategorySpendData[] data) {
long sum = parentCategory.amount;
foreach (category; data) {
if (category.parentCategoryId && category.parentCategoryId.value == parentCategory.categoryId) {
sum += sumAllChildCategoriesRecursive(category, data);
}
}
return sum;
}