diff --git a/handlers/payment.go b/handlers/payment.go index e3a9f3b..7e9c3fb 100644 --- a/handlers/payment.go +++ b/handlers/payment.go @@ -109,7 +109,9 @@ func PaymentAdd(c *gin.Context) { return } deletableIfRollback = append(deletableIfRollback, payment) + var substractFromCard uint64 = 0 for _, uItemBought := range updates.Items { + var totalCost uint64 = 0 // Creating item and adding it to rollback if itemID is set to 0 if uItemBought.ItemID == 0 { newItem := &db.Item{ @@ -133,12 +135,13 @@ func PaymentAdd(c *gin.Context) { return } deletableIfRollback = append(deletableIfRollback, newItem) + totalCost = newItem.Price * uint64(uItemBought.Quantity) newItemBought := &db.ItemBought{ ItemID: newItem.ID, PaymentID: payment.ID, TypeID: uItemBought.TypeID, Quantity: uItemBought.Quantity, - TotalCost: newItem.Price * uint64(uItemBought.Quantity), + TotalCost: totalCost, MetricType: uItemBought.MetricType, MetricValue: uItemBought.MetricValue, } @@ -155,8 +158,73 @@ func PaymentAdd(c *gin.Context) { deletableIfRollback = append(deletableIfRollback, newItemBought) newItemBought.Item = newItem } else { - // TODO: check if Item has same userID and potentially update Item + dbItem := &db.Item{} + if err := dbc.Find(dbItem, uItemBought.ItemID).Error; err != nil { + c.JSON(500, types.ErrorResponse{Message: err.Error()}) + weNeedRollback = true + return + } + if dbItem.UserID != userID { + c.JSON(500, types.ErrorResponse{Message: "ItemID is not your"}) + weNeedRollback = true + return + } + if dbItem.Price != uItemBought.Price { + dbItem.Price = uItemBought.Price + if err := dbc.Save(dbItem).Error; err != nil { + c.JSON(500, types.ErrorResponse{Message: err.Error()}) + weNeedRollback = true + return + } + } + totalCost = dbItem.Price * uint64(uItemBought.Quantity) + newItemBought := &db.ItemBought{ + ItemID: dbItem.ID, + PaymentID: payment.ID, + TypeID: uItemBought.TypeID, + Quantity: uItemBought.Quantity, + TotalCost: totalCost, + MetricType: uItemBought.MetricType, + MetricValue: uItemBought.MetricValue, + } + if err := dbc.Create(newItemBought).Error; err != nil { + c.JSON(500, types.ErrorResponse{Message: err.Error()}) + weNeedRollback = true + return + } + if newItemBought.ID == 0 { + c.JSON(500, types.ErrorResponse{Message: "Internal error: ERR.P.A.4"}) + weNeedRollback = true + return + } + deletableIfRollback = append(deletableIfRollback, newItemBought) + newItemBought.Item = dbItem } + // As totalCost is calculated either way AND db.Item.BeforeSave have db.Item.Price check + // we can gently assume that totalCost != 0 + substractFromCard += totalCost + } + + // Checks for db.Card.UserID != db.Payment.UserID for payment is done in db.Payment hooks + card := &db.Card{} + if err := dbc.Find(card, payment.CardID).Error; err != nil { + c.JSON(500, types.ErrorResponse{Message: err.Error()}) + weNeedRollback = true + return + } + // TODO: Examine if that would be better to calculate substractFromCard + // BEFORE update.Items loop and therefore this check can be done before + // processing payment's ItemBought entities + if card.Balance < substractFromCard { + c.JSON(500, types.ErrorResponse{Message: fmt.Sprintf("Card %s (%s) has Balance lower than overall Payment cost. Rollback.", card.Name, card.LastDigits)}) + weNeedRollback = true + return + } + card.Balance -= substractFromCard + if err := dbc.Save(card).Error; err != nil { + c.JSON(500, types.ErrorResponse{Message: err.Error()}) + weNeedRollback = true + return } c.JSON(200, types.Message{Info: fmt.Sprintf("Entity with %d ID is created successfully!", payment.ID)})