aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVidhu Kant Sharma <vidhukant@vidhukant.com>2023-10-09 22:11:16 +0530
committerVidhu Kant Sharma <vidhukant@vidhukant.com>2023-10-09 22:11:16 +0530
commit48845b9e703756471a98f8b1f1edaa2313763df4 (patch)
tree1883095a68148bad0d0e5daff818616e5137a3c3
parent1924bfca2439829253df3598481034e5c586e3e2 (diff)
checking user while adding and removing invoice itemsv0.0.13
-rw-r--r--invoice/controller.go61
-rw-r--r--invoice/hooks.go15
-rw-r--r--invoice/invoice.go1
-rw-r--r--invoice/router.go2
-rw-r--r--invoice/service.go45
-rw-r--r--main.go2
6 files changed, 123 insertions, 3 deletions
diff --git a/invoice/controller.go b/invoice/controller.go
index 354ae21..02bbaf5 100644
--- a/invoice/controller.go
+++ b/invoice/controller.go
@@ -28,6 +28,7 @@ func handleGetSingleInvoice (ctx *gin.Context) {
id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
if err != nil {
ctx.Error(e.ErrInvalidID)
+ ctx.Abort()
return
}
@@ -117,6 +118,7 @@ func handleDelInvoice (ctx *gin.Context) {
id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
if err != nil {
ctx.Error(e.ErrInvalidID)
+ ctx.Abort()
return
}
@@ -156,14 +158,31 @@ func addItem (ctx *gin.Context) {
id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
if err != nil {
ctx.Error(e.ErrInvalidID)
+ ctx.Abort()
+ 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)
@@ -176,3 +195,45 @@ func addItem (ctx *gin.Context) {
"data": item,
})
}
+
+func removeItem (ctx *gin.Context) {
+ id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
+ if err != nil {
+ ctx.Error(e.ErrInvalidID)
+ ctx.Abort()
+ 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)
+ ctx.Abort()
+ return
+ }
+
+ ctx.JSON(http.StatusOK, gin.H{
+ "message": "success",
+ "data": item,
+ })
+}
diff --git a/invoice/hooks.go b/invoice/hooks.go
index 686500a..7a59352 100644
--- a/invoice/hooks.go
+++ b/invoice/hooks.go
@@ -70,3 +70,18 @@ func (i *InvoiceItem) BeforeSave(tx *gorm.DB) error {
return nil
}
+
+func (i *InvoiceItem) BeforeDelete(tx *gorm.DB) error {
+ var err error
+
+ isDraft, err := isDraft(i.InvoiceID)
+ if err != nil {
+ return err
+ }
+
+ if !isDraft {
+ return errors.ErrCannotEditInvoice
+ }
+
+ return nil
+}
diff --git a/invoice/invoice.go b/invoice/invoice.go
index fa8bb08..e2b8f7c 100644
--- a/invoice/invoice.go
+++ b/invoice/invoice.go
@@ -62,6 +62,7 @@ type Invoice struct {
BillingAddress InvoiceBillingAddress
ShippingAddress InvoiceShippingAddress
IsDraft bool
+ Items []InvoiceItem
// Transporter Transporter
// DueDate string
diff --git a/invoice/router.go b/invoice/router.go
index e231c0d..8e0a0ca 100644
--- a/invoice/router.go
+++ b/invoice/router.go
@@ -29,6 +29,6 @@ func Routes(route *gin.RouterGroup) {
g.POST("/", handleSaveInvoice)
g.DELETE("/:id", handleDelInvoice)
g.POST("/:id/item", addItem)
- //g.DELETE("/:invoice_id/item/:item_id", handleDelInvoice)
+ g.DELETE("/item/:id", removeItem)
}
}
diff --git a/invoice/service.go b/invoice/service.go
index cfb873f..099f6a0 100644
--- a/invoice/service.go
+++ b/invoice/service.go
@@ -22,7 +22,7 @@ import (
)
func getInvoice(invoice *Invoice, id uint) error {
- res := db.Preload("BillingAddress").Preload("ShippingAddress").Find(&invoice, id)
+ res := db.Preload("BillingAddress").Preload("ShippingAddress").Preload("Items").Find(&invoice, id)
// TODO: handle potential errors
if res.Error != nil {
@@ -75,6 +75,49 @@ func (i *Invoice) del() error {
return nil
}
+// also checks for ownership
+func getItemInvoice(itemId, userId uint) (uint, error) {
+ var invoiceId uint
+ res := db.
+ Model(&InvoiceItem{}).
+ Select("invoice_id").
+ Where("id = ?", itemId).
+ Find(&invoiceId)
+
+ // TODO: handle potential errors
+ if res.Error != nil {
+ return invoiceId, res.Error
+ }
+
+ if res.RowsAffected == 0 {
+ return invoiceId, e.ErrNotFound
+ }
+
+ err := checkInvoiceOwnership(invoiceId, userId)
+
+ if err != nil {
+ return invoiceId, err
+ }
+
+ return invoiceId, nil
+}
+
+func (i *InvoiceItem) del() error {
+ res := db.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
+ }
+
+ return nil
+}
+
func (i *InvoiceItem) upsert() error {
res := db.Save(i)
// TODO: handle potential errors
diff --git a/main.go b/main.go
index a1bd010..1a8b655 100644
--- a/main.go
+++ b/main.go
@@ -38,7 +38,7 @@ import (
"log"
)
-const OPENBILLS_VERSION = "v0.0.12"
+const OPENBILLS_VERSION = "v0.0.13"
func init() {
if viper.GetBool("production_mode") {