147 lines
4.2 KiB
Go
147 lines
4.2 KiB
Go
|
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)})
|
||
|
}
|