diff options
author | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-11 20:55:48 +0530 |
---|---|---|
committer | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-11 20:55:48 +0530 |
commit | bc154857fb5569d7c1fa9785cc891cb927a6a156 (patch) | |
tree | 590c9f6a00a1b97b2ee45cfa5a767558089affe0 /invoice | |
parent | 8a47978ca17d2f251d67d12b0e34fa26bb1e4ace (diff) |
removed per-user itemsv0.17.0
Diffstat (limited to 'invoice')
-rw-r--r-- | invoice/controller.go | 229 | ||||
-rw-r--r-- | invoice/invoice.go | 3 | ||||
-rw-r--r-- | invoice/router.go | 4 | ||||
-rw-r--r-- | invoice/service.go | 42 | ||||
-rw-r--r-- | invoice/validators.go | 28 |
5 files changed, 35 insertions, 271 deletions
diff --git a/invoice/controller.go b/invoice/controller.go index ad6df3e..b03ec22 100644 --- a/invoice/controller.go +++ b/invoice/controller.go @@ -32,17 +32,7 @@ func handleGetSingleInvoice (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var invoice Invoice - err = getInvoice(&invoice, uint(id)) if err != nil { ctx.Error(err) @@ -50,85 +40,36 @@ func handleGetSingleInvoice (ctx *gin.Context) { return } - if invoice.UserID != userId { - ctx.Error(e.ErrForbidden) - ctx.Abort() - return - } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": invoice, }) } -func handleGetInvoices (ctx *gin.Context) { - var invoices []Invoice - - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err := getInvoices(&invoices, userId, false) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": invoices, - }) -} - -func handleGetDrafts (ctx *gin.Context) { - var invoices []Invoice - - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } +func handleGetInvoices(getDrafts bool) func(*gin.Context) { + return func(ctx *gin.Context) { + var invoices []Invoice - userId := uId.(uint) + err := getInvoices(&invoices, getDrafts) + if err != nil { + ctx.Error(err) + ctx.Abort() + return + } - err := getInvoices(&invoices, userId, true) - if err != nil { - ctx.Error(err) - ctx.Abort() - return + ctx.JSON(http.StatusOK, gin.H{ + "data": invoices, + }) } - - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": invoices, - }) } func handleSaveInvoice (ctx *gin.Context) { var invoice Invoice ctx.Bind(&invoice) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - invoice.UserID = userId - // if invoice number is 0, generate one! + // (maybe the client didn't give us one) if invoice.InvoiceNumber == 0 { - n, err := getNewInvoiceNumber(invoice.UserID) + n, err := getNewInvoiceNumber() if err != nil { ctx.Error(err) @@ -147,12 +88,12 @@ func handleSaveInvoice (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": invoice, }) } func handleDelInvoice (ctx *gin.Context) { + // TODO: only drafts can be deleted, non-drafts should be "cancelled" id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -163,23 +104,6 @@ func handleDelInvoice (ctx *gin.Context) { var invoice Invoice invoice.ID = uint(id) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - invoice.UserID = userId - - err = checkInvoiceOwnership(invoice.ID, invoice.UserID) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = invoice.del() if err != nil { ctx.Error(err) @@ -187,9 +111,7 @@ func handleDelInvoice (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - }) + ctx.JSON(http.StatusOK, nil) } // get items belonging to a certain invoice @@ -201,22 +123,6 @@ func handleGetInvoiceItems (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err = checkInvoiceOwnership(uint(id), userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - var items []InvoiceItem err = getInvoiceItems(&items, uint(id)) if err != nil { @@ -226,12 +132,12 @@ func handleGetInvoiceItems (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": items, }) } func addItem (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -239,27 +145,11 @@ func addItem (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var item InvoiceItem ctx.Bind(&item) item.InvoiceID = uint(id) - err = checkInvoiceOwnership(item.InvoiceID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = item.upsert() if err != nil { ctx.Error(err) @@ -267,13 +157,11 @@ func addItem (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": item, - }) + ctx.JSON(http.StatusOK, nil) } func removeItem (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -281,27 +169,9 @@ func removeItem (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var item InvoiceItem item.ID = uint(id) - invoiceId, err := getItemInvoice(item.ID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - - item.InvoiceID = invoiceId - err = item.del() if err != nil { ctx.Error(err) @@ -309,10 +179,7 @@ func removeItem (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": item, - }) + ctx.JSON(http.StatusOK, nil) } // get custom fields belonging to a certain invoice @@ -324,22 +191,6 @@ func handleGetInvoiceCustomFields (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err = checkInvoiceOwnership(uint(id), userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - var cf []CustomField err = getInvoiceCustomFields(&cf, uint(id)) if err != nil { @@ -349,12 +200,12 @@ func handleGetInvoiceCustomFields (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": cf, }) } func addCustomField (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -362,27 +213,10 @@ func addCustomField (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var cf CustomField ctx.Bind(&cf) - cf.InvoiceID = uint(id) - err = checkInvoiceOwnership(cf.InvoiceID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = cf.upsert() if err != nil { ctx.Error(err) @@ -391,12 +225,12 @@ func addCustomField (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": cf, }) } func removeCustomField (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -404,27 +238,9 @@ func removeCustomField (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var cf CustomField cf.ID = uint(id) - invoiceId, err := getCustomFieldInvoice(cf.ID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - - cf.InvoiceID = invoiceId - err = cf.del() if err != nil { ctx.Error(err) @@ -433,7 +249,6 @@ func removeCustomField (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": cf, }) } diff --git a/invoice/invoice.go b/invoice/invoice.go index 4397710..9fa931b 100644 --- a/invoice/invoice.go +++ b/invoice/invoice.go @@ -20,7 +20,6 @@ package invoice import ( "gorm.io/gorm" d "vidhukant.com/openbills/db" - "vidhukant.com/openbills/user" u "vidhukant.com/openbills/util" i "vidhukant.com/openbills/item" "time" @@ -63,8 +62,6 @@ type CustomField struct { type Invoice struct { gorm.Model - UserID uint `json:"-"` - User user.User `json:"-"` InvoiceDate time.Time InvoiceNumber uint BillingAddress InvoiceBillingAddress diff --git a/invoice/router.go b/invoice/router.go index febd8fd..f406786 100644 --- a/invoice/router.go +++ b/invoice/router.go @@ -24,8 +24,8 @@ import ( func Routes(route *gin.RouterGroup) { g := route.Group("/invoice") { - g.GET("/", handleGetInvoices) - g.GET("/draft", handleGetDrafts) + g.GET("/", handleGetInvoices(false)) + g.GET("/draft", handleGetInvoices(true)) g.GET("/:id", handleGetSingleInvoice) g.POST("/", handleSaveInvoice) g.DELETE("/:id", handleDelInvoice) diff --git a/invoice/service.go b/invoice/service.go index 163b21e..55b1319 100644 --- a/invoice/service.go +++ b/invoice/service.go @@ -22,18 +22,12 @@ import ( ) // returns greatest invoice number + 1 -func getNewInvoiceNumber(userId uint) (uint, error) { - var i uint - +func getNewInvoiceNumber() (uint, error) { // check if number of invoices is 0 var count int64 - err := db.Model(&Invoice{}). - Where("user_id = ?", userId). - Count(&count). - Error - + err := db.Model(&Invoice{}).Count(&count).Error if err != nil { - return i, err + return 0, err } // if no records exist, then invoice number should be 1 @@ -45,7 +39,8 @@ func getNewInvoiceNumber(userId uint) (uint, error) { // NOTE: if there are gaps in invoice numbers, // they won't be filled and the series would continue // from the greatest invoice number. - row := db.Model(&Invoice{}).Where("user_id = ?", userId).Select("max(invoice_number)").Row() + var i uint + row := db.Model(&Invoice{}).Select("max(invoice_number)").Row() err = row.Scan(&i) return i + 1, err @@ -66,8 +61,8 @@ func getInvoice(invoice *Invoice, id uint) error { return nil } -func getInvoices(invoices *[]Invoice, userId uint, isDraft bool) error { - res := db.Where("user_id = ? and is_draft = ?", userId, isDraft).Find(&invoices) +func getInvoices(invoices *[]Invoice, isDraft bool) error { + res := db.Where("is_draft = ?", isDraft).Find(&invoices) // TODO: handle potential errors if res.Error != nil { @@ -118,14 +113,13 @@ func (i *Invoice) upsert() error { } func (i *Invoice) del() error { - res := db.Where("id = ? and user_id = ?", i.ID, i.UserID).Delete(i) + res := db.Where("id = ?", i.ID).Delete(i) // TODO: handle potential errors if res.Error != nil { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return e.ErrNotFound } @@ -133,8 +127,7 @@ func (i *Invoice) del() error { return nil } -// also checks for ownership -func getItemInvoice(itemId, userId uint) (uint, error) { +func getItemInvoice(itemId uint) (uint, error) { var invoiceId uint res := db. Model(&InvoiceItem{}). @@ -151,17 +144,10 @@ func getItemInvoice(itemId, userId uint) (uint, error) { return invoiceId, e.ErrNotFound } - err := checkInvoiceOwnership(invoiceId, userId) - - if err != nil { - return invoiceId, err - } - return invoiceId, nil } -// also checks for ownership -func getCustomFieldInvoice(fieldId, userId uint) (uint, error) { +func getCustomFieldInvoice(fieldId uint) (uint, error) { var invoiceId uint res := db. Model(&CustomField{}). @@ -178,12 +164,6 @@ func getCustomFieldInvoice(fieldId, userId uint) (uint, error) { return invoiceId, e.ErrNotFound } - err := checkInvoiceOwnership(invoiceId, userId) - - if err != nil { - return invoiceId, err - } - return invoiceId, nil } @@ -195,7 +175,6 @@ func (i *InvoiceItem) del() error { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return e.ErrNotFound } @@ -211,7 +190,6 @@ func (c *CustomField) del() error { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return e.ErrNotFound } diff --git a/invoice/validators.go b/invoice/validators.go index 9f145dc..1c39cbe 100644 --- a/invoice/validators.go +++ b/invoice/validators.go @@ -24,7 +24,7 @@ import ( func (i *Invoice) validate() error { var count int64 err := db.Model(&Invoice{}). - Where("user_id = ? and invoice_number = ?", i.UserID, i.InvoiceNumber). + Where("invoice_number = ?", i.InvoiceNumber). Count(&count). Error @@ -59,29 +59,3 @@ func isDraft(invoiceId uint) (bool, error) { return invoice.IsDraft, nil } - -func checkInvoiceOwnership(invoiceId, userId uint) error { - var invoice Invoice - err := db. - Select("id", "user_id"). - Where("id = ?", invoiceId). - Find(&invoice). - Error - - // TODO: handle potential errors - if err != nil { - return err - } - - // invoice doesn't exist - if invoice.ID == 0 { - return errors.ErrNotFound - } - - // user doesn't own this invoice - if invoice.UserID != userId { - return errors.ErrForbidden - } - - return nil -} |