diff options
| -rw-r--r-- | auth/middleware.go | 2 | ||||
| -rw-r--r-- | customer/controller.go | 71 | ||||
| -rw-r--r-- | customer/customer.go | 3 | ||||
| -rw-r--r-- | customer/service.go | 7 | ||||
| -rw-r--r-- | customer/validators.go | 26 | ||||
| -rw-r--r-- | errors/errors.go | 4 | ||||
| -rw-r--r-- | errors/status.go | 6 | ||||
| -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 | ||||
| -rw-r--r-- | item/controller.go | 101 | ||||
| -rw-r--r-- | item/hooks.go | 13 | ||||
| -rw-r--r-- | item/item.go | 7 | ||||
| -rw-r--r-- | item/router.go | 1 | ||||
| -rw-r--r-- | item/service.go | 22 | ||||
| -rw-r--r-- | item/validators.go | 58 | ||||
| -rw-r--r-- | main.go | 2 | ||||
| -rw-r--r-- | user/validators.go | 45 | 
20 files changed, 59 insertions, 615 deletions
diff --git a/auth/middleware.go b/auth/middleware.go index 9a065d5..9ce5e12 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -70,8 +70,6 @@ func Authorize() gin.HandlerFunc {  			return  		} -		ctx.Set("UserID", claims.UserID) -  		ctx.Next()  	}  } diff --git a/customer/controller.go b/customer/controller.go index f2704bd..83423da 100644 --- a/customer/controller.go +++ b/customer/controller.go @@ -31,17 +31,7 @@ func handleGetSingleCustomer (ctx *gin.Context) {  		return  	} -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -  	var customer Customer -  	err = getCustomer(&customer, uint(id))  	if err != nil {  		ctx.Error(err) @@ -49,14 +39,7 @@ func handleGetSingleCustomer (ctx *gin.Context) {  		return  	} -	if customer.UserID != userId { -		ctx.Error(e.ErrForbidden) -		ctx.Abort() -		return -	} -  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": customer,  	})  } @@ -64,16 +47,7 @@ func handleGetSingleCustomer (ctx *gin.Context) {  func handleGetCustomers (ctx *gin.Context) {  	var customers []Customer -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) - -	err := getCustomers(&customers, userId) +	err := getCustomers(&customers)  	if err != nil {  		ctx.Error(err)  		ctx.Abort() @@ -81,7 +55,6 @@ func handleGetCustomers (ctx *gin.Context) {  	}  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": customers,  	})  } @@ -90,26 +63,6 @@ func handleSaveCustomer (ctx *gin.Context) {  	var customer Customer  	ctx.Bind(&customer) -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -	customer.UserID = userId // necessary even when editing, just in case if UserID was ommitted in the request - -	if customer.ID != 0 { -		// if customer is being edited, check ownership -		err := checkCustomerOwnership(customer.ID, userId) -	  if err != nil { -	  	ctx.Error(err) -	  	ctx.Abort() -	  	return -	  } -  } -  	err := customer.upsert()  	if err != nil {  		ctx.Error(err) @@ -118,7 +71,6 @@ func handleSaveCustomer (ctx *gin.Context) {  	}  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": customer,  	})  } @@ -133,23 +85,6 @@ func handleDelCustomer (ctx *gin.Context) {  	var customer Customer  	customer.ID = uint(id) -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -	customer.UserID = userId - -	err = checkCustomerOwnership(customer.ID, customer.UserID) -	if err != nil { -		ctx.Error(err) -		ctx.Abort() -		return -	} -  	err = customer.del()  	if err != nil {  		ctx.Error(err) @@ -157,7 +92,5 @@ func handleDelCustomer (ctx *gin.Context) {  		return  	} -	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success", -	}) +	ctx.JSON(http.StatusOK, nil)  } diff --git a/customer/customer.go b/customer/customer.go index 2303ae8..25c4645 100644 --- a/customer/customer.go +++ b/customer/customer.go @@ -21,7 +21,6 @@ import (  	"gorm.io/gorm"  	d "vidhukant.com/openbills/db"    u "vidhukant.com/openbills/util" -	"vidhukant.com/openbills/user"  )  var db *gorm.DB @@ -45,8 +44,6 @@ type CustomerShippingAddress struct {  type Customer struct {  	gorm.Model -	UserID            uint      `json:"-"` -	User              user.User `json:"-"`  	FirmName          string  	Gstin             string  	ContactName       string diff --git a/customer/service.go b/customer/service.go index 8cd2bde..a0ed4dc 100644 --- a/customer/service.go +++ b/customer/service.go @@ -37,8 +37,8 @@ func getCustomer(customer *Customer, id uint) error {  	return nil  } -func getCustomers(customers *[]Customer, userId uint) error { -	res := db.Where("user_id = ?", userId).Find(&customers) +func getCustomers(customers *[]Customer) error { +	res := db.Find(&customers)  	// TODO: handle potential errors  	if res.Error != nil { @@ -60,14 +60,13 @@ func (c *Customer) upsert() error {  }  func (c *Customer) del() error { -	res := db.Where("id = ? and user_id = ?", c.ID, c.UserID).Delete(c) +	res := db.Where("id = ?", c.ID).Delete(c)  	// 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  	} diff --git a/customer/validators.go b/customer/validators.go index b8c2a14..5693116 100644 --- a/customer/validators.go +++ b/customer/validators.go @@ -62,29 +62,3 @@ func (c *Customer) validate() error {  	return nil  } - -func checkCustomerOwnership(customerId, userId uint) error { -	var customer Customer -	err := db. -		Select("id", "user_id"). -		Where("id = ?", customerId). -		Find(&customer). -		Error - -	// TODO: handle potential errors -	if err != nil { -		return err -  } - -	// customer doesn't exist -	if customer.ID == 0 { -		return errors.ErrNotFound -	} - -	// user doesn't own this customer -	if customer.UserID != userId { -		return errors.ErrForbidden -	} - -	return nil -} diff --git a/errors/errors.go b/errors/errors.go index 0d88490..17afdfe 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -62,11 +62,7 @@ var (  	ErrCannotEditInvoice      = errors.New("This Invoice Cannot Be Edited Now")  	// 409 -	ErrNonUniqueGSTIN         = errors.New("GSTIN Must Be Unique") -	ErrNonUniquePhone         = errors.New("Phone Number Is Already In Use") -	ErrNonUniqueEmail         = errors.New("Email Address Is Already In Use")  	ErrNonUniqueUsername      = errors.New("Username Is Already In Use") -	ErrNonUniqueWebsite       = errors.New("Website Is Already In Use")  	ErrNonUniqueBrandName     = errors.New("Brand Name Is Already In Use")  	ErrNonUniqueBrandItem     = errors.New("Item With Same Name And Brand Already Exists")  	ErrNonUniqueInvoiceNumber = errors.New("Invoice Number Must Be Unique") diff --git a/errors/status.go b/errors/status.go index 47820b5..a874423 100644 --- a/errors/status.go +++ b/errors/status.go @@ -70,11 +70,7 @@ func StatusCodeFromErr(err error) int {  	}  	// 409 -	if errors.Is(err, ErrNonUniqueGSTIN) || -		errors.Is(err, ErrNonUniquePhone) || -		errors.Is(err, ErrNonUniqueUsername) || -		errors.Is(err, ErrNonUniqueEmail) || -		errors.Is(err, ErrNonUniqueWebsite) || +	if errors.Is(err, ErrNonUniqueUsername) ||  		errors.Is(err, ErrNonUniqueBrandName) ||  		errors.Is(err, ErrNonUniqueInvoiceNumber) ||  		errors.Is(err, ErrNonUniqueBrandItem) { 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 -} diff --git a/item/controller.go b/item/controller.go index 9993688..bb2eb94 100644 --- a/item/controller.go +++ b/item/controller.go @@ -31,17 +31,8 @@ func handleGetBrandItems (ctx *gin.Context) {  		return  	} -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -  	var items []SavedItem -	err = getBrandItems(&items, uint(id), userId) +	err = getBrandItems(&items, uint(id))  	if err != nil {  		ctx.Error(err)  		ctx.Abort() @@ -49,7 +40,6 @@ func handleGetBrandItems (ctx *gin.Context) {  	}  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": items,  	})  } @@ -57,16 +47,7 @@ func handleGetBrandItems (ctx *gin.Context) {  func handleGetBrands (ctx *gin.Context) {  	var brands []Brand -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) - -	err := getBrands(&brands, userId) +	err := getBrands(&brands)  	if err != nil {  		ctx.Error(err)  		ctx.Abort() @@ -74,7 +55,6 @@ func handleGetBrands (ctx *gin.Context) {  	}  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": brands,  	})  } @@ -83,16 +63,6 @@ func handleSaveBrand (ctx *gin.Context) {  	var brand Brand  	ctx.Bind(&brand) -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -	brand.UserID = userId -  	err := brand.upsert()  	if err != nil {  		ctx.Error(err) @@ -101,7 +71,6 @@ func handleSaveBrand (ctx *gin.Context) {  	}  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": brand,  	})  } @@ -116,24 +85,6 @@ func handleDelBrand (ctx *gin.Context) {  	var brand Brand  	brand.ID = uint(id) - -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -	brand.UserID = userId - -	err = checkBrandOwnership(brand.ID, brand.UserID) -	if err != nil { -		ctx.Error(err) -		ctx.Abort() -		return -	} -  	err = brand.del()  	if err != nil {  		ctx.Error(err) @@ -141,24 +92,13 @@ func handleDelBrand (ctx *gin.Context) {  		return  	} -	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success", -	}) +	ctx.JSON(http.StatusOK, nil)  }  func handleGetItems (ctx *gin.Context) {  	var items []SavedItem -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) - -	err := getItems(&items, userId) +	err := getItems(&items)  	if err != nil {  		ctx.Error(err)  		ctx.Abort() @@ -166,7 +106,6 @@ func handleGetItems (ctx *gin.Context) {  	}  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": items,  	})  } @@ -175,16 +114,6 @@ func handleSaveItem (ctx *gin.Context) {  	var item SavedItem  	ctx.Bind(&item) -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -	item.UserID = userId -  	err := item.upsert()  	if err != nil {  		ctx.Error(err) @@ -193,7 +122,6 @@ func handleSaveItem (ctx *gin.Context) {  	}  	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success",  		"data": item,  	})  } @@ -208,23 +136,6 @@ func handleDelItem (ctx *gin.Context) {  	var item SavedItem  	item.ID = uint(id) -	uId, ok := ctx.Get("UserID") -	if !ok { -		ctx.Error(e.ErrUnauthorized) -		ctx.Abort() -		return -	} - -	userId := uId.(uint) -	item.UserID = userId - -	err = checkItemOwnership(item.ID, item.UserID) -	if err != nil { -		ctx.Error(err) -		ctx.Abort() -		return -	} -  	err = item.del()  	if err != nil {  		ctx.Error(err) @@ -232,7 +143,5 @@ func handleDelItem (ctx *gin.Context) {  		return  	} -	ctx.JSON(http.StatusOK, gin.H{ -		"message": "success", -	}) +	ctx.JSON(http.StatusOK, nil)  } diff --git a/item/hooks.go b/item/hooks.go index 74b6860..5056cb1 100644 --- a/item/hooks.go +++ b/item/hooks.go @@ -20,22 +20,11 @@ package item  import (  	"gorm.io/gorm"  	"vidhukant.com/openbills/errors" -	e "errors"  )  func (i *SavedItem) BeforeSave(tx *gorm.DB) error {  	var err error -	// also checks if brand actually exists -	err = checkBrandOwnership(i.BrandID, i.UserID) -	if err != nil { -		if e.Is(err, errors.ErrBrandNotFound) { -			// this error has a better error message for this case -			return errors.ErrBrandNotFound -		} -		return err -	} -  	err = i.validate()  	if err != nil {  		return err @@ -60,7 +49,7 @@ func (b *Brand) BeforeDelete(tx *gorm.DB) error {  	}  	// delete all items -	err := db.Where("brand_id = ? and user_id = ?", b.ID, b.UserID).Delete(&SavedItem{}).Error +	err := db.Where("brand_id = ?", b.ID).Delete(&SavedItem{}).Error  	if err != nil {  		return err  	} diff --git a/item/item.go b/item/item.go index 3f911fa..617a662 100644 --- a/item/item.go +++ b/item/item.go @@ -20,7 +20,6 @@ package item  import (  	"gorm.io/gorm"  	d "vidhukant.com/openbills/db" -	"vidhukant.com/openbills/user"  )  var db *gorm.DB @@ -32,8 +31,6 @@ func init() {  type Brand struct {  	gorm.Model -	UserID uint      `json:"-"` -	User   user.User `json:"-"`  	Name   string  } @@ -41,7 +38,7 @@ type Item struct {  	Name          string  	Description   string  	HSN           string -	UnitOfMeasure string // TODO: probably has to be a custom type +	UnitOfMeasure string  	UnitPrice     string // float  	GSTPercentage string // float  } @@ -51,6 +48,4 @@ type SavedItem struct {  	Item  	BrandID            uint  	Brand              Brand -	UserID             uint      `json:"-"` -	User               user.User `json:"-"`  } diff --git a/item/router.go b/item/router.go index fab973f..b953d09 100644 --- a/item/router.go +++ b/item/router.go @@ -33,7 +33,6 @@ func Routes(route *gin.RouterGroup) {  	i := route.Group("/item")  	{  		i.GET("/", handleGetItems) -		//i.GET("/:id", handleGetBrandItems)  		i.POST("/", handleSaveItem)  		i.DELETE("/:id", handleDelItem)  	} diff --git a/item/service.go b/item/service.go index 80faff0..0b2afaf 100644 --- a/item/service.go +++ b/item/service.go @@ -21,12 +21,7 @@ import (  	"vidhukant.com/openbills/errors"  ) -func getBrandItems(items *[]SavedItem, id, userId uint) error { -	err := checkBrandOwnership(id, userId) -	if err != nil { -		return err -	} - +func getBrandItems(items *[]SavedItem, id uint) error {  	// get items  	res := db.Model(&SavedItem{}).Where("brand_id = ?", id).Find(&items) @@ -35,7 +30,6 @@ func getBrandItems(items *[]SavedItem, id, userId uint) 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 errors.ErrEmptyResponse  	} @@ -43,8 +37,8 @@ func getBrandItems(items *[]SavedItem, id, userId uint) error {  	return nil  } -func getBrands(brands *[]Brand, userId uint) error { -	res := db.Where("user_id = ?", userId).Find(&brands) +func getBrands(brands *[]Brand) error { +	res := db.Find(&brands)  	// TODO: handle potential errors  	if res.Error != nil { @@ -66,14 +60,13 @@ func (b *Brand) upsert() error {  func (b *Brand) del() error {  	// delete brand -	res := db.Where("id = ? and user_id = ?", b.ID, b.UserID).Delete(b) +	res := db.Where("id = ?", b.ID).Delete(b)  	// 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 errors.ErrNotFound  	} @@ -81,8 +74,8 @@ func (b *Brand) del() error {  	return nil  } -func getItems(items *[]SavedItem, userId uint) error { -	res := db.Where("user_id = ?", userId).Preload("Brand").Find(&items) +func getItems(items *[]SavedItem) error { +	res := db.Preload("Brand").Find(&items)  	// TODO: handle potential errors  	if res.Error != nil { @@ -103,14 +96,13 @@ func (i *SavedItem) upsert() error {  }  func (i *SavedItem) 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 errors.ErrNotFound  	} diff --git a/item/validators.go b/item/validators.go index b808ae4..63c254f 100644 --- a/item/validators.go +++ b/item/validators.go @@ -32,11 +32,11 @@ func (b *Brand) validate() error {  		return errors.ErrEmptyBrandName  	} -	// make sure GSTIN is unique +	// make sure brand name is unique  	var count int64  	err := db.Model(&Brand{}).  		Select("name"). -		Where("name = ? and user_id = ?", b.Name, b.UserID). +		Where("name = ?", b.Name).  		Count(&count).  		Error @@ -75,7 +75,7 @@ func (i *SavedItem) validate() error {  	var count int64  	err = db.Model(&SavedItem{}).  		Select("name, brand_id"). -		Where("brand_id = ? and name = ? and user_id = ?", i.BrandID, i.Name, i.UserID). +		Where("brand_id = ? and name = ?", i.BrandID, i.Name).  		Count(&count).  		Error @@ -89,55 +89,3 @@ func (i *SavedItem) validate() error {  	return nil  } - -func checkBrandOwnership(brandId, userId uint) error { -	var brand Brand -	err := db. -		Select("id", "user_id"). -		Where("id = ?", brandId). -		Find(&brand). -		Error - -	// TODO: handle potential errors -	if err != nil { -		return err -  } - -	// brand doesn't exist -	if brand.ID == 0 { -		return errors.ErrNotFound -	} - -	// user doesn't own this brand -	if brand.UserID != userId { -		return errors.ErrForbidden -	} - -	return nil -} - -func checkItemOwnership(itemId, userId uint) error { -	var item SavedItem -	err := db. -		Select("id", "user_id"). -		Where("id = ?", itemId). -		Find(&item). -		Error - -	// TODO: handle potential errors -	if err != nil { -		return err -  } - -	// item doesn't exist -	if item.ID == 0 { -		return errors.ErrNotFound -	} - -	// user doesn't own this item -	if item.UserID != userId { -		return errors.ErrForbidden -	} - -	return nil -} @@ -38,7 +38,7 @@ import (  	"log"  ) -const OPENBILLS_VERSION = "v0.16.0" +const OPENBILLS_VERSION = "v0.17.0"  func init() {  	if !viper.GetBool("debug_mode") { diff --git a/user/validators.go b/user/validators.go index b54457f..e497122 100644 --- a/user/validators.go +++ b/user/validators.go @@ -19,7 +19,6 @@ package user  import (  	"strings" -	e "errors"  	"github.com/spf13/viper"  	"vidhukant.com/openbills/errors"  	"vidhukant.com/openbills/util" @@ -59,41 +58,6 @@ func validateUsername(username string) error {    return nil  } -// NOTE: very inefficient and really really really dumb but it works -// TODO: find a better (or even a remotely good) way -func validateUserField(field, value string) error { -	if value != "" { -		var count int64 -		err := db.Model(&User{}). -			Where(field + " = ?", value). -			Count(&count). -			Error - -		if err != nil { -			return err -		} - -		if count > 0 { -			switch(field) { -			case "username": -				return errors.ErrNonUniqueUsername -      case "phone": -        return errors.ErrNonUniquePhone -			case "email": -				return errors.ErrNonUniqueEmail -      case "website": -        return errors.ErrNonUniqueWebsite -      case "gstin": -        return errors.ErrNonUniqueGSTIN -			default: -				return e.New(field + " is not unique") -			} -		} -	} - -	return nil -} -  func (u *User) validate() error {  	u.Username = strings.TrimSpace(u.Username)  	u.Email = strings.TrimSpace(u.Email) @@ -102,8 +66,6 @@ func (u *User) validate() error {    u.Gstin = strings.TrimSpace(u.Gstin)  	u.IsVerified = false -	// TODO: validate username length and stuff -      // don't validate if GSTIN is empty    if u.Gstin != "" && !util.ValidateGstin(u.Gstin) {      return errors.ErrInvalidGSTIN @@ -146,12 +108,5 @@ func (u *User) validate() error {      return err    } -	for _, i := range [][]string{{"username", u.Username}, {"email", u.Email}, {"website", u.Website}, {"gstin", u.Gstin}, {"phone", u.Phone}} { -    err := validateUserField(i[0], i[1]) -		if err != nil { -			return err -		} -	} -  	return nil  }  |