package category import ( "github.com/labstack/echo/v4" "gitnet.fr/deblan/budget/backend/controller/crud" "gitnet.fr/deblan/budget/backend/message" "gitnet.fr/deblan/budget/database/manager" "gitnet.fr/deblan/budget/database/model" "gorm.io/gorm" ) type Controller struct { crud *crud.Controller } func (ctrl *Controller) Config() crud.Configuration { return crud.Configuration{ Table: "categories", Model: model.Category{}, Models: []model.Category{}, ValidOrders: []string{"id", "label", "month_threshold", "ignore_transactions"}, DefaultLimit: 100, CreateModel: func() interface{} { return new(model.Category) }, ListQuery: func(db *gorm.DB) { db.Preload("Rules") }, ItemQuery: func(db *gorm.DB) { db.Preload("Rules") }, } } func New(e *echo.Echo) *Controller { c := Controller{ crud: crud.New(), } listRoute := "/api/category" itemRoute := "/api/category/:id" e.GET(listRoute, c.List) e.POST(listRoute, c.Create) e.GET(itemRoute, c.Show) e.POST(itemRoute, c.Update) e.DELETE(itemRoute, c.Delete) return &c } func (ctrl *Controller) List(c echo.Context) error { if nil == model.LoadApiUser(c) { return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) } return ctrl.crud.With(ctrl.Config()).List(c) } func (ctrl *Controller) Show(c echo.Context) error { if nil == model.LoadApiUser(c) { return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) } return ctrl.crud.With(ctrl.Config()).Show(c) } func (ctrl *Controller) Delete(c echo.Context) error { if nil == model.LoadApiUser(c) { return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) } return ctrl.crud.With(ctrl.Config()).Delete(c) } func (ctrl *Controller) Create(c echo.Context) error { if nil == model.LoadApiUser(c) { return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) } type body struct { Label string `json:"label" form:"label" validate:"required"` MonthThreshold *float64 `json:"month_threshold" form:"month_threshold"` Color string `json:"color" form:"color" validate:"required"` Rules []model.CategoryRule `json:"rules" form:"rules"` IgnoreTransactions bool `json:"ignore_transactions" form:"ignore_transactions"` } return ctrl.crud.With(ctrl.Config()).Create(c, new(body), func(db *gorm.DB, v interface{}) (interface{}, error) { value := v.(*body) item := model.NewCategory(value.Label, value.Color, value.Rules, value.MonthThreshold) db.Model(ctrl.crud.Config.Model).Create(&item) return item, nil }) } func (ctrl *Controller) Update(c echo.Context) error { if nil == model.LoadApiUser(c) { return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) } type body struct { Label string `json:"label" form:"label" validate:"required"` Color string `json:"color" form:"color" validate:"required"` MonthThreshold *float64 `json:"month_threshold" form:"month_threshold"` IgnoreTransactions bool `json:"ignore_transactions" form:"ignore_transactions"` Rules []model.CategoryRule `json:"rules" form:"rules"` } return ctrl.crud.With(ctrl.Config()).Update(c, new(body), func(db *gorm.DB, a, b interface{}) (interface{}, error) { item := a.(*model.Category) update := b.(*body) dbItem := model.Category{} db.Model(model.Category{}).Preload("Rules").First(&dbItem, item.ID) dbItem.Label = update.Label dbItem.Color = update.Color dbItem.MonthThreshold = update.MonthThreshold dbItem.IgnoreTransactions = &update.IgnoreTransactions if dbItem.MonthThreshold == nil { manager.Get().Db.Model(&dbItem).Update("month_threshold", gorm.Expr("NULL")) } for _, rule := range dbItem.Rules { ok := false for _, nRule := range update.Rules { if nRule.ID == rule.ID { ok = true } } if !ok { manager.Get().Db.Model(&rule).Delete(&rule, rule.ID) } } dbItem.Rules = update.Rules manager.Get().Db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&dbItem) return item, nil }) }