diff --git a/.prettierrc.json b/.prettierrc.json index a2065a9..6e00b35 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,8 +1,7 @@ { - "bracketSpacing": true, + "bracketSpacing": false, "bracketSameLine": false, "semi": false, "singleQuote": true, - "singleAttributePerLine": true, - "printWidth": 160 + "singleAttributePerLine": true } diff --git a/Dockerfile b/Dockerfile index 9a33285..5ee2340 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3 +FROM alpine COPY ./budget-go /usr/bin/ COPY ./budget-go-client /usr/bin/ diff --git a/Makefile b/Makefile index 552106d..9948b7d 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,16 @@ build: tpl front rice -tags=static_build \ -o $(EXECUTABLE_CMD) ./cmd/cli +.ONESHELL: +swagger: + directories="cmd/server,database/model" + + for i in backend/controller/*; do + directories="$$directories,$$i" + done + + swag init -d "cmd/server,$$directories" -g server.go + .PHONY: docker: docker build . -t gitnet.fr/deblan/budget-go diff --git a/backend/controller/auth/controller.go b/backend/controller/auth/controller.go index b3650f9..e87f52d 100644 --- a/backend/controller/auth/controller.go +++ b/backend/controller/auth/controller.go @@ -18,12 +18,9 @@ type Controller struct { func New(e *echo.Echo) *Controller { c := Controller{} - loginRoute := "/login" - logoutRoute := "/logout" - - e.GET(loginRoute, c.LoginGet) - e.POST(loginRoute, c.LoginPost) - e.GET(logoutRoute, c.LogoutGet) + e.GET("/login", c.LoginGet) + e.POST("/login", c.LoginPost) + e.GET("/logout", c.LogoutGet) return &c } @@ -53,7 +50,6 @@ func (ctrl *Controller) LoginPost(c echo.Context) error { Path: "/", MaxAge: 3600 * 24 * 2, HttpOnly: true, - Secure: true, } sess.Values["user"] = user.ID sess.Save(c.Request(), c.Response()) diff --git a/backend/controller/bank_account/controller.go b/backend/controller/bank_account/controller.go index bdf0073..3090b51 100644 --- a/backend/controller/bank_account/controller.go +++ b/backend/controller/bank_account/controller.go @@ -3,7 +3,6 @@ package bank_account import ( "github.com/labstack/echo/v4" "gitnet.fr/deblan/budget/backend/controller/crud" - "gitnet.fr/deblan/budget/backend/message" "gitnet.fr/deblan/budget/database/model" "gorm.io/gorm" ) @@ -30,45 +29,80 @@ func New(e *echo.Echo) *Controller { crud: crud.New(), } - listRoute := "/api/bank_account" - itemRoute := "/api/bank_account/: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) + e.GET("/api/bank_account", c.List) + e.POST("/api/bank_account", c.Create) + e.GET("/api/bank_account/:id", c.Show) + e.POST("/api/bank_account/:id", c.Update) + e.DELETE("/api/bank_account/:id", c.Delete) return &c } +// @Summary List bank accounts +// @Tags bank_account +// @Security ApiKeyAuth +// @Accept json +// @Produce json +// @Success 200 {object} crud.ListData +// @Success 403 +// @Router /api/bank_account [get] 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).List(c) } +// @Summary Show a bank account +// @Tags bank_account +// @Security ApiKeyAuth +// @Accept json +// @Produce json +// @Success 200 {object} model.BankAccount +// @Success 403 +// @Success 404 +// @Param id path int true "ID" +// @Router /api/bank_account/{id} [get] 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Show(c) } +// @Summary Delete a bank account +// @Tags bank_account +// @Security ApiKeyAuth +// @Accept json +// @Produce json +// @Success 200 +// @Success 403 +// @Success 400 +// @Param id path int true "ID" +// @Router /api/bank_account/{id} [delete] 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Delete(c) } +// @Summary Create a bank account +// @Tags bank_account +// @Security ApiKeyAuth +// @Accept json +// @Produce json +// @Success 200 {object} model.BankAccount +// @Success 403 +// @Success 400 +// @Param label body string true "Name" +// @Router /api/bank_account [post] func (ctrl *Controller) Create(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { @@ -83,12 +117,11 @@ func (ctrl *Controller) Create(c echo.Context) error { 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}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { diff --git a/backend/controller/category/controller.go b/backend/controller/category/controller.go index 921585b..adf0d5d 100644 --- a/backend/controller/category/controller.go +++ b/backend/controller/category/controller.go @@ -3,7 +3,6 @@ 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" @@ -37,21 +36,18 @@ func New(e *echo.Echo) *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) + e.GET("/api/category", c.List) + e.POST("/api/category", c.Create) + e.GET("/api/category/:id", c.Show) + e.POST("/api/category/:id", c.Update) + e.DELETE("/api/category/:id", 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).List(c) @@ -59,7 +55,7 @@ func (ctrl *Controller) List(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Show(c) @@ -67,7 +63,7 @@ func (ctrl *Controller) Show(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Delete(c) @@ -75,7 +71,7 @@ func (ctrl *Controller) Delete(c echo.Context) error { func (ctrl *Controller) Create(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { @@ -98,7 +94,7 @@ func (ctrl *Controller) Create(c echo.Context) error { func (ctrl *Controller) Update(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { diff --git a/backend/controller/collabora/controller.go b/backend/controller/collabora/controller.go index d7c50de..491e1b0 100644 --- a/backend/controller/collabora/controller.go +++ b/backend/controller/collabora/controller.go @@ -12,7 +12,6 @@ import ( "time" "github.com/labstack/echo/v4" - "gitnet.fr/deblan/budget/backend/message" "gitnet.fr/deblan/budget/backend/view" tpl "gitnet.fr/deblan/budget/backend/view/template/collabora" "gitnet.fr/deblan/budget/config" @@ -106,7 +105,7 @@ func (ctrl *Controller) Info(c echo.Context) error { } if file == "" { - return c.JSON(404, message.FileNotFound) + return c.JSON(404, "File not found") } fi, _ := os.Stat(file) @@ -142,7 +141,7 @@ func (ctrl *Controller) WopiContentGet(c echo.Context) error { } if file == "" { - return c.JSON(404, message.FileNotFound) + return c.JSON(404, "File not found") } content, _ := os.ReadFile(file) @@ -166,7 +165,7 @@ func (ctrl *Controller) WopiContentPost(c echo.Context) error { } if file == "" { - return c.JSON(404, message.FileNotFound) + return c.JSON(404, "File not found") } data, _ := ioutil.ReadAll(c.Request().Body) diff --git a/backend/controller/crud/crud.go b/backend/controller/crud/crud.go index ccbd99f..ebe409b 100644 --- a/backend/controller/crud/crud.go +++ b/backend/controller/crud/crud.go @@ -7,45 +7,26 @@ import ( "strings" "github.com/labstack/echo/v4" - "gitnet.fr/deblan/budget/backend/message" "gitnet.fr/deblan/budget/database/manager" "gorm.io/gorm" "gorm.io/gorm/clause" - - "github.com/go-playground/locales/fr" - ut "github.com/go-playground/universal-translator" - "github.com/go-playground/validator/v10" - fr_translations "github.com/go-playground/validator/v10/translations/fr" ) type UpdateCallback func(*gorm.DB, interface{}, interface{}) (interface{}, error) type CreateCallback func(*gorm.DB, interface{}) (interface{}, error) type Error struct { - Code int `json:"code"` - Message string `json:"message"` - Errors validator.ValidationErrorsTranslations `json:"errors"` + Code int `json:"code"` + Message string `json:"message"` } type Controller struct { - Config Configuration - Validator *validator.Validate - Trans ut.Translator + Config Configuration } func New() *Controller { c := Controller{} - fr := fr.New() - uni := ut.New(fr, fr) - - trans, _ := uni.GetTranslator("fr") - validate := validator.New() - fr_translations.RegisterDefaultTranslations(validate, trans) - - c.Validator = validate - c.Trans = trans - return &c } @@ -54,10 +35,6 @@ func (ctrl *Controller) With(config Configuration) *Controller { return ctrl } -var ( - IdEqual = "id = ?" -) - func (ctrl *Controller) List(c echo.Context) error { db := manager.Get().Db db = db.Model(ctrl.Config.Model) @@ -115,7 +92,7 @@ func (ctrl *Controller) Show(c echo.Context) error { } var count int64 - db.Model(ctrl.Config.Model).Where(IdEqual, value).Count(&count) + db.Model(ctrl.Config.Model).Where("id = ?", value).Count(&count) if count == 0 { return c.JSON(404, Error{ @@ -125,7 +102,7 @@ func (ctrl *Controller) Show(c echo.Context) error { } item := ctrl.Config.CreateModel() - db.Model(ctrl.Config.Model).Where(IdEqual, value) + db.Model(ctrl.Config.Model).Where("id = ?", value) if ctrl.Config.ItemQuery != nil { ctrl.Config.ItemQuery(db) @@ -148,17 +125,17 @@ func (ctrl *Controller) Delete(c echo.Context) error { } var count int64 - db.Model(ctrl.Config.Model).Where(IdEqual, value).Count(&count) + db.Model(ctrl.Config.Model).Where("id = ?", value).Count(&count) if count == 0 { return c.JSON(404, Error{ Code: 404, - Message: message.NotFound, + Message: "Not found", }) } item := ctrl.Config.CreateModel() - db.Model(ctrl.Config.Model).Where(IdEqual, value).Delete(&item) + db.Model(ctrl.Config.Model).Where("id = ?", value).Delete(&item) return c.JSON(200, nil) } @@ -169,17 +146,14 @@ func (ctrl *Controller) Create(c echo.Context, body interface{}, createCallback if err := c.Bind(body); err != nil { return c.JSON(400, Error{ Code: 400, - Message: message.BadRequest, + Message: "Bad request", }) } - if err := ctrl.Validator.Struct(body); err != nil { - errs := err.(validator.ValidationErrors) - + if err := c.Validate(body); err != nil { return c.JSON(400, Error{ Code: 400, - Message: message.InvalidForm, - Errors: errs.Translate(ctrl.Trans), + Message: err.Error(), }) } @@ -207,12 +181,12 @@ func (ctrl *Controller) Update(c echo.Context, body interface{}, updateCallback } var count int64 - db.Model(ctrl.Config.Model).Where(IdEqual, value).Count(&count) + db.Model(ctrl.Config.Model).Where("id = ?", value).Count(&count) if count == 0 { return c.JSON(404, Error{ Code: 404, - Message: message.NotFound, + Message: "Not found", }) } @@ -232,13 +206,10 @@ func (ctrl *Controller) Update(c echo.Context, body interface{}, updateCallback }) } - if err := ctrl.Validator.Struct(body); err != nil { - errs := err.(validator.ValidationErrors) - + if err := c.Validate(body); err != nil { return c.JSON(400, Error{ Code: 400, - Message: message.InvalidForm, - Errors: errs.Translate(ctrl.Trans), + Message: err.Error(), }) } diff --git a/backend/controller/file/controller.go b/backend/controller/file/controller.go index 9c1cc5a..31efba5 100644 --- a/backend/controller/file/controller.go +++ b/backend/controller/file/controller.go @@ -9,7 +9,6 @@ import ( "github.com/labstack/echo/v4" "gitnet.fr/deblan/budget/backend/controller/crud" - "gitnet.fr/deblan/budget/backend/message" "gitnet.fr/deblan/budget/config" "gitnet.fr/deblan/budget/database/model" f "gitnet.fr/deblan/budget/file" @@ -32,7 +31,7 @@ func New(e *echo.Echo) *Controller { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } tree := f.GetTree("", config.Get().File.Path) @@ -42,7 +41,7 @@ func (ctrl *Controller) List(c echo.Context) error { func (ctrl *Controller) CreateFile(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } file, err := c.FormFile("file") @@ -78,7 +77,7 @@ func (ctrl *Controller) CreateFile(c echo.Context) error { func (ctrl *Controller) CreateDirectory(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { @@ -127,7 +126,7 @@ func (ctrl *Controller) CreateDirectory(c echo.Context) error { func (ctrl *Controller) Download(c echo.Context) error { if nil == model.LoadUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } var file string @@ -144,7 +143,7 @@ func (ctrl *Controller) Download(c echo.Context) error { } if file == "" { - return c.JSON(404, message.FileNotFound) + return c.JSON(404, "File not found") } content, _ := os.ReadFile(file) @@ -154,7 +153,7 @@ func (ctrl *Controller) Download(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } var file string @@ -178,7 +177,7 @@ func (ctrl *Controller) Delete(c echo.Context) error { } if file == "" { - return c.JSON(404, message.FileNotFound) + return c.JSON(404, "File not found") } os.RemoveAll(file) diff --git a/backend/controller/saving_account/controller.go b/backend/controller/saving_account/controller.go index 64f7325..03ac10e 100644 --- a/backend/controller/saving_account/controller.go +++ b/backend/controller/saving_account/controller.go @@ -3,7 +3,6 @@ package saving_account import ( "github.com/labstack/echo/v4" "gitnet.fr/deblan/budget/backend/controller/crud" - "gitnet.fr/deblan/budget/backend/message" "gitnet.fr/deblan/budget/database/model" "gorm.io/gorm" ) @@ -30,21 +29,18 @@ func New(e *echo.Echo) *Controller { crud: crud.New(), } - listRoute := "/api/saving_account" - itemRoute := "/api/saving_account/: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) + e.GET("/api/saving_account", c.List) + e.POST("/api/saving_account", c.Create) + e.GET("/api/saving_account/:id", c.Show) + e.POST("/api/saving_account/:id", c.Update) + e.DELETE("/api/saving_account/:id", 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).List(c) @@ -52,7 +48,7 @@ func (ctrl *Controller) List(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Show(c) @@ -60,7 +56,7 @@ func (ctrl *Controller) Show(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Delete(c) @@ -68,7 +64,7 @@ func (ctrl *Controller) Delete(c echo.Context) error { func (ctrl *Controller) Create(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { @@ -90,7 +86,7 @@ func (ctrl *Controller) Create(c echo.Context) error { func (ctrl *Controller) Update(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { diff --git a/backend/controller/transaction/controller.go b/backend/controller/transaction/controller.go index e1dfac2..1c94964 100644 --- a/backend/controller/transaction/controller.go +++ b/backend/controller/transaction/controller.go @@ -5,10 +5,8 @@ import ( "io" "strconv" - "github.com/go-playground/validator/v10" "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" @@ -23,7 +21,7 @@ func (ctrl *Controller) Config() crud.Configuration { Table: "transactions", Model: model.Transaction{}, Models: []model.Transaction{}, - ValidOrders: []string{"id", "accounted_at", "short_label", "label", "reference", "information", "operation_type", "debit", "credit", "date", "category_id", "bank_account_id"}, + ValidOrders: []string{"accounted_at", "short_label", "label", "reference", "information", "operation_type", "debit", "credit", "date", "category_id", "bank_account_id"}, DefaultLimit: 20, DefaultOrder: "date", DefaultSort: "desc", @@ -52,7 +50,7 @@ func New(e *echo.Echo) *Controller { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).List(c) @@ -60,7 +58,7 @@ func (ctrl *Controller) List(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Show(c) @@ -68,7 +66,7 @@ func (ctrl *Controller) Show(c echo.Context) error { func (ctrl *Controller) UpdateCategories(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } datas := model.UpdateTransactionsCategories() @@ -78,7 +76,7 @@ func (ctrl *Controller) UpdateCategories(c echo.Context) error { func (ctrl *Controller) Create(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } db := manager.Get().Db @@ -87,10 +85,7 @@ func (ctrl *Controller) Create(c echo.Context) error { if err != nil { return c.JSON(400, crud.Error{ Code: 400, - Message: message.InvalidForm, - Errors: validator.ValidationErrorsTranslations{ - "BankAccount": message.BlankBankAccount, - }, + Message: err.Error(), }) } @@ -100,10 +95,7 @@ func (ctrl *Controller) Create(c echo.Context) error { if count == 0 { return c.JSON(400, crud.Error{ Code: 400, - Message: message.InvalidForm, - Errors: validator.ValidationErrorsTranslations{ - "BankAccount": message.UnknownBankAccount, - }, + Message: "Invalid bank account", }) } @@ -111,10 +103,7 @@ func (ctrl *Controller) Create(c echo.Context) error { if err != nil { return c.JSON(400, crud.Error{ Code: 400, - Message: message.InvalidForm, - Errors: validator.ValidationErrorsTranslations{ - "File": message.BlankFile, - }, + Message: err.Error(), }) } @@ -122,10 +111,7 @@ func (ctrl *Controller) Create(c echo.Context) error { if err != nil { return c.JSON(400, crud.Error{ Code: 400, - Message: message.InvalidForm, - Errors: validator.ValidationErrorsTranslations{ - "File": message.UnproccessableFile, - }, + Message: err.Error(), }) } @@ -139,10 +125,7 @@ func (ctrl *Controller) Create(c echo.Context) error { if err != nil { return c.JSON(400, crud.Error{ Code: 400, - Message: message.InvalidForm, - Errors: validator.ValidationErrorsTranslations{ - "File": message.InvalidFile, - }, + Message: err.Error(), }) } diff --git a/backend/controller/user/controller.go b/backend/controller/user/controller.go index 9957240..b8d4ff7 100644 --- a/backend/controller/user/controller.go +++ b/backend/controller/user/controller.go @@ -3,7 +3,6 @@ package user import ( "github.com/labstack/echo/v4" "gitnet.fr/deblan/budget/backend/controller/crud" - "gitnet.fr/deblan/budget/backend/message" "gitnet.fr/deblan/budget/database/model" "gorm.io/gorm" ) @@ -29,21 +28,18 @@ func New(e *echo.Echo) *Controller { crud: crud.New(), } - listRoute := "/api/user" - itemRoute := "/api/user/: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) + e.GET("/api/user", c.List) + e.POST("/api/user", c.Create) + e.GET("/api/user/:id", c.Show) + e.POST("/api/user/:id", c.Update) + e.DELETE("/api/user/:id", 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).List(c) @@ -51,7 +47,7 @@ func (ctrl *Controller) List(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Show(c) @@ -59,7 +55,7 @@ func (ctrl *Controller) Show(c echo.Context) error { 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 c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } return ctrl.crud.With(ctrl.Config()).Delete(c) @@ -67,7 +63,7 @@ func (ctrl *Controller) Delete(c echo.Context) error { func (ctrl *Controller) Create(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { @@ -88,7 +84,7 @@ func (ctrl *Controller) Create(c echo.Context) error { func (ctrl *Controller) Update(c echo.Context) error { if nil == model.LoadApiUser(c) { - return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired}) + return c.JSON(403, crud.Error{Code: 403, Message: "Login required"}) } type body struct { diff --git a/backend/message/message.go b/backend/message/message.go deleted file mode 100644 index 600e379..0000000 --- a/backend/message/message.go +++ /dev/null @@ -1,14 +0,0 @@ -package message - -var ( - LoginRequired = "Login required" - FileNotFound = "File not found" - NotFound = "Not found" - BadRequest = "Bad request" - InvalidForm = "Le formulaire n'est pas valide" - BlankBankAccount = "Le compte bancaire n'est pas renseigné" - UnknownBankAccount = "Le compte bancaire n'existe pas" - BlankFile = "Le fichier n'est pas renseigné" - UnproccessableFile = "Le fichier ne peut être traité" - InvalidFile = "Le fichier n'est pas valide" -) diff --git a/backend/view/template/auth/login.templ b/backend/view/template/auth/login.templ index cedee05..c429698 100644 --- a/backend/view/template/auth/login.templ +++ b/backend/view/template/auth/login.templ @@ -11,9 +11,9 @@ templ Page(hasError bool) {
-
+
-
+
diff --git a/backend/view/template/auth/login_templ.go b/backend/view/template/auth/login_templ.go index 26b4600..8e57ce8 100644 --- a/backend/view/template/auth/login_templ.go +++ b/backend/view/template/auth/login_templ.go @@ -39,7 +39,7 @@ func Page(hasError bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Budget
") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Budget
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/bin/watch.sh b/bin/watch.sh index b9a58f2..8342fb6 100755 --- a/bin/watch.sh +++ b/bin/watch.sh @@ -2,12 +2,31 @@ export TEMPL_EXPERIMENT=rawgo +title() { + printf -- "# %s\n" "$1" +} + while true; do + clear + + title "Remove rice-box" rm -f cmd/server/rice-box.go + + title "Build assets" ./node_modules/.bin/webpack + + title "Make templates" make tpl + + title "Make swagger" + make swagger + + title "Start server" screen -S budget -d -m go run ./cmd/server + + title "Notify" notify-send "Budget" "Ready!" + inotifywait -r . -e close_write screen -X -S budget quit done diff --git a/cmd/server/server.go b/cmd/server/server.go index d8a6ead..360fbfc 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -14,10 +14,14 @@ import ( "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" + echoSwagger "github.com/swaggo/echo-swagger" + + // _ "github.com/swaggo/echo-swagger/example/docs" + "gitnet.fr/deblan/budget/backend/router" "gitnet.fr/deblan/budget/config" "gitnet.fr/deblan/budget/database/manager" "gitnet.fr/deblan/budget/database/model" - "gitnet.fr/deblan/budget/backend/router" + "gitnet.fr/deblan/budget/docs" ) type TemplateRenderer struct { @@ -32,7 +36,16 @@ func (cv *AppValidator) Validate(i interface{}) error { return cv.validator.Struct(i) } +// @securityDefinitions.apikey ApiKeyAuth +// @in header +// @name x-api-key func main() { + docs.SwaggerInfo.Title = "Budget API" + docs.SwaggerInfo.Description = "API" + docs.SwaggerInfo.Version = "1.0" + docs.SwaggerInfo.BasePath = "/" + docs.SwaggerInfo.Schemes = []string{"http", "https"} + ini := flag.String("c", "config.ini", "Path to config.ini") conf := config.Get() conf.Load(*ini) @@ -50,6 +63,7 @@ func main() { assetHandler := http.FileServer(rice.MustFindBox("../../backend/view/static").HTTPBox()) e.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler))) + e.GET("/swagger/*", echoSwagger.WrapHandler) e.Use(middleware.Logger()) router.RegisterControllers(e) diff --git a/database/model/transaction.go b/database/model/transaction.go index 4e7f8a3..641f841 100644 --- a/database/model/transaction.go +++ b/database/model/transaction.go @@ -1,12 +1,19 @@ package model import ( - "fmt" + "crypto/md5" + "encoding/csv" + "encoding/hex" + "errors" + "io/ioutil" "regexp" + "strconv" "strings" "time" "gitnet.fr/deblan/budget/database/manager" + "golang.org/x/text/encoding/charmap" + "golang.org/x/text/transform" ) type Transaction struct { @@ -57,6 +64,8 @@ func (t *Transaction) MatchRule(rule CategoryRule) (bool, int) { if match { counter += 8 } + } else { + match = match && true } if rule.BankCategory != nil { @@ -66,6 +75,8 @@ func (t *Transaction) MatchRule(rule CategoryRule) (bool, int) { if match { counter += 6 } + } else { + match = match && true } if rule.Amount != nil { @@ -74,6 +85,8 @@ func (t *Transaction) MatchRule(rule CategoryRule) (bool, int) { if match { counter += 4 } + } else { + match = match && true } if rule.DateFrom != nil { @@ -82,6 +95,8 @@ func (t *Transaction) MatchRule(rule CategoryRule) (bool, int) { if match { counter += 2 } + } else { + match = match && true } if rule.DateTo != nil { @@ -90,10 +105,8 @@ func (t *Transaction) MatchRule(rule CategoryRule) (bool, int) { if match { counter += 2 } - } - - if match { - fmt.Printf("%+v\n", match) + } else { + match = match && true } return match, counter @@ -118,15 +131,149 @@ func (t *Transaction) MatchCategory(category Category) (bool, int) { return match, maxCounter } +func ImportCaisseEpargneTransactions(content string, bankAccountID int) ([]Transaction, error) { + lines := strings.Split(content, "\n") + db := manager.Get().Db + datas := []Transaction{} + + for key, line := range lines { + if key == 0 { + continue + } + + line = strings.TrimSpace(line) + + if line == "" { + continue + } + + fields := strings.Split(line, ";") + + if len(fields) != 13 { + return datas, errors.New("Invalid format") + } + + ref := fields[3] + + if ref == "" { + hash := md5.New() + hash.Write([]byte(line)) + hashInBytes := hash.Sum(nil) + ref = hex.EncodeToString(hashInBytes) + } + + var count int64 + + db.Model(Transaction{}).Where(Transaction{Reference: ref}).Count(&count) + + if count > 0 { + continue + } + + transaction := Transaction{ + ShortLabel: toUTF8(fields[1]), + Label: toUTF8(fields[2]), + Reference: ref, + Information: fields[4], + OperationType: fields[5], + AccountedAt: toDate(fields[0], "02/01/2006"), + BankCategory: fields[6], + BankSubCategory: fields[7], + Debit: -toFloat(fields[8]), + Credit: toFloat(fields[9]), + BankAccountID: bankAccountID, + Date: toDate(fields[10], "02/01/2006"), + } + + db.Model(Transaction{}).Save(&transaction) + + datas = append(datas, transaction) + } + + return datas, nil +} + +func ImportRevolutTransactions(content string, bankAccountID int) ([]Transaction, error) { + db := manager.Get().Db + datas := []Transaction{} + + r := csv.NewReader(strings.NewReader(content)) + records, err := r.ReadAll() + + if err != nil { + return nil, err + } + + for key, fields := range records { + if key == 0 { + continue + } + + if len(fields) != 10 { + return datas, errors.New("Invalid format") + } + + hash := md5.New() + hash.Write([]byte(strings.Join(fields, ","))) + hashInBytes := hash.Sum(nil) + ref := hex.EncodeToString(hashInBytes) + + if fields[8] != "COMPLETED" { + continue + } + + var count int64 + + db.Model(Transaction{}).Where(Transaction{Reference: ref}).Count(&count) + + if count > 0 { + continue + } + + amount := toFloat(fields[5]) + var debit float64 + var credit float64 + + if amount < 0 { + debit = -amount + credit = 0 + } else { + debit = 0 + credit = amount + } + + date := toDate(fields[2], "2006-01-02 15:04:05") + + transaction := Transaction{ + ShortLabel: fields[4], + Label: fields[4], + Reference: ref, + Information: "", + OperationType: fields[0], + AccountedAt: date, + BankCategory: "", + BankSubCategory: "", + Debit: debit, + Credit: credit, + BankAccountID: bankAccountID, + Date: date, + } + + db.Model(Transaction{}).Save(&transaction) + + datas = append(datas, transaction) + } + + return datas, nil +} + func ImportTransactions(content string, bankAccountID int, format string) ([]Transaction, error) { var datas []Transaction var err error if format == "revolut" { datas, err = ImportRevolutTransactions(content, bankAccountID) - } else if format == "banque_populaire" { - datas, err = ImportBanquePopulaireTransactions(content, bankAccountID) - } else if format == "caisse_epargne" { + } else { datas, err = ImportCaisseEpargneTransactions(content, bankAccountID) } @@ -164,3 +311,23 @@ func UpdateTransactionsCategories() []Transaction { return datas } + +func toFloat(value string) float64 { + value = strings.ReplaceAll(value, ",", ".") + v, _ := strconv.ParseFloat(value, 64) + + return v +} + +func toDate(value, format string) time.Time { + v, _ := time.Parse(format, value) + + return v +} + +func toUTF8(input string) string { + reader := transform.NewReader(strings.NewReader(input), charmap.ISO8859_1.NewDecoder()) + decoded, _ := ioutil.ReadAll(reader) + + return string(decoded) +} diff --git a/database/model/transaction_banque_populaire.go b/database/model/transaction_banque_populaire.go deleted file mode 100644 index 307fe5c..0000000 --- a/database/model/transaction_banque_populaire.go +++ /dev/null @@ -1,81 +0,0 @@ -package model - -import ( - "crypto/md5" - "encoding/hex" - "errors" - "strings" - - "gitnet.fr/deblan/budget/database/manager" -) - -func ImportBanquePopulaireTransactions(content string, bankAccountID int) ([]Transaction, error) { - lines := strings.Split(content, "\n") - db := manager.Get().Db - datas := []Transaction{} - - for key, line := range lines { - if key == 0 { - continue - } - - line = strings.TrimSpace(line) - - if line == "" { - continue - } - - fields := strings.Split(line, ";") - - if len(fields) != 8 { - return datas, errors.New("Invalid format") - } - - hash := md5.New() - hash.Write([]byte(line)) - hashInBytes := hash.Sum(nil) - ref := hex.EncodeToString(hashInBytes) - - var count int64 - - db.Model(Transaction{}).Where(Transaction{ - Reference: ref, - BankAccountID: bankAccountID, - }).Count(&count) - - if count > 0 { - continue - } - - amount := ToFloat(fields[6]) - debit := 0.0 - credit := 0.0 - - if amount > 0 { - credit = amount - } else { - debit = -amount - } - - transaction := Transaction{ - ShortLabel: "", - Label: ToUTF8(fields[3]), - Reference: ref, - Information: "", - OperationType: "", - AccountedAt: ToDate(fields[1], "02/01/2006"), - BankCategory: "", - BankSubCategory: "", - Debit: debit, - Credit: credit, - BankAccountID: bankAccountID, - Date: ToDate(fields[2], "02/01/2006"), - } - - db.Model(Transaction{}).Save(&transaction) - - datas = append(datas, transaction) - } - - return datas, nil -} diff --git a/database/model/transaction_caisse_epargne.go b/database/model/transaction_caisse_epargne.go deleted file mode 100644 index de163b3..0000000 --- a/database/model/transaction_caisse_epargne.go +++ /dev/null @@ -1,75 +0,0 @@ -package model - -import ( - "crypto/md5" - "encoding/hex" - "errors" - "strings" - - "gitnet.fr/deblan/budget/database/manager" -) - -func ImportCaisseEpargneTransactions(content string, bankAccountID int) ([]Transaction, error) { - lines := strings.Split(content, "\n") - db := manager.Get().Db - datas := []Transaction{} - - for key, line := range lines { - if key == 0 { - continue - } - - line = strings.TrimSpace(line) - - if line == "" { - continue - } - - fields := strings.Split(line, ";") - - if len(fields) != 13 { - return datas, errors.New("Invalid format") - } - - ref := fields[3] - - if ref == "" { - hash := md5.New() - hash.Write([]byte(line)) - hashInBytes := hash.Sum(nil) - ref = hex.EncodeToString(hashInBytes) - } - - var count int64 - - db.Model(Transaction{}).Where(Transaction{ - Reference: ref, - BankAccountID: bankAccountID, - }).Count(&count) - - if count > 0 { - continue - } - - transaction := Transaction{ - ShortLabel: ToUTF8(fields[1]), - Label: ToUTF8(fields[2]), - Reference: ref, - Information: fields[4], - OperationType: fields[5], - AccountedAt: ToDate(fields[0], "02/01/2006"), - BankCategory: fields[6], - BankSubCategory: fields[7], - Debit: -ToFloat(fields[8]), - Credit: ToFloat(fields[9]), - BankAccountID: bankAccountID, - Date: ToDate(fields[10], "02/01/2006"), - } - - db.Model(Transaction{}).Save(&transaction) - - datas = append(datas, transaction) - } - - return datas, nil -} diff --git a/database/model/transaction_formater.go b/database/model/transaction_formater.go deleted file mode 100644 index 07fc953..0000000 --- a/database/model/transaction_formater.go +++ /dev/null @@ -1,31 +0,0 @@ -package model - -import ( - "io/ioutil" - "strconv" - "strings" - "time" - - "golang.org/x/text/encoding/charmap" - "golang.org/x/text/transform" -) - -func ToFloat(value string) float64 { - value = strings.ReplaceAll(value, ",", ".") - v, _ := strconv.ParseFloat(value, 64) - - return v -} - -func ToDate(value, format string) time.Time { - v, _ := time.Parse(format, value) - - return v -} - -func ToUTF8(input string) string { - reader := transform.NewReader(strings.NewReader(input), charmap.ISO8859_1.NewDecoder()) - decoded, _ := ioutil.ReadAll(reader) - - return string(decoded) -} diff --git a/database/model/transaction_revolut.go b/database/model/transaction_revolut.go deleted file mode 100644 index 37575d1..0000000 --- a/database/model/transaction_revolut.go +++ /dev/null @@ -1,88 +0,0 @@ -package model - -import ( - "crypto/md5" - "encoding/csv" - "encoding/hex" - "errors" - "strings" - - "gitnet.fr/deblan/budget/database/manager" -) - -func ImportRevolutTransactions(content string, bankAccountID int) ([]Transaction, error) { - db := manager.Get().Db - datas := []Transaction{} - - r := csv.NewReader(strings.NewReader(content)) - records, err := r.ReadAll() - - if err != nil { - return nil, err - } - - for key, fields := range records { - if key == 0 { - continue - } - - if len(fields) != 10 { - return datas, errors.New("Invalid format") - } - - hash := md5.New() - hash.Write([]byte(strings.Join(fields, ","))) - hashInBytes := hash.Sum(nil) - ref := hex.EncodeToString(hashInBytes) - - if fields[8] != "COMPLETED" { - continue - } - - var count int64 - - db.Model(Transaction{}).Where(Transaction{ - Reference: ref, - BankAccountID: bankAccountID, - }).Count(&count) - - if count > 0 { - continue - } - - amount := ToFloat(fields[5]) - var debit float64 - var credit float64 - - if amount < 0 { - debit = -amount - credit = 0 - } else { - debit = 0 - credit = amount - } - - date := ToDate(fields[2], "2006-01-02 15:04:05") - - transaction := Transaction{ - ShortLabel: fields[4], - Label: fields[4], - Reference: ref, - Information: "", - OperationType: fields[0], - AccountedAt: date, - BankCategory: "", - BankSubCategory: "", - Debit: debit, - Credit: credit, - BankAccountID: bankAccountID, - Date: date, - } - - db.Model(Transaction{}).Save(&transaction) - - datas = append(datas, transaction) - } - - return datas, nil -} diff --git a/frontend/js/App.vue b/frontend/js/App.vue index 5718658..55f13e7 100644 --- a/frontend/js/App.vue +++ b/frontend/js/App.vue @@ -1,6 +1,6 @@ + + diff --git a/frontend/js/chart/capital.js b/frontend/js/chart/capital.js index 22d92f2..567f6fd 100644 --- a/frontend/js/chart/capital.js +++ b/frontend/js/chart/capital.js @@ -1,4 +1,4 @@ -import { isInRange } from '../lib/dateFilter' +import {isInRange} from '../lib/dateFilter' const getDate = (value, precision) => { const d = new Date(value) @@ -50,7 +50,7 @@ const compute = (transactions, precision, dateFrom, dateTo) => { transactions.forEach((transaction) => { let date = getDate(transaction.date, precision) - let begin = !Object.hasOwn(indexes, date) + let begin = !Object.prototype.hasOwnProperty.call(indexes, date) if (begin) { indexes[date] = labels.length @@ -79,4 +79,4 @@ const compute = (transactions, precision, dateFrom, dateTo) => { return config } -export { compute } +export {compute} diff --git a/frontend/js/chart/debitAverage.js b/frontend/js/chart/debitAverage.js index f804648..f1a2848 100644 --- a/frontend/js/chart/debitAverage.js +++ b/frontend/js/chart/debitAverage.js @@ -1,4 +1,4 @@ -import { isInRange } from '../lib/dateFilter' +import {isInRange} from '../lib/dateFilter' const getDate = (value) => { const d = new Date(value) @@ -36,7 +36,7 @@ const compute = (transactions, dateFrom, dateTo, order) => { let category = transaction.category ?? emptyCategory - if (!Object.hasOwn(data, category.label)) { + if (!Object.prototype.hasOwnProperty.call(data, category.label)) { data[category.label] = { category: category, average: 0, @@ -52,7 +52,7 @@ const compute = (transactions, dateFrom, dateTo, order) => { const date = getDate(transaction.date) - if (!Object.hasOwn(data[category.label].months, date)) { + if (!Object.prototype.hasOwnProperty.call(data[category.label].months, date)) { data[category.label].months[date] = 0 } @@ -82,4 +82,4 @@ const compute = (transactions, dateFrom, dateTo, order) => { return data } -export { compute } +export {compute} diff --git a/frontend/js/chart/diffCreditDebit.js b/frontend/js/chart/diffCreditDebit.js index 4014313..16e2745 100644 --- a/frontend/js/chart/diffCreditDebit.js +++ b/frontend/js/chart/diffCreditDebit.js @@ -1,4 +1,4 @@ -import { isInRange } from '../lib/dateFilter' +import {isInRange} from '../lib/dateFilter' const getDate = (value) => { const d = new Date(value) @@ -39,7 +39,7 @@ const compute = (transactions, dateFrom, dateTo) => { const date = getDate(transaction.date) - if (!Object.hasOwn(indexes, date)) { + if (!Object.prototype.hasOwnProperty.call(indexes, date)) { indexes[date] = labels.length values[date] = 0 labels.push(date) @@ -68,4 +68,4 @@ const compute = (transactions, dateFrom, dateTo) => { return config } -export { compute } +export {compute} diff --git a/frontend/js/chart/distribution.js b/frontend/js/chart/distribution.js index 2089bc6..8724527 100644 --- a/frontend/js/chart/distribution.js +++ b/frontend/js/chart/distribution.js @@ -1,4 +1,4 @@ -import { isInRange } from '../lib/dateFilter' +import {isInRange} from '../lib/dateFilter' const getDate = (value) => { const d = new Date(value) @@ -13,7 +13,13 @@ const getDate = (value) => { return `${month}/${year}` } -const computeBar = (transactions, stacked, dateFrom, dateTo, selectedCategories) => { +const computeBar = ( + transactions, + stacked, + dateFrom, + dateTo, + selectedCategories, +) => { const indexes = {} const labels = [] const bars = {} @@ -36,12 +42,12 @@ const computeBar = (transactions, stacked, dateFrom, dateTo, selectedCategories) let date = getDate(transaction.date) - if (!Object.hasOwn(indexes, date)) { + if (!Object.prototype.hasOwnProperty.call(indexes, date)) { indexes[date] = labels.length labels.push(date) } - if (!Object.hasOwn(bars, category.label)) { + if (!Object.prototype.hasOwnProperty.call(bars, category.label)) { bars[category.label] = { label: category.label, data: [], @@ -72,7 +78,8 @@ const computeBar = (transactions, stacked, dateFrom, dateTo, selectedCategories) let date = getDate(transaction.date) - bars[category.label].data[indexes[date]] += transaction.debit - transaction.credit + bars[category.label].data[indexes[date]] += + transaction.debit - transaction.credit }) labels.forEach((label, key) => { @@ -103,7 +110,12 @@ const computeBar = (transactions, stacked, dateFrom, dateTo, selectedCategories) } } -const computeDoughnut = (transactions, dateFrom, dateTo, selectedCategories) => { +const computeDoughnut = ( + transactions, + dateFrom, + dateTo, + selectedCategories, +) => { const indexes = {} const labels = [] const data = [] @@ -125,7 +137,7 @@ const computeDoughnut = (transactions, dateFrom, dateTo, selectedCategories) => return } - if (!Object.hasOwn(indexes, category.id)) { + if (!Object.prototype.hasOwnProperty.call(indexes, category.id)) { indexes[category.id] = labels.length labels.push(category.label) backgroundColor.push(category.color) @@ -152,4 +164,4 @@ const computeDoughnut = (transactions, dateFrom, dateTo, selectedCategories) => } } -export { computeDoughnut, computeBar } +export {computeDoughnut, computeBar} diff --git a/frontend/js/chart/monthThreshold.js b/frontend/js/chart/monthThreshold.js index 5fb4710..6f01e4b 100644 --- a/frontend/js/chart/monthThreshold.js +++ b/frontend/js/chart/monthThreshold.js @@ -1,4 +1,4 @@ -import { isInRange } from '../lib/dateFilter' +import {isInRange} from '../lib/dateFilter' const getDate = (value) => { const d = new Date(value) @@ -24,7 +24,10 @@ const compute = (transactions, cats, dateFrom, dateTo) => { }) transactions.forEach((value) => { - if (value.category === null || !Object.hasOwn(categories, value.category.id)) { + if ( + value.category === null || + !Object.prototype.hasOwnProperty.call(categories, value.category.id) + ) { return } @@ -34,11 +37,16 @@ const compute = (transactions, cats, dateFrom, dateTo) => { const date = getDate(value.date) - if (!Object.hasOwn(datas, date)) { + if (!Object.prototype.hasOwnProperty.call(datas, date)) { datas[date] = {} } - if (!Object.hasOwn(datas[date], value.category.id.toString())) { + if ( + !Object.prototype.hasOwnProperty.call( + datas[date], + value.category.id.toString(), + ) + ) { datas[date][value.category.id.toString()] = 0 } @@ -65,4 +73,4 @@ const compute = (transactions, cats, dateFrom, dateTo) => { return datas } -export { compute } +export {compute} diff --git a/frontend/js/chart/savingAccount.js b/frontend/js/chart/savingAccount.js index 8d24a8f..fc970e4 100644 --- a/frontend/js/chart/savingAccount.js +++ b/frontend/js/chart/savingAccount.js @@ -27,4 +27,4 @@ const compute = (accounts) => { } } -export { compute } +export {compute} diff --git a/frontend/js/components/CrudFilter.vue b/frontend/js/components/Filters.vue similarity index 76% rename from frontend/js/components/CrudFilter.vue rename to frontend/js/components/Filters.vue index 8475ccd..d32f5a8 100644 --- a/frontend/js/components/CrudFilter.vue +++ b/frontend/js/components/Filters.vue @@ -18,7 +18,9 @@
@@ -31,14 +33,18 @@ /> diff --git a/frontend/js/components/SortButton.vue b/frontend/js/components/SortButton.vue index daad704..b8a68f1 100644 --- a/frontend/js/components/SortButton.vue +++ b/frontend/js/components/SortButton.vue @@ -1,6 +1,5 @@