From 4def7ed60cc5387f6e97f594cb84878dcd277cfd Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sat, 20 Sep 2025 17:45:21 +0800 Subject: [PATCH] the query_transactions_tool_handler mcp tool supports filtering multiple categories or accounts with the same name, and filtering sub-accounts / secondary categories by their parent account / category name --- pkg/mcp/query_transactions_tool_handler.go | 14 ++++---- pkg/services/accounts.go | 41 ++++++++++++++++++++++ pkg/services/transaction_categories.go | 41 ++++++++++++++++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/pkg/mcp/query_transactions_tool_handler.go b/pkg/mcp/query_transactions_tool_handler.go index 38a36742..a31756de 100644 --- a/pkg/mcp/query_transactions_tool_handler.go +++ b/pkg/mcp/query_transactions_tool_handler.go @@ -126,13 +126,12 @@ func (h *mcpQueryTransactionsToolHandler) Handle(c *core.WebContext, callToolReq return nil, nil, err } - accountsMap := services.GetAccountService().GetVisibleAccountNameMapByList(allAccounts) filterAccountIds := make([]int64, 0) if queryTransactionsRequest.AccountName != "" { - if account, exists := accountsMap[queryTransactionsRequest.AccountName]; exists { - filterAccountIds = append(filterAccountIds, account.AccountId) - } else { + filterAccountIds = services.GetAccountService().GetAccountOrSubAccountIdsByAccountName(allAccounts, queryTransactionsRequest.AccountName) + + if len(filterAccountIds) < 1 { return nil, nil, errs.ErrAccountNotFound } } @@ -144,13 +143,12 @@ func (h *mcpQueryTransactionsToolHandler) Handle(c *core.WebContext, callToolReq return nil, nil, err } - categoriesMap := services.GetTransactionCategoryService().GetVisibleCategoryNameMapByList(allCategories) filterCategoryIds := make([]int64, 0) if queryTransactionsRequest.SecondaryCategoryName != "" { - if category, exists := categoriesMap[queryTransactionsRequest.SecondaryCategoryName]; exists { - filterCategoryIds = append(filterCategoryIds, category.CategoryId) - } else { + filterCategoryIds = services.GetTransactionCategoryService().GetCategoryOrSubCategoryIdsByCategoryName(allCategories, queryTransactionsRequest.SecondaryCategoryName) + + if len(filterCategoryIds) < 1 { return nil, nil, errs.ErrTransactionCategoryNotFound } } diff --git a/pkg/services/accounts.go b/pkg/services/accounts.go index 05a39fdc..cc46637b 100644 --- a/pkg/services/accounts.go +++ b/pkg/services/accounts.go @@ -940,3 +940,44 @@ func (s *AccountService) GetAccountOrSubAccountIds(c core.Context, accountIds st return allAccountIds, nil } + +// GetAccountOrSubAccountIdsByAccountName returns a list of account ids or sub-account ids according to given account name +func (s *AccountService) GetAccountOrSubAccountIdsByAccountName(accounts []*models.Account, accountName string) []int64 { + accountIds := make([]int64, 0) + parentAccountIds := make([]int64, 0) + childAccountByParentAccountId := make(map[int64][]*models.Account) + + for i := 0; i < len(accounts); i++ { + account := accounts[i] + + if account.Name == accountName { + if account.Type == models.ACCOUNT_TYPE_SINGLE_ACCOUNT { + accountIds = append(accountIds, account.AccountId) + } else if account.Type == models.ACCOUNT_TYPE_MULTI_SUB_ACCOUNTS { + parentAccountIds = append(parentAccountIds, account.AccountId) + } + } else if account.ParentAccountId > 0 { + childAccounts, exists := childAccountByParentAccountId[account.ParentAccountId] + + if !exists { + childAccounts = make([]*models.Account, 0) + } + + childAccounts = append(childAccounts, account) + childAccountByParentAccountId[account.ParentAccountId] = childAccounts + } + } + + for i := 0; i < len(parentAccountIds); i++ { + parentAccountId := parentAccountIds[i] + + if childAccounts, exists := childAccountByParentAccountId[parentAccountId]; exists { + for j := 0; j < len(childAccounts); j++ { + childAccount := childAccounts[j] + accountIds = append(accountIds, childAccount.AccountId) + } + } + } + + return accountIds +} diff --git a/pkg/services/transaction_categories.go b/pkg/services/transaction_categories.go index efac0353..f14ece17 100644 --- a/pkg/services/transaction_categories.go +++ b/pkg/services/transaction_categories.go @@ -602,3 +602,44 @@ func (s *TransactionCategoryService) GetCategoryOrSubCategoryIds(c core.Context, return allCategoryIds, nil } + +// GetCategoryOrSubCategoryIdsByCategoryName returns a list of transaction category ids or sub-category ids according to given category name +func (s *TransactionCategoryService) GetCategoryOrSubCategoryIdsByCategoryName(categories []*models.TransactionCategory, categoryName string) []int64 { + categoryIds := make([]int64, 0) + parentCategoryIds := make([]int64, 0) + childCategoryByParentCategoryId := make(map[int64][]*models.TransactionCategory) + + for i := 0; i < len(categories); i++ { + category := categories[i] + + if category.Name == categoryName { + if category.ParentCategoryId != models.LevelOneTransactionCategoryParentId { + categoryIds = append(categoryIds, category.CategoryId) + } else if category.ParentCategoryId == models.LevelOneTransactionCategoryParentId { + parentCategoryIds = append(parentCategoryIds, category.CategoryId) + } + } else if category.ParentCategoryId != models.LevelOneTransactionCategoryParentId { + childCategories, exists := childCategoryByParentCategoryId[category.ParentCategoryId] + + if !exists { + childCategories = make([]*models.TransactionCategory, 0) + } + + childCategories = append(childCategories, category) + childCategoryByParentCategoryId[category.ParentCategoryId] = childCategories + } + } + + for i := 0; i < len(parentCategoryIds); i++ { + parentCategoryId := parentCategoryIds[i] + + if childCategories, exists := childCategoryByParentCategoryId[parentCategoryId]; exists { + for j := 0; j < len(childCategories); j++ { + childCategory := childCategories[j] + categoryIds = append(categoryIds, childCategory.CategoryId) + } + } + } + + return categoryIds +}