Compare commits
No commits in common. "cb60cb39d5e1865d99482509f0c29b7562defc3f" and "a52b108bf88241f59eae14eb8e5b1d3c3e9d4686" have entirely different histories.
cb60cb39d5
...
a52b108bf8
|
@ -123,10 +123,6 @@ func main() {
|
||||||
{
|
{
|
||||||
metricRoutes.GET("/all", handlers.MetricGetAll)
|
metricRoutes.GET("/all", handlers.MetricGetAll)
|
||||||
}
|
}
|
||||||
paymentRoutes := api.Group("/payment", middleware.AuthMiddleware())
|
|
||||||
{
|
|
||||||
paymentRoutes.POST("/add", handlers.PaymentAdd)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
|
|
|
@ -10,7 +10,3 @@ type UserIdentifiable interface {
|
||||||
GetUserID() uint
|
GetUserID() uint
|
||||||
SetUserID(userID uint)
|
SetUserID(userID uint)
|
||||||
}
|
}
|
||||||
|
|
||||||
type PaymentGroup interface {
|
|
||||||
__internalBelogingToPayment()
|
|
||||||
}
|
|
||||||
|
|
43
db/item.go
43
db/item.go
|
@ -1,16 +1,11 @@
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import "gorm.io/gorm"
|
||||||
"errors"
|
|
||||||
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Name string
|
Name string
|
||||||
Comment string
|
Comment string
|
||||||
Price uint64
|
|
||||||
MetricType uint8
|
MetricType uint8
|
||||||
MetricValue uint64
|
MetricValue uint64
|
||||||
//
|
//
|
||||||
|
@ -21,7 +16,7 @@ type Item struct {
|
||||||
Carbs uint64
|
Carbs uint64
|
||||||
Fats uint64
|
Fats uint64
|
||||||
//
|
//
|
||||||
Prices []ItemPrice `gorm:"constraint:OnDelete:CASCADE;"`
|
Prices []ItemPrice
|
||||||
CurrentPriceID uint
|
CurrentPriceID uint
|
||||||
CurrentPrice *ItemPrice
|
CurrentPrice *ItemPrice
|
||||||
//
|
//
|
||||||
|
@ -31,8 +26,6 @@ type Item struct {
|
||||||
User *User
|
User *User
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) __internalBelogingToPayment() {}
|
|
||||||
|
|
||||||
// Implements db.UserIdentifiable:1
|
// Implements db.UserIdentifiable:1
|
||||||
func (i Item) GetID() uint {
|
func (i Item) GetID() uint {
|
||||||
return i.ID
|
return i.ID
|
||||||
|
@ -77,35 +70,3 @@ func GetItemToRootCat(id uint, preloadPrices bool) (*Item, error) {
|
||||||
}).Preload("CurrentPrice").First(&item, id).Error
|
}).Preload("CurrentPrice").First(&item, id).Error
|
||||||
return &item, err
|
return &item, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
ERROR_ITEM_PRICE_ISZERO = errors.New("Item's Price is zero")
|
|
||||||
ERROR_ITEM_ITEMPRICE_INTERR = errors.New("Item's ItemPrice ID is zero after creating")
|
|
||||||
)
|
|
||||||
|
|
||||||
func (i *Item) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
if i.Price == 0 {
|
|
||||||
return ERROR_ITEM_PRICE_ISZERO
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Item) AfterCreate(tx *gorm.DB) error {
|
|
||||||
if i.CurrentPriceID == 0 {
|
|
||||||
itemPrice := &ItemPrice{
|
|
||||||
ItemID: i.ID,
|
|
||||||
Price: i.Price,
|
|
||||||
}
|
|
||||||
if err := tx.Create(itemPrice).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if itemPrice.ID == 0 {
|
|
||||||
return ERROR_ITEM_ITEMPRICE_INTERR
|
|
||||||
}
|
|
||||||
i.CurrentPriceID = itemPrice.ID
|
|
||||||
if err := tx.Save(i).Error; err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,5 +15,3 @@ type ItemBought struct {
|
||||||
MetricType uint8
|
MetricType uint8
|
||||||
MetricValue uint64
|
MetricValue uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i ItemBought) __internalBelogingToPayment() {}
|
|
||||||
|
|
|
@ -18,8 +18,6 @@ type Payment struct {
|
||||||
Title string
|
Title string
|
||||||
Descr string
|
Descr string
|
||||||
Note string
|
Note string
|
||||||
Items []ItemBought `gorm:"constraint:OnDelete:CASCADE;"`
|
Items []ItemBought
|
||||||
Date time.Time
|
Date time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Payment) __internalBelogingToPayment() {}
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ var itemTransform func(inp *db.Item) types.DbItem = func(inp *db.Item) types.DbI
|
||||||
Proteins: inp.Proteins,
|
Proteins: inp.Proteins,
|
||||||
Carbs: inp.Carbs,
|
Carbs: inp.Carbs,
|
||||||
Fats: inp.Fats,
|
Fats: inp.Fats,
|
||||||
Price: inp.Price,
|
Price: inp.CurrentPrice.Price,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
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)})
|
|
||||||
}
|
|
|
@ -65,6 +65,16 @@ type DbType struct {
|
||||||
Color string `json:"color" example:"red"`
|
Color string `json:"color" example:"red"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DbPayment struct {
|
||||||
|
ID uint `json:"id" example:"1"`
|
||||||
|
CardID uint `json:"card_id" example:"1"`
|
||||||
|
CategoryID uint `json:"category_id" example:"1"`
|
||||||
|
Title string `json:"title" example:"Veggies"`
|
||||||
|
Descr string `json:"description" example:""`
|
||||||
|
Note string `json:"not" example:"I'm a teapot"`
|
||||||
|
Date time.Time `json:"date" example:"29/11/2001 12:00"`
|
||||||
|
}
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID uint `json:"user_id" example:"1"`
|
UserID uint `json:"user_id" example:"1"`
|
||||||
|
@ -112,28 +122,3 @@ type DbMetric struct {
|
||||||
Name string `json:"name" example:"Kilogram"`
|
Name string `json:"name" example:"Kilogram"`
|
||||||
Short string `json:"short" example:"kg"`
|
Short string `json:"short" example:"kg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Payment struct {
|
|
||||||
ID uint `json:"id" example:"1"`
|
|
||||||
CardID uint `json:"card_id" example:"1"`
|
|
||||||
CategoryID uint `json:"category_id" example:"1"`
|
|
||||||
Title string `json:"title" example:"some title"`
|
|
||||||
Description string `json:"descr" example:"i bought some title for 20$"`
|
|
||||||
Note string `json:"note" example:"no i did not hit domain"`
|
|
||||||
Date time.Time `json:"date" example:"29/11/2001 12:00"`
|
|
||||||
Items []ItemBought `json:"items" example:"[]"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ItemBought struct {
|
|
||||||
ID uint `json:"id" example:"1"`
|
|
||||||
NewName string `json:"new_name" example:"itemName"`
|
|
||||||
NewComment string `json:"new_comment" example:"itemName"`
|
|
||||||
ItemID uint `json:"item_id" example:"0"`
|
|
||||||
PaymentID uint `json:"payment_id" example:"1"`
|
|
||||||
TypeID uint `json:"type_id" example:"1"`
|
|
||||||
Price uint64 `json:"price" example:"1025"`
|
|
||||||
Quantity uint `json:"quantity" example:"2"`
|
|
||||||
TotalCost uint64 `json:"total_cost" example:"2050"`
|
|
||||||
MetricType uint8 `json:"metric_type" example:"0"`
|
|
||||||
MetricValue uint64 `json:"metric_value" example:"100"`
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user