fin-check-api/handlers/payment.go

147 lines
4.2 KiB
Go
Raw Permalink Normal View History

2024-11-20 17:19:57 +01:00
package handlers
import (
"fmt"
"log"
"git.qowevisa.me/Qowevisa/fin-check-api/db"
"git.qowevisa.me/Qowevisa/fin-check-api/types"
"github.com/gin-gonic/gin"
)
var itemBoughtTransform func(inp *db.ItemBought) types.ItemBought = func(inp *db.ItemBought) types.ItemBought {
return types.ItemBought{}
}
var paymentTransform func(inp *db.Payment) types.Payment = func(inp *db.Payment) types.Payment {
var items []types.ItemBought
for _, item := range inp.Items {
items = append(items, itemBoughtTransform(&item))
}
return types.Payment{
ID: inp.ID,
CardID: inp.CardID,
CategoryID: inp.CategoryID,
Title: inp.Title,
Description: inp.Descr,
Note: inp.Note,
Date: inp.Date,
Items: items,
}
}
// @Summary Add payment
// @Description Add payment
// @Tags payment
// @Accept json
// @Produce json
// @Param Authorization header string true "Bearer token"
// @Param payment body types.Payment true "Payment"
// @Success 200 {object} types.Message
// @Failure 400 {object} types.ErrorResponse
// @Failure 500 {object} types.ErrorResponse
// @Security ApiKeyAuth
// @Router /payment/add [post]
func PaymentAdd(c *gin.Context) {
userID, err := GetUserID(c)
if err != nil {
c.JSON(500, types.ErrorResponse{Message: err.Error()})
return
}
var updates types.Payment
if err := c.ShouldBindJSON(&updates); err != nil {
log.Printf("err is %v\n", err)
c.JSON(400, types.ErrorResponse{Message: "Invalid request"})
return
}
// As this handler will likely create more than one row in database we need to
// create some sort of defer func that will rollback all created rows
weNeedRollback := false
var deletableIfRollback []db.PaymentGroup
defer func() {
if weNeedRollback {
dbc := db.Connect()
for _, deleteIt := range deletableIfRollback {
if err := dbc.Debug().Delete(deleteIt).Error; err != nil {
log.Printf("ERROR: dbc.Delete: %v\n", err)
continue
}
}
}
}()
dbc := db.Connect()
payment := &db.Payment{
CardID: updates.CardID,
CategoryID: updates.CategoryID,
UserID: userID,
Title: updates.Title,
Descr: updates.Description,
Note: updates.Note,
Date: updates.Date,
}
if err := dbc.Debug().Create(payment).Error; err != nil {
c.JSON(500, types.ErrorResponse{Message: err.Error()})
weNeedRollback = true
return
}
if payment.ID == 0 {
c.JSON(500, types.ErrorResponse{Message: "Internal error: ERR.P.A.1"})
weNeedRollback = true
return
}
deletableIfRollback = append(deletableIfRollback, payment)
for _, uItemBought := range updates.Items {
// Creating item and adding it to rollback if itemID is set to 0
if uItemBought.ItemID == 0 {
newItem := &db.Item{
Name: uItemBought.NewName,
Comment: uItemBought.NewComment,
Price: uItemBought.Price,
MetricType: uItemBought.MetricType,
MetricValue: uItemBought.MetricValue,
CategoryID: updates.CategoryID,
TypeID: uItemBought.TypeID,
UserID: userID,
}
if err := dbc.Create(newItem).Error; err != nil {
c.JSON(500, types.ErrorResponse{Message: err.Error()})
weNeedRollback = true
return
}
if newItem.ID == 0 {
c.JSON(500, types.ErrorResponse{Message: "Internal error: ERR.P.A.2"})
weNeedRollback = true
return
}
deletableIfRollback = append(deletableIfRollback, newItem)
newItemBought := &db.ItemBought{
ItemID: newItem.ID,
PaymentID: payment.ID,
TypeID: uItemBought.TypeID,
Quantity: uItemBought.Quantity,
TotalCost: newItem.Price * uint64(uItemBought.Quantity),
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.3"})
weNeedRollback = true
return
}
deletableIfRollback = append(deletableIfRollback, newItemBought)
newItemBought.Item = newItem
} else {
// TODO: check if Item has same userID and potentially update Item
}
}
c.JSON(200, types.Message{Info: fmt.Sprintf("Entity with %d ID is created successfully!", payment.ID)})
}