From f151eb619782f8025515ed74cb6365b71cf0802c Mon Sep 17 00:00:00 2001 From: MaysWind Date: Tue, 9 Jul 2024 00:53:22 +0800 Subject: [PATCH] add command transaction-tag-index-fix-transaction-time to fix transaction tag index which does not have transaction time --- cmd/user_data.go | 36 +++++++++++++++++ pkg/cli/user_data.go | 66 ++++++++++++++++++++++++++++++++ pkg/errs/transaction_tag.go | 1 + pkg/services/transaction_tags.go | 26 +++++++++++++ src/locales/en.js | 1 + src/locales/zh_Hans.js | 1 + 6 files changed, 131 insertions(+) diff --git a/cmd/user_data.go b/cmd/user_data.go index 6ae1f2b6..61d1be2e 100644 --- a/cmd/user_data.go +++ b/cmd/user_data.go @@ -230,6 +230,19 @@ var UserData = &cli.Command{ }, }, }, + { + Name: "transaction-tag-index-fix-transaction-time", + Usage: "fix the transaction tag index data which does not have transaction time", + Action: fixTransactionTagIndexNotHaveTransactionTime, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "username", + Aliases: []string{"n"}, + Required: true, + Usage: "Specific user name", + }, + }, + }, { Name: "transaction-export", Usage: "Export user all transactions to file", @@ -553,6 +566,29 @@ func checkUserTransactionAndAccount(c *cli.Context) error { return nil } +func fixTransactionTagIndexNotHaveTransactionTime(c *cli.Context) error { + _, err := initializeSystem(c) + + if err != nil { + return err + } + + username := c.String("username") + + log.BootInfof("[user_data.fixTransactionTagIndexNotHaveTransactionTime] starting fixing user \"%s\" transaction tag index data", username) + + _, err = clis.UserData.FixTransactionTagIndexWithTransactionTime(c, username) + + if err != nil { + log.BootErrorf("[user_data.fixTransactionTagIndexNotHaveTransactionTime] error occurs when fixing user data") + return err + } + + log.BootInfof("[user_data.fixTransactionTagIndexNotHaveTransactionTime] user transaction tag index data has been fixed successfully") + + return nil +} + func exportUserTransaction(c *cli.Context) error { _, err := initializeSystem(c) diff --git a/pkg/cli/user_data.go b/pkg/cli/user_data.go index 74a951e9..2093e7a2 100644 --- a/pkg/cli/user_data.go +++ b/pkg/cli/user_data.go @@ -547,6 +547,72 @@ func (l *UserDataCli) CheckTransactionAndAccount(c *cli.Context, username string return true, nil } +// FixTransactionTagIndexWithTransactionTime fixes user transaction tag index data with transaction time +func (l *UserDataCli) FixTransactionTagIndexWithTransactionTime(c *cli.Context, username string) (bool, error) { + if username == "" { + log.BootErrorf("[user_data.FixTransactionTagIndexWithTransactionTime] user name is empty") + return false, errs.ErrUsernameIsEmpty + } + + uid, err := l.getUserIdByUsername(c, username) + + if err != nil { + log.BootErrorf("[user_data.FixTransactionTagIndexWithTransactionTime] error occurs when getting user id by user name") + return false, err + } + + tagIndexs, err := l.tags.GetAllTagIdsOfAllTransactions(nil, uid) + + if err != nil { + log.BootErrorf("[user_data.FixTransactionTagIndexWithTransactionTime] failed to get tag index for user \"%s\", because %s", username, err.Error()) + return false, err + } + + invalidTagIndexs := make([]*models.TransactionTagIndex, 0, len(tagIndexs)) + + for i := 0; i < len(tagIndexs); i++ { + tagIndex := tagIndexs[i] + + if tagIndex.TransactionTime < 1 { + invalidTagIndexs = append(invalidTagIndexs, tagIndex) + } + } + + if len(invalidTagIndexs) < 1 { + log.BootErrorf("[user_data.FixTransactionTagIndexWithTransactionTime] all user transaction tag index data has been checked, there is no problem with user data") + return false, errs.ErrOperationFailed + } + + allTransactions, err := l.transactions.GetAllTransactions(nil, uid, pageCountForGettingTransactions, false) + + if err != nil { + log.BootErrorf("[user_data.FixTransactionTagIndexWithTransactionTime] failed to all transactions for user \"%s\", because %s", username, err.Error()) + return false, err + } + + transactionMap := l.transactions.GetTransactionMapByList(allTransactions) + + for i := 0; i < len(invalidTagIndexs); i++ { + tagIndex := invalidTagIndexs[i] + transaction, exists := transactionMap[tagIndex.TransactionId] + + if !exists { + continue + } + + tagIndex.TransactionTime = transaction.TransactionTime + } + + err = l.tags.ModifyTagIndexTransactionTime(nil, uid, invalidTagIndexs) + + if err != nil { + log.BootErrorf("[user_data.FixTransactionTagIndexWithTransactionTime] failed to update transaction tag index for user \"%s\", because %s", username, err.Error()) + return false, err + } + + return true, nil +} + // ExportTransaction returns csv file content according user all transactions func (l *UserDataCli) ExportTransaction(c *cli.Context, username string, fileType string) ([]byte, error) { if username == "" { diff --git a/pkg/errs/transaction_tag.go b/pkg/errs/transaction_tag.go index eabaa702..2ee54321 100644 --- a/pkg/errs/transaction_tag.go +++ b/pkg/errs/transaction_tag.go @@ -9,4 +9,5 @@ var ( ErrTransactionTagNameIsEmpty = NewNormalError(NormalSubcategoryTag, 2, http.StatusBadRequest, "transaction tag name is empty") ErrTransactionTagNameAlreadyExists = NewNormalError(NormalSubcategoryTag, 3, http.StatusBadRequest, "transaction tag name already exists") ErrTransactionTagInUseCannotBeDeleted = NewNormalError(NormalSubcategoryTag, 4, http.StatusBadRequest, "transaction tag is in use and cannot be deleted") + ErrTransactionTagIndexNotFound = NewNormalError(NormalSubcategoryTag, 5, http.StatusBadRequest, "transaction tag index not found") ) diff --git a/pkg/services/transaction_tags.go b/pkg/services/transaction_tags.go index f0bdd413..679aa775 100644 --- a/pkg/services/transaction_tags.go +++ b/pkg/services/transaction_tags.go @@ -342,6 +342,32 @@ func (s *TransactionTagService) ExistsTagName(c *core.Context, uid int64, name s return s.UserDataDB(uid).NewSession(c).Cols("name").Where("uid=? AND deleted=? AND name=?", uid, false, name).Exist(&models.TransactionTag{}) } +// ModifyTagIndexTransactionTime updates transaction time of given transaction tag indexes +func (s *TransactionTagService) ModifyTagIndexTransactionTime(c *core.Context, uid int64, tagIndexs []*models.TransactionTagIndex) error { + if uid <= 0 { + return errs.ErrUserIdInvalid + } + + for i := 0; i < len(tagIndexs); i++ { + tagIndexs[i].UpdatedUnixTime = time.Now().Unix() + } + + return s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error { + for i := 0; i < len(tagIndexs); i++ { + tagIndex := tagIndexs[i] + updatedRows, err := sess.ID(tagIndex.TagIndexId).Cols("transaction_time", "updated_unix_time").Where("uid=? AND deleted=?", uid, false).Update(tagIndex) + + if err != nil { + return err + } else if updatedRows < 1 { + return errs.ErrTransactionTagIndexNotFound + } + } + + return nil + }) +} + // GetTagMapByList returns a transaction tag map by a list func (s *TransactionTagService) GetTagMapByList(tags []*models.TransactionTag) map[int64]*models.TransactionTag { tagMap := make(map[int64]*models.TransactionTag) diff --git a/src/locales/en.js b/src/locales/en.js index 7d9b4f0a..51e85098 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -680,6 +680,7 @@ export default { 'transaction tag name is empty': 'Transaction tag title is empty', 'transaction tag name already exists': 'Transaction tag title already exists', 'transaction tag is in use and cannot be deleted': 'Transaction tag is in use and it cannot be deleted', + 'transaction tag index not found': 'Transaction tag index is not found', 'data export not allowed': 'User data export is not allowed', 'query items cannot be blank': 'There are no query items', 'query items too much': 'There are too many query items', diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index aaf34317..4e54f9cc 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -680,6 +680,7 @@ export default { 'transaction tag name is empty': '交易标签标题不能为空', 'transaction tag name already exists': '交易标签标题已经存在', 'transaction tag is in use and cannot be deleted': '交易标签正在被使用,无法删除', + 'transaction tag index not found': '交易标签索引不存在', 'data export not allowed': '不允许用户数据导出', 'query items cannot be blank': '请求项目不能为空', 'query items too much': '请求项目过多',