add transaction tag index

This commit is contained in:
MaysWind
2020-12-13 23:58:20 +08:00
parent d46307de07
commit 45b1cf0176
10 changed files with 271 additions and 19 deletions
+34 -2
View File
@@ -78,6 +78,32 @@ func (s *TransactionTagService) GetMaxDisplayOrder(uid int64) (int, error) {
}
}
func (s *TransactionTagService) GetAllTagIdsOfTransactions(uid int64, transactionIds []int64) (map[int64][]int64, error) {
if uid <= 0 {
return nil, errs.ErrUserIdInvalid
}
var tagIndexs []*models.TransactionTagIndex
err := s.UserDataDB(uid).Where("uid=?", uid).In("transaction_id", transactionIds).Find(&tagIndexs)
allTransactionTagIds := make(map[int64][]int64)
for i := 0; i < len(tagIndexs); i++ {
tagIndex := tagIndexs[i]
var transactionTagIds []int64
if _, exists := allTransactionTagIds[tagIndex.TransactionId]; exists {
transactionTagIds = allTransactionTagIds[tagIndex.TransactionId]
}
transactionTagIds = append(transactionTagIds, tagIndex.TagId)
allTransactionTagIds[tagIndex.TransactionId] = transactionTagIds
}
return allTransactionTagIds, err
}
func (s *TransactionTagService) CreateTag(tag *models.TransactionTag) error {
if tag.Uid <= 0 {
return errs.ErrUserIdInvalid
@@ -180,13 +206,19 @@ func (s *TransactionTagService) ModifyTagDisplayOrders(uid int64, tags []*models
})
}
func (s *TransactionTagService) DeleteTags(uid int64, ids []int64) error {
func (s *TransactionTagService) DeleteTag(uid int64, tagId int64) error {
if uid <= 0 {
return errs.ErrUserIdInvalid
}
return s.UserDataDB(uid).DoTransaction(func(sess *xorm.Session) error {
deletedRows, err := sess.In("tag_id", ids).Where("uid=?", uid).Delete(&models.TransactionTag{})
exists, err := sess.Cols("uid", "tag_id").Where("uid=? AND tag_id=?", uid, tagId).Limit(1).Exist(&models.TransactionTagIndex{})
if exists {
return errs.ErrTransactionTagInUseCannotBeDeleted
}
deletedRows, err := sess.ID(tagId).Where("uid=?", uid).Delete(&models.TransactionTag{})
if err != nil {
return err
+114 -4
View File
@@ -122,7 +122,7 @@ func (s *TransactionService) GetMonthTransactionCount(uid int64, year int64, mon
return s.UserDataDB(uid).Where("uid=? AND deleted=? AND transaction_time>=? AND transaction_time<?", uid, false, startUnixTime, endUnixTime).Count(&models.Transaction{})
}
func (s *TransactionService) CreateTransaction(transaction *models.Transaction) error {
func (s *TransactionService) CreateTransaction(transaction *models.Transaction, tagIds []int64) error {
if transaction.Uid <= 0 {
return errs.ErrUserIdInvalid
}
@@ -143,11 +143,26 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
return errs.ErrTransactionTypeInvalid
}
now := time.Now().Unix()
transaction.TransactionId = s.GenerateUuid(uuid.UUID_TYPE_TRANSACTION)
transaction.TransactionTime = utils.GetMinTransactionTimeFromUnixTime(utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime))
transaction.CreatedUnixTime = time.Now().Unix()
transaction.UpdatedUnixTime = time.Now().Unix()
transaction.CreatedUnixTime = now
transaction.UpdatedUnixTime = now
tagIds = utils.ToUniqueInt64Slice(tagIds)
transactionTagIndexs := make([]*models.TransactionTagIndex, len(tagIds))
for i := 0; i < len(tagIds); i++ {
transactionTagIndexs[i] = &models.TransactionTagIndex{
Uid: transaction.Uid,
TagId: tagIds[i],
TransactionId: transaction.TransactionId,
CreatedUnixTime: now,
UpdatedUnixTime: now,
}
}
return s.UserDataDB(transaction.Uid).DoTransaction(func(sess *xorm.Session) error {
// Get and verify source and destination account
@@ -204,6 +219,28 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
return errs.ErrTransactionCategoryTypeInvalid
}
// Get and verify tags
if len(transactionTagIndexs) > 0 {
var tags []*models.TransactionTag
err := sess.Where("uid=? AND deleted=?", transaction.Uid, false).In("tag_ids", tagIds).Find(&tags)
if err != nil {
return err
}
tagMap := make(map[int64]*models.TransactionTag)
for i := 0; i < len(tags); i++ {
tagMap[tags[i].TagId] = tags[i]
}
for i := 0; i < len(transactionTagIndexs); i++ {
if _, exists := tagMap[transactionTagIndexs[i].TagId]; !exists {
return errs.ErrTransactionTagNotFound
}
}
}
// Verify balance modification transaction and calculate real amount
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
otherTransactionExists, err := sess.Where("uid=? AND deleted=? AND destination_account_id=?", transaction.Uid, false, destinationAccount.AccountId).Limit(1).Exist(&models.Transaction{})
@@ -245,6 +282,18 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
}
}
// Insert transaction tag index
if len(transactionTagIndexs) > 0 {
for i := 0; i < len(transactionTagIndexs); i++ {
transactionTagIndex := transactionTagIndexs[i]
_, err := sess.Insert(transactionTagIndex)
if err != nil {
return err
}
}
}
// Update account table
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
destinationAccount.UpdatedUnixTime = time.Now().Unix()
@@ -297,7 +346,7 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
})
}
func (s *TransactionService) ModifyTransaction(transaction *models.Transaction) error {
func (s *TransactionService) ModifyTransaction(transaction *models.Transaction, addTagIds []int64, removeTagIds []int64) error {
if transaction.Uid <= 0 {
return errs.ErrUserIdInvalid
}
@@ -310,6 +359,21 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction)
transaction.UpdatedUnixTime = now
updateCols = append(updateCols, "updated_unix_time")
addTagIds = utils.ToUniqueInt64Slice(addTagIds)
removeTagIds = utils.ToUniqueInt64Slice(removeTagIds)
transactionTagIndexs := make([]*models.TransactionTagIndex, len(addTagIds))
for i := 0; i < len(addTagIds); i++ {
transactionTagIndexs[i] = &models.TransactionTagIndex{
Uid: transaction.Uid,
TagId: addTagIds[i],
TransactionId: transaction.TransactionId,
CreatedUnixTime: now,
UpdatedUnixTime: now,
}
}
err := s.UserDB().DoTransaction(func(sess *xorm.Session) error {
// Get and verify current transaction
oldTransaction := &models.Transaction{}
@@ -435,6 +499,28 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction)
updateCols = append(updateCols, "comment")
}
// Get and verify tags
if len(transactionTagIndexs) > 0 {
var tags []*models.TransactionTag
err := sess.Where("uid=? AND deleted=?", transaction.Uid, false).In("tag_ids", addTagIds).Find(&tags)
if err != nil {
return err
}
tagMap := make(map[int64]*models.TransactionTag)
for i := 0; i < len(tags); i++ {
tagMap[tags[i].TagId] = tags[i]
}
for i := 0; i < len(transactionTagIndexs); i++ {
if _, exists := tagMap[transactionTagIndexs[i].TagId]; !exists {
return errs.ErrTransactionTagNotFound
}
}
}
// Update transaction row
updatedRows, err := sess.ID(transaction.TransactionId).Cols(updateCols...).Where("uid=? AND deleted=?", transaction.Uid, false).Update(transaction)
@@ -444,6 +530,30 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction)
return errs.ErrTransactionNotFound
}
// Update transaction tag index
if len(removeTagIds) > 0 {
deletedRows, err := sess.Where("uid=?", transaction.Uid).In("tag_id", removeTagIds).Delete(&models.TransactionTagIndex{})
if err != nil {
return err
} else if deletedRows < 1 {
return errs.ErrTransactionTagNotFound
}
return err
}
if len(transactionTagIndexs) > 0 {
for i := 0; i < len(transactionTagIndexs); i++ {
transactionTagIndex := transactionTagIndexs[i]
_, err := sess.Insert(transactionTagIndex)
if err != nil {
return err
}
}
}
// Update account table
if oldTransaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
if transaction.SourceAccountId != oldTransaction.SourceAccountId {