mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-14 06:57:35 +08:00
code refactor
This commit is contained in:
+62
-27
@@ -36,7 +36,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{},
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
transactions, err := a.transactions.GetTransactionsByMaxTime(uid, transactionListReq.MaxTime, transactionListReq.Count+1)
|
||||
transactions, err := a.transactions.GetTransactionsByMaxTime(uid, transactionListReq.MaxTime, nil, 0, 0, transactionListReq.Count+1)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error())
|
||||
@@ -49,6 +49,12 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{},
|
||||
finalCount = len(transactions)
|
||||
}
|
||||
|
||||
hasMore := false
|
||||
|
||||
if finalCount < len(transactions) {
|
||||
hasMore = true
|
||||
}
|
||||
|
||||
transactionIds := make([]int64, finalCount)
|
||||
|
||||
for i := 0; i < finalCount; i++ {
|
||||
@@ -72,7 +78,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{},
|
||||
|
||||
sort.Sort(transactionResps.Items)
|
||||
|
||||
if finalCount < len(transactions) {
|
||||
if hasMore {
|
||||
transactionResps.NextTimeSequenceId = &transactions[finalCount].TransactionTime
|
||||
}
|
||||
|
||||
@@ -90,7 +96,7 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
transactions, err := a.transactions.GetTransactionsInMonthByPage(uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Page, transactionListReq.Count)
|
||||
transactions, err := a.transactions.GetTransactionsInMonthByPage(uid, transactionListReq.Year, transactionListReq.Month, nil, 0, 0, transactionListReq.Page, transactionListReq.Count)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionMonthListHandler] failed to get transactions in month \"%d-%d\" for user \"uid:%d\", because %s", transactionListReq.Year, transactionListReq.Month, uid, err.Error())
|
||||
@@ -138,6 +144,10 @@ func (a *TransactionsApi) TransactionGetHandler(c *core.Context) (interface{}, *
|
||||
return nil, errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
transaction = a.transactions.GetRelatedTransferTransaction(transaction, transaction.RelatedId)
|
||||
}
|
||||
|
||||
allTransactionTagIds, err := a.transactionTags.GetAllTagIdsOfTransactions(uid, []int64{transaction.TransactionId})
|
||||
|
||||
if err != nil {
|
||||
@@ -178,17 +188,17 @@ func (a *TransactionsApi) TransactionCreateHandler(c *core.Context) (interface{}
|
||||
return nil, errs.ErrBalanceModificationTransactionCannotSetCategory
|
||||
}
|
||||
|
||||
if transactionCreateReq.Type != models.TRANSACTION_TYPE_TRANSFER && transactionCreateReq.SourceAccountId != transactionCreateReq.DestinationAccountId {
|
||||
log.WarnfWithRequestId(c, "[transactions.TransactionCreateHandler] non-transfer transaction source account is not destination account")
|
||||
return nil, errs.ErrTransactionSourceAndDestinationIdNotEqual
|
||||
if transactionCreateReq.Type != models.TRANSACTION_TYPE_TRANSFER && transactionCreateReq.DestinationAccountId != 0 {
|
||||
log.WarnfWithRequestId(c, "[transactions.TransactionCreateHandler] non-transfer transaction destination account cannot be set")
|
||||
return nil, errs.ErrTransactionDestinationAccountCannotBeSet
|
||||
} else if transactionCreateReq.Type == models.TRANSACTION_TYPE_TRANSFER && transactionCreateReq.SourceAccountId == transactionCreateReq.DestinationAccountId {
|
||||
log.WarnfWithRequestId(c, "[transactions.TransactionCreateHandler] transfer transaction source account must not be destination account")
|
||||
return nil, errs.ErrTransactionSourceAndDestinationIdCannotBeEqual
|
||||
}
|
||||
|
||||
if transactionCreateReq.Type != models.TRANSACTION_TYPE_TRANSFER && transactionCreateReq.SourceAmount != transactionCreateReq.DestinationAmount {
|
||||
log.WarnfWithRequestId(c, "[transactions.TransactionCreateHandler] non-transfer transaction source amount is not destination amount")
|
||||
return nil, errs.ErrTransactionSourceAndDestinationAmountNotEqual
|
||||
if transactionCreateReq.Type != models.TRANSACTION_TYPE_TRANSFER && transactionCreateReq.DestinationAmount != 0 {
|
||||
log.WarnfWithRequestId(c, "[transactions.TransactionCreateHandler] non-transfer transaction destination amount cannot be set")
|
||||
return nil, errs.ErrTransactionDestinationAmountCannotBeSet
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
@@ -233,6 +243,11 @@ func (a *TransactionsApi) TransactionModifyHandler(c *core.Context) (interface{}
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionModifyHandler] cannot modify transaction \"id:%d\" for user \"uid:%d\", because transaction type is transfer in", transactionModifyReq.Id, uid)
|
||||
return nil, errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
|
||||
allTransactionTagIds, err := a.transactionTags.GetAllTagIdsOfTransactions(uid, []int64{transaction.TransactionId})
|
||||
|
||||
if err != nil {
|
||||
@@ -249,19 +264,22 @@ func (a *TransactionsApi) TransactionModifyHandler(c *core.Context) (interface{}
|
||||
Uid: uid,
|
||||
CategoryId: transactionModifyReq.CategoryId,
|
||||
TransactionTime: utils.GetMinTransactionTimeFromUnixTime(transactionModifyReq.Time),
|
||||
SourceAccountId: transactionModifyReq.SourceAccountId,
|
||||
DestinationAccountId: transactionModifyReq.DestinationAccountId,
|
||||
SourceAmount: transactionModifyReq.SourceAmount,
|
||||
DestinationAmount: transactionModifyReq.DestinationAmount,
|
||||
AccountId: transactionModifyReq.SourceAccountId,
|
||||
Amount: transactionModifyReq.SourceAmount,
|
||||
Comment: transactionModifyReq.Comment,
|
||||
}
|
||||
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
newTransaction.RelatedAccountId = transactionModifyReq.DestinationAccountId
|
||||
newTransaction.RelatedAccountAmount = transactionModifyReq.DestinationAmount
|
||||
}
|
||||
|
||||
if newTransaction.CategoryId == transaction.CategoryId &&
|
||||
utils.GetUnixTimeFromTransactionTime(newTransaction.TransactionTime) == utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime) &&
|
||||
newTransaction.SourceAccountId == transaction.SourceAccountId &&
|
||||
newTransaction.DestinationAccountId == transaction.DestinationAccountId &&
|
||||
newTransaction.SourceAmount == transaction.SourceAmount &&
|
||||
newTransaction.DestinationAmount == transaction.DestinationAmount &&
|
||||
newTransaction.AccountId == transaction.AccountId &&
|
||||
newTransaction.Amount == transaction.Amount &&
|
||||
(transaction.Type != models.TRANSACTION_DB_TYPE_TRANSFER_OUT || newTransaction.RelatedAccountId == transaction.RelatedAccountId) &&
|
||||
(transaction.Type != models.TRANSACTION_DB_TYPE_TRANSFER_OUT || newTransaction.RelatedAccountAmount == transaction.RelatedAccountAmount) &&
|
||||
newTransaction.Comment == transaction.Comment &&
|
||||
len(addTransactionTagIds) < 1 &&
|
||||
len(removeTransactionTagIds) < 1 {
|
||||
@@ -303,15 +321,32 @@ func (a *TransactionsApi) TransactionDeleteHandler(c *core.Context) (interface{}
|
||||
}
|
||||
|
||||
func (a *TransactionsApi) createNewTransactionModel(uid int64, transactionCreateReq *models.TransactionCreateRequest) *models.Transaction {
|
||||
return &models.Transaction{
|
||||
Uid: uid,
|
||||
Type: transactionCreateReq.Type,
|
||||
CategoryId: transactionCreateReq.CategoryId,
|
||||
TransactionTime: utils.GetMinTransactionTimeFromUnixTime(transactionCreateReq.Time),
|
||||
SourceAccountId: transactionCreateReq.SourceAccountId,
|
||||
DestinationAccountId: transactionCreateReq.DestinationAccountId,
|
||||
SourceAmount: transactionCreateReq.SourceAmount,
|
||||
DestinationAmount: transactionCreateReq.DestinationAmount,
|
||||
Comment: transactionCreateReq.Comment,
|
||||
var transactionDbType models.TransactionDbType
|
||||
|
||||
if transactionCreateReq.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
transactionDbType = models.TRANSACTION_DB_TYPE_MODIFY_BALANCE
|
||||
} else if transactionCreateReq.Type == models.TRANSACTION_TYPE_EXPENSE {
|
||||
transactionDbType = models.TRANSACTION_DB_TYPE_EXPENSE
|
||||
} else if transactionCreateReq.Type == models.TRANSACTION_TYPE_INCOME {
|
||||
transactionDbType = models.TRANSACTION_DB_TYPE_INCOME
|
||||
} else if transactionCreateReq.Type == models.TRANSACTION_TYPE_TRANSFER {
|
||||
transactionDbType = models.TRANSACTION_DB_TYPE_TRANSFER_OUT
|
||||
}
|
||||
|
||||
transaction := &models.Transaction{
|
||||
Uid: uid,
|
||||
Type: transactionDbType,
|
||||
CategoryId: transactionCreateReq.CategoryId,
|
||||
TransactionTime: utils.GetMinTransactionTimeFromUnixTime(transactionCreateReq.Time),
|
||||
AccountId: transactionCreateReq.SourceAccountId,
|
||||
Amount: transactionCreateReq.SourceAmount,
|
||||
Comment: transactionCreateReq.Comment,
|
||||
}
|
||||
|
||||
if transactionCreateReq.Type == models.TRANSACTION_TYPE_TRANSFER {
|
||||
transaction.RelatedAccountId = transactionCreateReq.DestinationAccountId
|
||||
transaction.RelatedAccountAmount = transactionCreateReq.DestinationAmount
|
||||
}
|
||||
|
||||
return transaction
|
||||
}
|
||||
|
||||
+11
-10
@@ -7,14 +7,15 @@ var (
|
||||
ErrTransactionIdInvalid = NewNormalError(NormalSubcategoryTransaction, 0, http.StatusBadRequest, "transaction id is invalid")
|
||||
ErrTransactionNotFound = NewNormalError(NormalSubcategoryTransaction, 1, http.StatusBadRequest, "transaction not found")
|
||||
ErrTransactionTypeInvalid = NewNormalError(NormalSubcategoryTransaction, 2, http.StatusBadRequest, "transaction type is invalid")
|
||||
ErrTransactionSourceAndDestinationIdNotEqual = NewNormalError(NormalSubcategoryTransaction, 3, http.StatusBadRequest, "transaction source and destination account id not equal")
|
||||
ErrTransactionSourceAndDestinationIdCannotBeEqual = NewNormalError(NormalSubcategoryTransaction, 4, http.StatusBadRequest, "transaction source and destination account id cannot be equal")
|
||||
ErrTransactionSourceAndDestinationAmountNotEqual = NewNormalError(NormalSubcategoryTransaction, 5, http.StatusBadRequest, "transaction source and destination amount not equal")
|
||||
ErrTooMuchTransactionInOneSecond = NewNormalError(NormalSubcategoryTransaction, 6, http.StatusBadRequest, "too much transaction in one second")
|
||||
ErrBalanceModificationTransactionCannotSetCategory = NewNormalError(NormalSubcategoryTransaction, 7, http.StatusBadRequest, "balance modification transaction cannot set category")
|
||||
ErrBalanceModificationTransactionCannotChangeAccountId = NewNormalError(NormalSubcategoryTransaction, 8, http.StatusBadRequest, "balance modification transaction cannot change account id")
|
||||
ErrBalanceModificationTransactionCannotAddWhenNotEmpty = NewNormalError(NormalSubcategoryTransaction, 9, http.StatusBadRequest, "balance modification transaction cannot add when other transaction exists")
|
||||
ErrCannotAddTransactionToHiddenAccount = NewNormalError(NormalSubcategoryTransaction, 10, http.StatusBadRequest, "cannot add transaction to hidden account")
|
||||
ErrCannotModifyTransactionInHiddenAccount = NewNormalError(NormalSubcategoryTransaction, 11, http.StatusBadRequest, "cannot modify transaction of hidden account")
|
||||
ErrCannotDeleteTransactionInHiddenAccount = NewNormalError(NormalSubcategoryTransaction, 12, http.StatusBadRequest, "cannot delete transaction in hidden account")
|
||||
ErrTransactionSourceAndDestinationIdCannotBeEqual = NewNormalError(NormalSubcategoryTransaction, 3, http.StatusBadRequest, "transaction source and destination account id cannot be equal")
|
||||
ErrTransactionSourceAndDestinationAmountNotEqual = NewNormalError(NormalSubcategoryTransaction, 4, http.StatusBadRequest, "transaction source and destination amount not equal")
|
||||
ErrTransactionDestinationAccountCannotBeSet = NewNormalError(NormalSubcategoryTransaction, 5, http.StatusBadRequest, "transaction destination account cannot be set")
|
||||
ErrTransactionDestinationAmountCannotBeSet = NewNormalError(NormalSubcategoryTransaction, 6, http.StatusBadRequest, "transaction destination amount cannot be set")
|
||||
ErrTooMuchTransactionInOneSecond = NewNormalError(NormalSubcategoryTransaction, 7, http.StatusBadRequest, "too much transaction in one second")
|
||||
ErrBalanceModificationTransactionCannotSetCategory = NewNormalError(NormalSubcategoryTransaction, 8, http.StatusBadRequest, "balance modification transaction cannot set category")
|
||||
ErrBalanceModificationTransactionCannotChangeAccountId = NewNormalError(NormalSubcategoryTransaction, 9, http.StatusBadRequest, "balance modification transaction cannot change account id")
|
||||
ErrBalanceModificationTransactionCannotAddWhenNotEmpty = NewNormalError(NormalSubcategoryTransaction, 10, http.StatusBadRequest, "balance modification transaction cannot add when other transaction exists")
|
||||
ErrCannotAddTransactionToHiddenAccount = NewNormalError(NormalSubcategoryTransaction, 11, http.StatusBadRequest, "cannot add transaction to hidden account")
|
||||
ErrCannotModifyTransactionInHiddenAccount = NewNormalError(NormalSubcategoryTransaction, 12, http.StatusBadRequest, "cannot modify transaction of hidden account")
|
||||
ErrCannotDeleteTransactionInHiddenAccount = NewNormalError(NormalSubcategoryTransaction, 13, http.StatusBadRequest, "cannot delete transaction in hidden account")
|
||||
)
|
||||
|
||||
+66
-20
@@ -13,19 +13,32 @@ const (
|
||||
TRANSACTION_TYPE_TRANSFER TransactionType = 4
|
||||
)
|
||||
|
||||
// TransactionDbType represents transaction type in database
|
||||
type TransactionDbType byte
|
||||
|
||||
// Transaction db types
|
||||
const (
|
||||
TRANSACTION_DB_TYPE_MODIFY_BALANCE TransactionDbType = 1
|
||||
TRANSACTION_DB_TYPE_INCOME TransactionDbType = 2
|
||||
TRANSACTION_DB_TYPE_EXPENSE TransactionDbType = 3
|
||||
TRANSACTION_DB_TYPE_TRANSFER_OUT TransactionDbType = 4
|
||||
TRANSACTION_DB_TYPE_TRANSFER_IN TransactionDbType = 5
|
||||
)
|
||||
|
||||
// Transaction represents transaction data stored in database
|
||||
type Transaction struct {
|
||||
TransactionId int64 `xorm:"PK"`
|
||||
Uid int64 `xorm:"UNIQUE(UQE_transaction_uid_transaction_time) INDEX(IDX_transaction_uid_deleted_transaction_time) INDEX(IDX_transaction_uid_deleted_type_time) INDEX(IDX_transaction_uid_deleted_category_id_time) NOT NULL"`
|
||||
Deleted bool `xorm:"INDEX(IDX_transaction_uid_deleted_transaction_time) INDEX(IDX_transaction_uid_deleted_type_time) INDEX(IDX_transaction_uid_deleted_category_id_time) NOT NULL"`
|
||||
Type TransactionType `xorm:"INDEX(IDX_transaction_uid_deleted_type_time) NOT NULL"`
|
||||
CategoryId int64 `xorm:"INDEX(IDX_transaction_uid_deleted_category_id_time) NOT NULL"`
|
||||
TransactionTime int64 `xorm:"UNIQUE(UQE_transaction_uid_transaction_time) INDEX(IDX_transaction_uid_deleted_transaction_time) INDEX(IDX_transaction_uid_deleted_type_time) INDEX(IDX_transaction_uid_deleted_category_id_time) NOT NULL"`
|
||||
SourceAccountId int64 `xorm:"NOT NULL"`
|
||||
DestinationAccountId int64 `xorm:"NOT NULL"`
|
||||
SourceAmount int64 `xorm:"NOT NULL"`
|
||||
DestinationAmount int64 `xorm:"NOT NULL"`
|
||||
Comment string `xorm:"VARCHAR(255) NOT NULL"`
|
||||
TransactionId int64 `xorm:"PK"`
|
||||
Uid int64 `xorm:"UNIQUE(UQE_transaction_uid_time) INDEX(IDX_transaction_uid_deleted_time) INDEX(IDX_transaction_uid_deleted_type_time) INDEX(IDX_transaction_uid_deleted_category_id_time) INDEX(IDX_transaction_uid_deleted_account_id_time) NOT NULL"`
|
||||
Deleted bool `xorm:"INDEX(IDX_transaction_uid_deleted_time) INDEX(IDX_transaction_uid_deleted_type_time) INDEX(IDX_transaction_uid_deleted_category_id_time) INDEX(IDX_transaction_uid_deleted_account_id_time) NOT NULL"`
|
||||
Type TransactionDbType `xorm:"INDEX(IDX_transaction_uid_deleted_type_time) NOT NULL"`
|
||||
CategoryId int64 `xorm:"INDEX(IDX_transaction_uid_deleted_category_id_time) NOT NULL"`
|
||||
AccountId int64 `xorm:"INDEX(IDX_transaction_uid_deleted_account_id_time) NOT NULL"`
|
||||
TransactionTime int64 `xorm:"UNIQUE(UQE_transaction_uid_time) INDEX(IDX_transaction_uid_deleted_time) INDEX(IDX_transaction_uid_deleted_type_time) INDEX(IDX_transaction_uid_deleted_category_id_time) INDEX(IDX_transaction_uid_deleted_account_id_time) NOT NULL"`
|
||||
Amount int64 `xorm:"NOT NULL"`
|
||||
RelatedId int64 `xorm:"NOT NULL"`
|
||||
RelatedAccountId int64 `xorm:"NOT NULL"`
|
||||
RelatedAccountAmount int64 `xorm:"NOT NULL"`
|
||||
Comment string `xorm:"VARCHAR(255) NOT NULL"`
|
||||
CreatedUnixTime int64
|
||||
UpdatedUnixTime int64
|
||||
DeletedUnixTime int64
|
||||
@@ -37,7 +50,7 @@ type TransactionCreateRequest struct {
|
||||
CategoryId int64 `json:"categoryId,string"`
|
||||
Time int64 `json:"time" binding:"required,min=1"`
|
||||
SourceAccountId int64 `json:"sourceAccountId,string" binding:"required,min=1"`
|
||||
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"required,min=1"`
|
||||
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
|
||||
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
|
||||
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
|
||||
TagIds []string `json:"tagIds"`
|
||||
@@ -50,7 +63,7 @@ type TransactionModifyRequest struct {
|
||||
CategoryId int64 `json:"categoryId,string"`
|
||||
Time int64 `json:"time" binding:"required,min=1"`
|
||||
SourceAccountId int64 `json:"sourceAccountId,string" binding:"required,min=1"`
|
||||
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"required,min=1"`
|
||||
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
|
||||
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
|
||||
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
|
||||
TagIds []string `json:"tagIds"`
|
||||
@@ -89,9 +102,9 @@ type TransactionInfoResponse struct {
|
||||
CategoryId int64 `json:"categoryId,string"`
|
||||
Time int64 `json:"time"`
|
||||
SourceAccountId int64 `json:"sourceAccountId,string"`
|
||||
DestinationAccountId int64 `json:"destinationAccountId,string"`
|
||||
DestinationAccountId int64 `json:"destinationAccountId,string,omitempty"`
|
||||
SourceAmount int64 `json:"sourceAmount"`
|
||||
DestinationAmount int64 `json:"destinationAmount"`
|
||||
DestinationAmount int64 `json:"destinationAmount,omitempty"`
|
||||
TagIds []string `json:"tagIds"`
|
||||
Comment string `json:"comment"`
|
||||
}
|
||||
@@ -104,16 +117,49 @@ type TransactionInfoPageWrapperResponse struct {
|
||||
|
||||
// ToTransactionInfoResponse returns a view-object according to database model
|
||||
func (c *Transaction) ToTransactionInfoResponse(tagIds []int64) *TransactionInfoResponse {
|
||||
var transactionType TransactionType
|
||||
|
||||
if c.Type == TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
transactionType = TRANSACTION_TYPE_MODIFY_BALANCE
|
||||
} else if c.Type == TRANSACTION_DB_TYPE_EXPENSE {
|
||||
transactionType = TRANSACTION_TYPE_EXPENSE
|
||||
} else if c.Type == TRANSACTION_DB_TYPE_INCOME {
|
||||
transactionType = TRANSACTION_TYPE_INCOME
|
||||
} else if c.Type == TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
transactionType = TRANSACTION_TYPE_TRANSFER
|
||||
} else if c.Type == TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
transactionType = TRANSACTION_TYPE_TRANSFER
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
sourceAccountId := c.AccountId
|
||||
sourceAmount := c.Amount
|
||||
|
||||
destinationAccountId := int64(0)
|
||||
destinationAmount := int64(0)
|
||||
|
||||
if c.Type == TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
destinationAccountId = c.RelatedAccountId
|
||||
destinationAmount = c.RelatedAccountAmount
|
||||
} else if c.Type == TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
sourceAccountId = c.RelatedAccountId
|
||||
sourceAmount = c.RelatedAccountAmount
|
||||
|
||||
destinationAccountId = c.AccountId
|
||||
destinationAmount = c.Amount
|
||||
}
|
||||
|
||||
return &TransactionInfoResponse{
|
||||
Id: c.TransactionId,
|
||||
TimeSequenceId: c.TransactionTime,
|
||||
Type: c.Type,
|
||||
Type: transactionType,
|
||||
CategoryId: c.CategoryId,
|
||||
Time: utils.GetUnixTimeFromTransactionTime(c.TransactionTime),
|
||||
SourceAccountId: c.SourceAccountId,
|
||||
DestinationAccountId: c.DestinationAccountId,
|
||||
SourceAmount: c.SourceAmount,
|
||||
DestinationAmount: c.DestinationAmount,
|
||||
SourceAccountId: sourceAccountId,
|
||||
DestinationAccountId: destinationAccountId,
|
||||
SourceAmount: sourceAmount,
|
||||
DestinationAmount: destinationAmount,
|
||||
TagIds: utils.Int64ArrayToStringArray(tagIds),
|
||||
Comment: c.Comment,
|
||||
}
|
||||
|
||||
+14
-37
@@ -140,12 +140,12 @@ func (s *AccountService) CreateAccounts(mainAccount *models.Account, childrenAcc
|
||||
TransactionId: s.GenerateUuid(uuid.UUID_TYPE_TRANSACTION),
|
||||
Uid: allAccounts[i].Uid,
|
||||
Deleted: false,
|
||||
Type: models.TRANSACTION_TYPE_MODIFY_BALANCE,
|
||||
Type: models.TRANSACTION_DB_TYPE_MODIFY_BALANCE,
|
||||
TransactionTime: transactionTime,
|
||||
SourceAccountId: allAccounts[i].AccountId,
|
||||
DestinationAccountId: allAccounts[i].AccountId,
|
||||
SourceAmount: allAccounts[i].Balance,
|
||||
DestinationAmount: allAccounts[i].Balance,
|
||||
AccountId: allAccounts[i].AccountId,
|
||||
Amount: allAccounts[i].Balance,
|
||||
RelatedAccountId: allAccounts[i].AccountId,
|
||||
RelatedAccountAmount: allAccounts[i].Balance,
|
||||
CreatedUnixTime: now,
|
||||
UpdatedUnixTime: now,
|
||||
}
|
||||
@@ -287,49 +287,26 @@ func (s *AccountService) DeleteAccount(uid int64, accountId int64) error {
|
||||
accountAndSubAccountIds[i] = accountAndSubAccounts[i].AccountId
|
||||
}
|
||||
|
||||
var relatedTransactionsBySourceAccount []*models.Transaction
|
||||
err = sess.Cols("uid", "deleted", "source_account_id", "type").Where("uid=? AND deleted=?", uid, false).In("source_account_id", accountAndSubAccountIds).Limit(len(accountAndSubAccounts) + 1).Find(&relatedTransactionsBySourceAccount)
|
||||
var relatedTransactionsByAccount []*models.Transaction
|
||||
err = sess.Cols("uid", "deleted", "account_id", "type").Where("uid=? AND deleted=?", uid, false).In("account_id", accountAndSubAccountIds).Limit(len(accountAndSubAccounts) + 1).Find(&relatedTransactionsByAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(relatedTransactionsBySourceAccount) > len(accountAndSubAccountIds) {
|
||||
} else if len(relatedTransactionsByAccount) > len(accountAndSubAccountIds) {
|
||||
return errs.ErrAccountInUseCannotBeDeleted
|
||||
} else if len(relatedTransactionsBySourceAccount) > 0 {
|
||||
} else if len(relatedTransactionsByAccount) > 0 {
|
||||
accountTransactionExists := make(map[int64]bool)
|
||||
|
||||
for i := 0; i < len(relatedTransactionsBySourceAccount); i++ {
|
||||
transaction := relatedTransactionsBySourceAccount[i]
|
||||
for i := 0; i < len(relatedTransactionsByAccount); i++ {
|
||||
transaction := relatedTransactionsByAccount[i]
|
||||
|
||||
if transaction.Type != models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
if transaction.Type != models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
return errs.ErrAccountInUseCannotBeDeleted
|
||||
} else if _, exists := accountTransactionExists[transaction.SourceAccountId]; exists {
|
||||
} else if _, exists := accountTransactionExists[transaction.AccountId]; exists {
|
||||
return errs.ErrAccountInUseCannotBeDeleted
|
||||
}
|
||||
|
||||
accountTransactionExists[transaction.SourceAccountId] = true
|
||||
}
|
||||
}
|
||||
|
||||
var relatedTransactionsByDestinationAccount []*models.Transaction
|
||||
err = sess.Cols("uid", "deleted", "destination_account_id", "type").Where("uid=? AND deleted=?", uid, false).In("destination_account_id", accountAndSubAccountIds).Limit(len(accountAndSubAccounts) + 1).Find(&relatedTransactionsByDestinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(relatedTransactionsByDestinationAccount) > len(accountAndSubAccountIds) {
|
||||
return errs.ErrAccountInUseCannotBeDeleted
|
||||
} else if len(relatedTransactionsByDestinationAccount) > 0 {
|
||||
accountTransactionExists := make(map[int64]bool)
|
||||
|
||||
for i := 0; i < len(relatedTransactionsByDestinationAccount); i++ {
|
||||
transaction := relatedTransactionsByDestinationAccount[i]
|
||||
|
||||
if transaction.Type != models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
return errs.ErrAccountInUseCannotBeDeleted
|
||||
} else if _, exists := accountTransactionExists[transaction.DestinationAccountId]; exists {
|
||||
return errs.ErrAccountInUseCannotBeDeleted
|
||||
}
|
||||
|
||||
accountTransactionExists[transaction.DestinationAccountId] = true
|
||||
accountTransactionExists[transaction.AccountId] = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+331
-155
@@ -32,7 +32,7 @@ var (
|
||||
)
|
||||
|
||||
// GetTransactionsByMaxTime returns transactions before given time
|
||||
func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, count int) ([]*models.Transaction, error) {
|
||||
func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, transactionType *models.TransactionDbType, categoryId int64, accountId int64, count int) ([]*models.Transaction, error) {
|
||||
if uid <= 0 {
|
||||
return nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
@@ -44,17 +44,44 @@ func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64,
|
||||
var transactions []*models.Transaction
|
||||
var err error
|
||||
|
||||
if maxTime > 0 {
|
||||
err = s.UserDataDB(uid).Where("uid=? AND deleted=? AND transaction_time<=?", uid, false, maxTime).Limit(count, 0).OrderBy("transaction_time desc").Find(&transactions)
|
||||
} else {
|
||||
err = s.UserDataDB(uid).Where("uid=? AND deleted=?", uid, false).Limit(count, 0).OrderBy("transaction_time desc").Find(&transactions)
|
||||
condition := "uid=? AND deleted=?"
|
||||
conditionParams := make([]interface{}, 0, 10)
|
||||
conditionParams = append(conditionParams, uid)
|
||||
conditionParams = append(conditionParams, false)
|
||||
|
||||
if transactionType != nil {
|
||||
condition = condition + " AND type=?"
|
||||
conditionParams = append(conditionParams, transactionType)
|
||||
} else if accountId == 0 {
|
||||
condition = condition + " AND (type=? OR type=? OR type=? OR type=?)"
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_MODIFY_BALANCE)
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_INCOME)
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_EXPENSE)
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
||||
}
|
||||
|
||||
if categoryId > 0 {
|
||||
condition = condition + " AND category_id=?"
|
||||
conditionParams = append(conditionParams, categoryId)
|
||||
}
|
||||
|
||||
if accountId > 0 {
|
||||
condition = condition + " AND account_id=?"
|
||||
conditionParams = append(conditionParams, accountId)
|
||||
}
|
||||
|
||||
if maxTime > 0 {
|
||||
condition = condition + " AND transaction_time<=?"
|
||||
conditionParams = append(conditionParams, maxTime)
|
||||
}
|
||||
|
||||
err = s.UserDataDB(uid).Where(condition, conditionParams...).Limit(count, 0).OrderBy("transaction_time desc").Find(&transactions)
|
||||
|
||||
return transactions, err
|
||||
}
|
||||
|
||||
// GetTransactionsInMonthByPage returns transactions in given year and month
|
||||
func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, month int, page int, count int) ([]*models.Transaction, error) {
|
||||
func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, month int, transactionType *models.TransactionDbType, categoryId int64, accountId int64, page int, count int) ([]*models.Transaction, error) {
|
||||
if uid <= 0 {
|
||||
return nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
@@ -79,7 +106,36 @@ func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, m
|
||||
endUnixTime := endTime.Unix()
|
||||
|
||||
var transactions []*models.Transaction
|
||||
err = s.UserDataDB(uid).Where("uid=? AND deleted=? AND transaction_time>=? AND transaction_time<?", uid, false, startUnixTime, endUnixTime).Limit(count, count*(page-1)).OrderBy("transaction_time desc").Find(&transactions)
|
||||
|
||||
condition := "uid=? AND deleted=? AND transaction_time>=? AND transaction_time<?"
|
||||
conditionParams := make([]interface{}, 0, 12)
|
||||
conditionParams = append(conditionParams, uid)
|
||||
conditionParams = append(conditionParams, false)
|
||||
conditionParams = append(conditionParams, startUnixTime)
|
||||
conditionParams = append(conditionParams, endUnixTime)
|
||||
|
||||
if transactionType != nil {
|
||||
condition = condition + " AND type=?"
|
||||
conditionParams = append(conditionParams, transactionType)
|
||||
} else if accountId == 0 {
|
||||
condition = condition + " AND (type=? OR type=? OR type=? OR type=?)"
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_MODIFY_BALANCE)
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_INCOME)
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_EXPENSE)
|
||||
conditionParams = append(conditionParams, models.TRANSACTION_DB_TYPE_TRANSFER_OUT)
|
||||
}
|
||||
|
||||
if categoryId > 0 {
|
||||
condition = condition + " AND category_id=?"
|
||||
conditionParams = append(conditionParams, categoryId)
|
||||
}
|
||||
|
||||
if accountId > 0 {
|
||||
condition = condition + " AND account_id=?"
|
||||
conditionParams = append(conditionParams, accountId)
|
||||
}
|
||||
|
||||
err = s.UserDataDB(uid).Where(condition, conditionParams...).Limit(count, count*(page-1)).OrderBy("transaction_time desc").Find(&transactions)
|
||||
|
||||
return transactions, err
|
||||
}
|
||||
@@ -177,11 +233,12 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction,
|
||||
return err
|
||||
}
|
||||
|
||||
if sourceAccount.Hidden || destinationAccount.Hidden {
|
||||
if sourceAccount.Hidden || (destinationAccount != nil && destinationAccount.Hidden) {
|
||||
return errs.ErrCannotAddTransactionToHiddenAccount
|
||||
}
|
||||
|
||||
if sourceAccount.Currency == destinationAccount.Currency && transaction.SourceAmount != transaction.DestinationAmount {
|
||||
if (transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN) &&
|
||||
sourceAccount.Currency == destinationAccount.Currency && transaction.Amount != transaction.RelatedAccountAmount {
|
||||
return errs.ErrTransactionSourceAndDestinationAmountNotEqual
|
||||
}
|
||||
|
||||
@@ -200,8 +257,8 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction,
|
||||
}
|
||||
|
||||
// Verify balance modification transaction and calculate real amount
|
||||
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
otherTransactionExists, err := sess.Cols("uid", "deleted", "destination_account_id").Where("uid=? AND deleted=? AND destination_account_id=?", transaction.Uid, false, destinationAccount.AccountId).Limit(1).Exist(&models.Transaction{})
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
otherTransactionExists, err := sess.Cols("uid", "deleted", "account_id").Where("uid=? AND deleted=? AND account_id=?", transaction.Uid, false, sourceAccount.AccountId).Limit(1).Exist(&models.Transaction{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -209,10 +266,18 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction,
|
||||
return errs.ErrBalanceModificationTransactionCannotAddWhenNotEmpty
|
||||
}
|
||||
|
||||
transaction.DestinationAmount = transaction.SourceAmount - destinationAccount.Balance
|
||||
transaction.RelatedAccountId = transaction.TransactionId
|
||||
transaction.RelatedAccountAmount = transaction.Amount - sourceAccount.Balance
|
||||
}
|
||||
|
||||
// Insert transaction row
|
||||
var relatedTransaction *models.Transaction
|
||||
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
relatedTransaction = s.GetRelatedTransferTransaction(transaction, s.GenerateUuid(uuid.UUID_TYPE_TRANSACTION))
|
||||
transaction.RelatedId = relatedTransaction.TransactionId
|
||||
}
|
||||
|
||||
createdRows, err := sess.Insert(transaction)
|
||||
|
||||
if err != nil || createdRows < 1 { // maybe another transaction has same time
|
||||
@@ -240,6 +305,22 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction,
|
||||
}
|
||||
}
|
||||
|
||||
if relatedTransaction != nil {
|
||||
relatedTransaction.TransactionTime = transaction.TransactionTime + 1
|
||||
|
||||
if utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime) != utils.GetUnixTimeFromTransactionTime(relatedTransaction.TransactionTime) {
|
||||
return errs.ErrTooMuchTransactionInOneSecond
|
||||
}
|
||||
|
||||
createdRows, err := sess.Insert(relatedTransaction)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if createdRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
}
|
||||
|
||||
err = nil
|
||||
|
||||
// Insert transaction tag index
|
||||
@@ -255,36 +336,36 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction,
|
||||
}
|
||||
|
||||
// Update account table
|
||||
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", transaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_TYPE_INCOME {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", transaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_TYPE_EXPENSE {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", transaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_TYPE_TRANSFER {
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedSourceRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", transaction.SourceAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", transaction.RelatedAccountAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_INCOME {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", transaction.Amount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_EXPENSE {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", transaction.Amount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedSourceRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", transaction.Amount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -293,13 +374,15 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction,
|
||||
}
|
||||
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedDestinationRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", transaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
updatedDestinationRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", transaction.RelatedAccountAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedDestinationRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
return errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -348,6 +431,10 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
|
||||
transaction.Type = oldTransaction.Type
|
||||
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
transaction.RelatedId = oldTransaction.RelatedId
|
||||
}
|
||||
|
||||
// Check whether account id is valid
|
||||
err = s.isAccountIdValid(transaction)
|
||||
|
||||
@@ -362,11 +449,12 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
return err
|
||||
}
|
||||
|
||||
if sourceAccount.Hidden || destinationAccount.Hidden {
|
||||
if sourceAccount.Hidden || (destinationAccount != nil && destinationAccount.Hidden) {
|
||||
return errs.ErrCannotModifyTransactionInHiddenAccount
|
||||
}
|
||||
|
||||
if sourceAccount.Currency == destinationAccount.Currency && transaction.SourceAmount != transaction.DestinationAmount {
|
||||
if (transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN) &&
|
||||
sourceAccount.Currency == destinationAccount.Currency && transaction.Amount != transaction.RelatedAccountAmount {
|
||||
return errs.ErrTransactionSourceAndDestinationAmountNotEqual
|
||||
}
|
||||
|
||||
@@ -376,7 +464,7 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
return err
|
||||
}
|
||||
|
||||
if oldSourceAccount.Hidden || oldDestinationAccount.Hidden {
|
||||
if oldSourceAccount.Hidden || (oldDestinationAccount != nil && oldDestinationAccount.Hidden) {
|
||||
return errs.ErrCannotAddTransactionToHiddenAccount
|
||||
}
|
||||
|
||||
@@ -412,25 +500,28 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
updateCols = append(updateCols, "transaction_time")
|
||||
}
|
||||
|
||||
if transaction.SourceAccountId != oldTransaction.SourceAccountId {
|
||||
updateCols = append(updateCols, "source_account_id")
|
||||
if transaction.AccountId != oldTransaction.AccountId {
|
||||
updateCols = append(updateCols, "account_id")
|
||||
}
|
||||
|
||||
if transaction.DestinationAccountId != oldTransaction.DestinationAccountId {
|
||||
updateCols = append(updateCols, "destination_account_id")
|
||||
}
|
||||
|
||||
if transaction.SourceAmount != oldTransaction.SourceAmount {
|
||||
if oldTransaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
originalBalance := sourceAccount.Balance - oldTransaction.DestinationAmount
|
||||
transaction.DestinationAmount = transaction.SourceAmount - originalBalance
|
||||
if transaction.Amount != oldTransaction.Amount {
|
||||
if oldTransaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
originalBalance := sourceAccount.Balance - oldTransaction.RelatedAccountAmount
|
||||
transaction.RelatedAccountAmount = transaction.Amount - originalBalance
|
||||
updateCols = append(updateCols, "related_account_amount")
|
||||
}
|
||||
|
||||
updateCols = append(updateCols, "source_amount")
|
||||
updateCols = append(updateCols, "amount")
|
||||
}
|
||||
|
||||
if transaction.DestinationAmount != oldTransaction.DestinationAmount {
|
||||
updateCols = append(updateCols, "destination_amount")
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
if transaction.RelatedAccountId != oldTransaction.RelatedAccountId {
|
||||
updateCols = append(updateCols, "related_account_id")
|
||||
}
|
||||
|
||||
if transaction.RelatedAccountAmount != oldTransaction.RelatedAccountAmount {
|
||||
updateCols = append(updateCols, "related_account_amount")
|
||||
}
|
||||
}
|
||||
|
||||
if transaction.Comment != oldTransaction.Comment {
|
||||
@@ -453,6 +544,22 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
return errs.ErrTransactionNotFound
|
||||
}
|
||||
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
relatedTransaction := s.GetRelatedTransferTransaction(transaction, transaction.RelatedId)
|
||||
|
||||
if utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime) != utils.GetUnixTimeFromTransactionTime(relatedTransaction.TransactionTime) {
|
||||
return errs.ErrTooMuchTransactionInOneSecond
|
||||
}
|
||||
|
||||
updatedRows, err := sess.ID(relatedTransaction.TransactionId).Cols(updateCols...).Where("uid=? AND deleted=?", relatedTransaction.Uid, false).Update(relatedTransaction)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
}
|
||||
|
||||
// Update transaction tag index
|
||||
if len(removeTagIds) > 0 {
|
||||
deletedRows, err := sess.Where("uid=?", transaction.Uid).In("tag_id", removeTagIds).Delete(&models.TransactionTagIndex{})
|
||||
@@ -476,14 +583,14 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
}
|
||||
|
||||
// Update account table
|
||||
if oldTransaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
if transaction.DestinationAccountId != oldTransaction.DestinationAccountId {
|
||||
if oldTransaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
if transaction.AccountId != oldTransaction.AccountId {
|
||||
return errs.ErrBalanceModificationTransactionCannotChangeAccountId
|
||||
}
|
||||
|
||||
if transaction.DestinationAmount != oldTransaction.DestinationAmount {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)+(%d)", oldTransaction.DestinationAmount, transaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
if transaction.RelatedAccountAmount != oldTransaction.RelatedAccountAmount {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)+(%d)", oldTransaction.RelatedAccountAmount, transaction.RelatedAccountAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -491,19 +598,19 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_TYPE_INCOME {
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_INCOME {
|
||||
var oldAccountNewAmount int64 = 0
|
||||
var newAccountNewAmount int64 = 0
|
||||
|
||||
if transaction.DestinationAccountId == oldTransaction.DestinationAccountId {
|
||||
oldAccountNewAmount = transaction.DestinationAmount
|
||||
} else if transaction.DestinationAccountId != oldTransaction.DestinationAccountId {
|
||||
newAccountNewAmount = transaction.DestinationAmount
|
||||
if transaction.AccountId == oldTransaction.AccountId {
|
||||
oldAccountNewAmount = transaction.Amount
|
||||
} else if transaction.AccountId != oldTransaction.AccountId {
|
||||
newAccountNewAmount = transaction.Amount
|
||||
}
|
||||
|
||||
if oldAccountNewAmount != oldTransaction.DestinationAmount {
|
||||
oldDestinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(oldDestinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)+(%d)", oldTransaction.DestinationAmount, oldAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldDestinationAccount.Uid, false).Update(oldDestinationAccount)
|
||||
if oldAccountNewAmount != oldTransaction.Amount {
|
||||
oldSourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(oldSourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)+(%d)", oldTransaction.Amount, oldAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldSourceAccount.Uid, false).Update(oldSourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -513,8 +620,8 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
}
|
||||
|
||||
if newAccountNewAmount != 0 {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", newAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", newAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -522,19 +629,19 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_TYPE_EXPENSE {
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_EXPENSE {
|
||||
var oldAccountNewAmount int64 = 0
|
||||
var newAccountNewAmount int64 = 0
|
||||
|
||||
if transaction.DestinationAccountId == oldTransaction.DestinationAccountId {
|
||||
oldAccountNewAmount = transaction.DestinationAmount
|
||||
} else if transaction.DestinationAccountId != oldTransaction.DestinationAccountId {
|
||||
newAccountNewAmount = transaction.DestinationAmount
|
||||
if transaction.AccountId == oldTransaction.AccountId {
|
||||
oldAccountNewAmount = transaction.Amount
|
||||
} else if transaction.AccountId != oldTransaction.AccountId {
|
||||
newAccountNewAmount = transaction.Amount
|
||||
}
|
||||
|
||||
if oldAccountNewAmount != oldTransaction.DestinationAmount {
|
||||
oldDestinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(oldDestinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)-(%d)", oldTransaction.DestinationAmount, oldAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldDestinationAccount.Uid, false).Update(oldDestinationAccount)
|
||||
if oldAccountNewAmount != oldTransaction.Amount {
|
||||
oldSourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(oldSourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)-(%d)", oldTransaction.Amount, oldAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldSourceAccount.Uid, false).Update(oldSourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -544,8 +651,8 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
}
|
||||
|
||||
if newAccountNewAmount != 0 {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", newAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", newAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -553,19 +660,19 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_TYPE_TRANSFER {
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
var oldSourceAccountNewAmount int64 = 0
|
||||
var newSourceAccountNewAmount int64 = 0
|
||||
|
||||
if transaction.SourceAccountId == oldTransaction.SourceAccountId {
|
||||
oldSourceAccountNewAmount = transaction.SourceAmount
|
||||
} else if transaction.SourceAccountId != oldTransaction.SourceAccountId {
|
||||
newSourceAccountNewAmount = transaction.SourceAmount
|
||||
if transaction.AccountId == oldTransaction.AccountId {
|
||||
oldSourceAccountNewAmount = transaction.Amount
|
||||
} else if transaction.AccountId != oldTransaction.AccountId {
|
||||
newSourceAccountNewAmount = transaction.Amount
|
||||
}
|
||||
|
||||
if oldSourceAccountNewAmount != oldTransaction.SourceAmount {
|
||||
if oldSourceAccountNewAmount != oldTransaction.Amount {
|
||||
oldSourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(oldSourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)-(%d)", oldTransaction.SourceAmount, oldSourceAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldSourceAccount.Uid, false).Update(oldSourceAccount)
|
||||
updatedRows, err := sess.ID(oldSourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)-(%d)", oldTransaction.Amount, oldSourceAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldSourceAccount.Uid, false).Update(oldSourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -588,15 +695,15 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
var oldDestinationAccountNewAmount int64 = 0
|
||||
var newDestinationAccountNewAmount int64 = 0
|
||||
|
||||
if transaction.DestinationAccountId == oldTransaction.DestinationAccountId {
|
||||
oldDestinationAccountNewAmount = transaction.DestinationAmount
|
||||
} else if transaction.DestinationAccountId != oldTransaction.DestinationAccountId {
|
||||
newDestinationAccountNewAmount = transaction.DestinationAmount
|
||||
if transaction.RelatedAccountId == oldTransaction.RelatedAccountId {
|
||||
oldDestinationAccountNewAmount = transaction.RelatedAccountAmount
|
||||
} else if transaction.RelatedAccountId != oldTransaction.RelatedAccountId {
|
||||
newDestinationAccountNewAmount = transaction.RelatedAccountAmount
|
||||
}
|
||||
|
||||
if oldDestinationAccountNewAmount != oldTransaction.DestinationAmount {
|
||||
if oldDestinationAccountNewAmount != oldTransaction.RelatedAccountAmount {
|
||||
oldDestinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(oldDestinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)+(%d)", oldTransaction.DestinationAmount, oldDestinationAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldDestinationAccount.Uid, false).Update(oldDestinationAccount)
|
||||
updatedRows, err := sess.ID(oldDestinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)+(%d)", oldTransaction.RelatedAccountAmount, oldDestinationAccountNewAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", oldDestinationAccount.Uid, false).Update(oldDestinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -615,6 +722,8 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction,
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
return errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -658,12 +767,12 @@ func (s *TransactionService) DeleteTransaction(uid int64, transactionId int64) e
|
||||
return err
|
||||
}
|
||||
|
||||
if sourceAccount.Hidden || destinationAccount.Hidden {
|
||||
if sourceAccount.Hidden || (destinationAccount != nil && destinationAccount.Hidden) {
|
||||
return errs.ErrCannotDeleteTransactionInHiddenAccount
|
||||
}
|
||||
|
||||
// Update transaction row to deleted
|
||||
deletedRows, err := sess.ID(transactionId).Cols("deleted", "deleted_unix_time").Where("uid=? AND deleted=?", uid, false).Update(updateModel)
|
||||
deletedRows, err := sess.ID(oldTransaction.TransactionId).Cols("deleted", "deleted_unix_time").Where("uid=? AND deleted=?", uid, false).Update(updateModel)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -671,37 +780,47 @@ func (s *TransactionService) DeleteTransaction(uid int64, transactionId int64) e
|
||||
return errs.ErrTransactionNotFound
|
||||
}
|
||||
|
||||
if oldTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || oldTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
deletedRows, err = sess.ID(oldTransaction.RelatedId).Cols("deleted", "deleted_unix_time").Where("uid=? AND deleted=?", uid, false).Update(updateModel)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if deletedRows < 1 {
|
||||
return errs.ErrTransactionNotFound
|
||||
}
|
||||
}
|
||||
|
||||
// Update account table
|
||||
if oldTransaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", oldTransaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_TYPE_INCOME {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", oldTransaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_TYPE_EXPENSE {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", oldTransaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_TYPE_TRANSFER {
|
||||
if oldTransaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedSourceRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", oldTransaction.SourceAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", oldTransaction.RelatedAccountAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_INCOME {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", oldTransaction.Amount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_EXPENSE {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", oldTransaction.Amount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
sourceAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedSourceRows, err := sess.ID(sourceAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance+(%d)", oldTransaction.Amount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", sourceAccount.Uid, false).Update(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -710,32 +829,74 @@ func (s *TransactionService) DeleteTransaction(uid int64, transactionId int64) e
|
||||
}
|
||||
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
updatedDestinationRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", oldTransaction.DestinationAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
updatedDestinationRows, err := sess.ID(destinationAccount.AccountId).SetExpr("balance", fmt.Sprintf("balance-(%d)", oldTransaction.RelatedAccountAmount)).Cols("updated_unix_time").Where("uid=? AND deleted=?", destinationAccount.Uid, false).Update(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if updatedDestinationRows < 1 {
|
||||
return errs.ErrDatabaseOperationFailed
|
||||
}
|
||||
} else if oldTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
return errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (s *TransactionService) GetRelatedTransferTransaction(originalTransaction *models.Transaction, relatedTransactionId int64) *models.Transaction {
|
||||
var relatedType models.TransactionDbType
|
||||
var relatedTransactionTime int64
|
||||
|
||||
if originalTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
relatedType = models.TRANSACTION_DB_TYPE_TRANSFER_IN
|
||||
relatedTransactionTime = originalTransaction.TransactionTime + 1
|
||||
} else if originalTransaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
relatedType = models.TRANSACTION_DB_TYPE_TRANSFER_OUT
|
||||
relatedTransactionTime = originalTransaction.TransactionTime - 1
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
relatedTransaction := &models.Transaction{
|
||||
TransactionId: relatedTransactionId,
|
||||
Uid: originalTransaction.Uid,
|
||||
Deleted: originalTransaction.Deleted,
|
||||
Type: relatedType,
|
||||
CategoryId: originalTransaction.CategoryId,
|
||||
TransactionTime: relatedTransactionTime,
|
||||
AccountId: originalTransaction.RelatedAccountId,
|
||||
Amount: originalTransaction.RelatedAccountAmount,
|
||||
RelatedId: originalTransaction.TransactionId,
|
||||
RelatedAccountId: originalTransaction.AccountId,
|
||||
RelatedAccountAmount: originalTransaction.Amount,
|
||||
Comment: originalTransaction.Comment,
|
||||
CreatedUnixTime: originalTransaction.CreatedUnixTime,
|
||||
UpdatedUnixTime: originalTransaction.UpdatedUnixTime,
|
||||
DeletedUnixTime: originalTransaction.DeletedUnixTime,
|
||||
}
|
||||
|
||||
return relatedTransaction
|
||||
}
|
||||
|
||||
func (s *TransactionService) isAccountIdValid(transaction *models.Transaction) error {
|
||||
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE ||
|
||||
transaction.Type == models.TRANSACTION_TYPE_INCOME ||
|
||||
transaction.Type == models.TRANSACTION_TYPE_EXPENSE {
|
||||
if transaction.SourceAccountId != transaction.DestinationAccountId {
|
||||
return errs.ErrTransactionSourceAndDestinationIdNotEqual
|
||||
} else if transaction.SourceAmount != transaction.DestinationAmount {
|
||||
return errs.ErrTransactionSourceAndDestinationAmountNotEqual
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
if transaction.RelatedAccountId != 0 && transaction.RelatedAccountId != transaction.AccountId {
|
||||
return errs.ErrTransactionDestinationAccountCannotBeSet
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_TYPE_TRANSFER {
|
||||
if transaction.SourceAccountId == transaction.DestinationAccountId {
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_INCOME ||
|
||||
transaction.Type == models.TRANSACTION_DB_TYPE_EXPENSE {
|
||||
if transaction.RelatedAccountId != 0 {
|
||||
return errs.ErrTransactionDestinationAccountCannotBeSet
|
||||
} else if transaction.RelatedAccountAmount != 0 {
|
||||
return errs.ErrTransactionDestinationAmountCannotBeSet
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||
if transaction.AccountId == transaction.RelatedAccountId {
|
||||
return errs.ErrTransactionSourceAndDestinationIdCannotBeEqual
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
return errs.ErrTransactionTypeInvalid
|
||||
} else {
|
||||
return errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
@@ -747,7 +908,7 @@ func (s *TransactionService) getAccountModels(sess *xorm.Session, transaction *m
|
||||
sourceAccount = &models.Account{}
|
||||
destinationAccount = &models.Account{}
|
||||
|
||||
has, err := sess.ID(transaction.SourceAccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(sourceAccount)
|
||||
has, err := sess.ID(transaction.AccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(sourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -755,17 +916,32 @@ func (s *TransactionService) getAccountModels(sess *xorm.Session, transaction *m
|
||||
return nil, nil, errs.ErrSourceAccountNotFound
|
||||
}
|
||||
|
||||
if transaction.DestinationAccountId == transaction.SourceAccountId {
|
||||
destinationAccount = sourceAccount
|
||||
} else {
|
||||
has, err = sess.ID(transaction.DestinationAccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(destinationAccount)
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
if transaction.RelatedAccountId != 0 && transaction.RelatedAccountId != transaction.AccountId {
|
||||
return nil, nil, errs.ErrAccountIdInvalid
|
||||
} else {
|
||||
destinationAccount = sourceAccount
|
||||
}
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_INCOME || transaction.Type == models.TRANSACTION_DB_TYPE_EXPENSE {
|
||||
if transaction.RelatedAccountId != 0 {
|
||||
return nil, nil, errs.ErrAccountIdInvalid
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
} else if !has {
|
||||
return nil, nil, errs.ErrDestinationAccountNotFound
|
||||
destinationAccount = nil
|
||||
} else if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN {
|
||||
if transaction.RelatedAccountId <= 0 {
|
||||
return nil, nil, errs.ErrAccountIdInvalid
|
||||
} else {
|
||||
has, err = sess.ID(transaction.RelatedAccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(destinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
} else if !has {
|
||||
return nil, nil, errs.ErrDestinationAccountNotFound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sourceAccount, destinationAccount, nil
|
||||
}
|
||||
|
||||
@@ -773,10 +949,10 @@ func (s *TransactionService) getOldAccountModels(sess *xorm.Session, transaction
|
||||
oldSourceAccount = &models.Account{}
|
||||
oldDestinationAccount = &models.Account{}
|
||||
|
||||
if transaction.SourceAccountId == oldTransaction.SourceAccountId {
|
||||
if transaction.AccountId == oldTransaction.AccountId {
|
||||
oldSourceAccount = sourceAccount
|
||||
} else {
|
||||
has, err := sess.ID(oldTransaction.SourceAccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(oldSourceAccount)
|
||||
has, err := sess.ID(oldTransaction.AccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(oldSourceAccount)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -785,10 +961,10 @@ func (s *TransactionService) getOldAccountModels(sess *xorm.Session, transaction
|
||||
}
|
||||
}
|
||||
|
||||
if transaction.DestinationAccountId == oldTransaction.DestinationAccountId {
|
||||
if transaction.RelatedAccountId == oldTransaction.RelatedAccountId {
|
||||
oldDestinationAccount = destinationAccount
|
||||
} else {
|
||||
has, err := sess.ID(oldTransaction.DestinationAccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(oldDestinationAccount)
|
||||
has, err := sess.ID(oldTransaction.RelatedAccountId).Where("uid=? AND deleted=?", transaction.Uid, false).Get(oldDestinationAccount)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -800,8 +976,8 @@ func (s *TransactionService) getOldAccountModels(sess *xorm.Session, transaction
|
||||
}
|
||||
|
||||
func (s *TransactionService) isCategoryValid(sess *xorm.Session, transaction *models.Transaction) error {
|
||||
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
if transaction.CategoryId > 0 {
|
||||
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
|
||||
if transaction.CategoryId != 0 {
|
||||
return errs.ErrBalanceModificationTransactionCannotSetCategory
|
||||
}
|
||||
} else {
|
||||
@@ -818,9 +994,9 @@ func (s *TransactionService) isCategoryValid(sess *xorm.Session, transaction *mo
|
||||
return errs.ErrCannotUsePrimaryCategoryForTransaction
|
||||
}
|
||||
|
||||
if (transaction.Type == models.TRANSACTION_TYPE_INCOME && category.Type != models.CATEGORY_TYPE_INCOME) ||
|
||||
(transaction.Type == models.TRANSACTION_TYPE_EXPENSE && category.Type != models.CATEGORY_TYPE_EXPENSE) ||
|
||||
(transaction.Type == models.TRANSACTION_TYPE_TRANSFER && category.Type != models.CATEGORY_TYPE_TRANSFER) {
|
||||
if (transaction.Type == models.TRANSACTION_DB_TYPE_INCOME && category.Type != models.CATEGORY_TYPE_INCOME) ||
|
||||
(transaction.Type == models.TRANSACTION_DB_TYPE_EXPENSE && category.Type != models.CATEGORY_TYPE_EXPENSE) ||
|
||||
((transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT || transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_IN) && category.Type != models.CATEGORY_TYPE_TRANSFER) {
|
||||
return errs.ErrTransactionCategoryTypeInvalid
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -337,9 +337,10 @@ export default {
|
||||
'transaction id is invalid': 'Transaction ID is invalid',
|
||||
'transaction not found': 'Transaction is not found',
|
||||
'transaction type is invalid': 'Transaction type is invalid',
|
||||
'transaction source and destination account id not equal': 'Source account ID and destination account ID do not equal',
|
||||
'transaction source and destination account id cannot be equal': 'Source account ID and destination account ID cannot be equal',
|
||||
'transaction source and destination amount not equal': 'Source amount and destination source do not equal',
|
||||
'transaction destination account cannot be set': 'Cannot set destination account',
|
||||
'transaction destination amount cannot be set': 'Cannot set destination amount',
|
||||
'too much transaction in one second': 'There are too much transaction in one second, please choose another time',
|
||||
'balance modification transaction cannot set category': 'You cannot set category for balance modification transaction',
|
||||
'balance modification transaction cannot change account id': 'You cannot change account ID for balance modification transaction',
|
||||
|
||||
@@ -335,11 +335,12 @@ export default {
|
||||
'destination account not found': '目标账户不存在',
|
||||
'account is in use and cannot be deleted': '账户正在被使用,无法删除',
|
||||
'transaction id is invalid': '交易ID无效',
|
||||
'transaction not found': '交易不存',
|
||||
'transaction not found': '交易不存在',
|
||||
'transaction type is invalid': '交易类型无效',
|
||||
'transaction source and destination account id not equal': '来源账户和目标账户不一致',
|
||||
'transaction source and destination account id cannot be equal': '来源账户和目标账户不能相同',
|
||||
'transaction source and destination amount not equal': '源金额和目标金额不一致',
|
||||
'transaction destination account cannot be set': '不能设置目标账户',
|
||||
'transaction destination amount cannot be set': '不能设置目标金额',
|
||||
'too much transaction in one second': '一秒钟内交易太多,请选择其他时间',
|
||||
'balance modification transaction cannot set category': '您无法对修改余额的交易设置分类',
|
||||
'balance modification transaction cannot change account id': '您无法对修改余额的交易修改账户ID',
|
||||
|
||||
@@ -532,9 +532,9 @@ export default {
|
||||
type: self.transaction.type,
|
||||
time: self.transaction.unixTime,
|
||||
sourceAccountId: self.transaction.sourceAccountId,
|
||||
destinationAccountId: self.transaction.sourceAccountId,
|
||||
sourceAmount: self.transaction.sourceAmount,
|
||||
destinationAmount: self.transaction.sourceAmount,
|
||||
destinationAccountId: '0',
|
||||
destinationAmount: 0,
|
||||
tagIds: self.transaction.tagIds,
|
||||
comment: self.transaction.comment
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user