diff --git a/db/income.go b/db/income.go index e961bab..9238fa5 100644 --- a/db/income.go +++ b/db/income.go @@ -1,6 +1,7 @@ package db import ( + "errors" "time" "gorm.io/gorm" @@ -16,3 +17,93 @@ type Income struct { UserID uint User *User } + +// Implements db.UserIdentifiable:1 +func (e Income) GetID() uint { + return e.ID +} + +// Implements db.UserIdentifiable:2 +func (e Income) GetUserID() uint { + return e.UserID +} + +// Implements db.UserIdentifiable:3 +func (e *Income) SetUserID(id uint) { + e.UserID = id +} + +var ( + ERROR_INCOME_INVALID_USERID = errors.New("Income's `UserID` and Card's `UserID` are not equal") + ERROR_INCOME_CARD_INSUFFICIENT_BALANCE = errors.New("Card's `Balance` is lower than Income's Value") + ERROR_INCOME_INVALID_TYPE_USERID = errors.New("Income's `UserID` and Type's `UserID` are not equal") +) + +func (i *Income) BeforeCreate(tx *gorm.DB) error { + card := &Card{} + if err := tx.Find(card, i.CardID).Error; err != nil { + return err + } + if card.UserID != i.UserID { + return ERROR_INCOME_INVALID_USERID + } + card.Balance += i.Value + if err := tx.Save(card).Error; err != nil { + return err + } + + return nil +} + +func (i *Income) BeforeUpdate(tx *gorm.DB) (err error) { + var original Income + if err := tx.Model(&Income{}).Select("card_id", "value").Where("id = ?", i.ID).First(&original).Error; err != nil { + return err + } + if original.CardID != 0 { + oldCard := &Card{} + if err := tx.Find(oldCard, original.CardID).Error; err != nil { + return err + } + if oldCard.UserID != i.UserID { + return ERROR_INCOME_INVALID_USERID + } + if oldCard.Balance < original.Value { + return ERROR_INCOME_CARD_INSUFFICIENT_BALANCE + } + oldCard.Balance -= original.Value + if err := tx.Save(oldCard).Error; err != nil { + return err + } + } + + if i.CardID != 0 { + newCard := &Card{} + if err := tx.Find(newCard, i.CardID).Error; err != nil { + return err + } + if newCard.UserID != i.UserID { + return ERROR_INCOME_INVALID_USERID + } + newCard.Balance += i.Value + if err := tx.Save(newCard).Error; err != nil { + return err + } + } + return nil +} + +func (e *Income) AfterDelete(tx *gorm.DB) (err error) { + card := &Card{} + if err := tx.Find(card, e.CardID).Error; err != nil { + return err + } + if card.UserID != e.UserID { + return ERROR_INCOME_INVALID_USERID + } + card.Balance -= e.Value + if err := tx.Save(card).Error; err != nil { + return err + } + return nil +}