aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/item
diff options
context:
space:
mode:
authorVidhu Kant Sharma <vidhukant@vidhukant.com>2025-10-13 01:32:27 +0530
committerVidhu Kant Sharma <vidhukant@vidhukant.com>2025-10-13 01:32:27 +0530
commit0f435049cb3cc6900d881c5dce43bec3a1e60e2e (patch)
tree374950fba5605ea8411da428ac94b1deef4e2809 /item
parentfb9ba155438100f295fdb563ad955151ee038ad3 (diff)
added item variantsHEADv0.22.0master
Diffstat (limited to 'item')
-rw-r--r--item/hooks.go24
-rw-r--r--item/item.go29
-rw-r--r--item/service.go4
-rw-r--r--item/validators.go44
4 files changed, 81 insertions, 20 deletions
diff --git a/item/hooks.go b/item/hooks.go
index cd8d47c..e05a6cb 100644
--- a/item/hooks.go
+++ b/item/hooks.go
@@ -19,6 +19,7 @@ package item
import (
"gorm.io/gorm"
+ "vidhukant.com/openbills/errors"
)
func (i *SavedItem) BeforeSave(tx *gorm.DB) error {
@@ -29,5 +30,28 @@ func (i *SavedItem) BeforeSave(tx *gorm.DB) error {
return err
}
+ if i.ID != 0 {
+ // delete all of this item's variants and save again
+ err = db.Where("saved_item_id = ?", i.ID).Delete(&ItemVariant{}).Error
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (i *SavedItem) BeforeDelete(tx *gorm.DB) error {
+ // if ID is 0, item won't be deleted
+ if i.ID == 0 {
+ return errors.ErrNoWhereCondition
+ }
+
+ // delete all of this item's variants before deleting this item
+ err := db.Where("saved_item_id = ?", i.ID).Delete(&ItemVariant{}).Error
+ if err != nil {
+ return err
+ }
+
return nil
}
diff --git a/item/item.go b/item/item.go
index 108187a..05ca8f6 100644
--- a/item/item.go
+++ b/item/item.go
@@ -1,5 +1,5 @@
/* openbills - Server for web based Libre Billing Software
- * Copyright (C) 2023 Vidhu Kant Sharma <vidhukant@vidhukant.com>
+ * Copyright (C) 2023-2025 Vidhu Kant Sharma <vidhukant@vidhukant.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,21 +27,30 @@ var db *gorm.DB
func init() {
db = d.DB
- db.AutoMigrate(&SavedItem{})
+ db.AutoMigrate(&SavedItem{}, &ItemVariant{})
}
-type Item struct {
+type ItemVariant struct {
+ // if the item has only one variant and showing it on
+ // the UI side (or when printing) isn't really necessary
+ // just set it as ".default" on the UI side so it can be
+ // optionally ignored. it's just a standard I'm setting
+ // here, the server gives no shit
+ ID uint `gorm:"primaryKey"`
+ SavedItemID uint `gorm:"index"`
+ VariantName string // "red color", "large size", "red color large size", etc
+ UnitPrice string // float
+ GSTPercentage string // float
+ QuantityInStock string // float
+}
+
+type SavedItem struct {
+ ID uint `gorm:"primaryKey"`
Name string
BrandName string
Category string
Description string
HSN string
UnitOfMeasure string
- UnitPrice string // float
- GSTPercentage string // float
-}
-
-type SavedItem struct {
- gorm.Model
- Item
+ Variants []ItemVariant
}
diff --git a/item/service.go b/item/service.go
index 7a622cb..87d73fa 100644
--- a/item/service.go
+++ b/item/service.go
@@ -22,7 +22,7 @@ import (
)
func getItem(item *SavedItem, id uint) error {
- res := db.Find(&item, id)
+ res := db.Preload("Variants").Find(&item, id)
// TODO: handle potential errors
if res.Error != nil {
@@ -37,7 +37,7 @@ func getItem(item *SavedItem, id uint) error {
}
func getItems(items *[]SavedItem) error {
- res := db.Find(&items)
+ res := db.Preload("Variants").Find(&items)
// TODO: handle potential errors
if res.Error != nil {
diff --git a/item/validators.go b/item/validators.go
index d098f4e..3541acb 100644
--- a/item/validators.go
+++ b/item/validators.go
@@ -1,5 +1,5 @@
/* openbills - Server for web based Libre Billing Software
- * Copyright (C) 2023 Vidhu Kant Sharma <vidhukant@vidhukant.com>
+ * Copyright (C) 2023-2025 Vidhu Kant Sharma <vidhukant@vidhukant.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +20,6 @@ package item
import (
"strconv"
"strings"
-
"vidhukant.com/openbills/errors"
)
@@ -32,20 +31,49 @@ func (i *SavedItem) validate() error {
i.Description = strings.TrimSpace(i.Description)
i.HSN = strings.TrimSpace(i.HSN)
i.UnitOfMeasure = strings.TrimSpace(i.UnitOfMeasure)
- i.UnitPrice = strings.TrimSpace(i.UnitPrice)
- i.GSTPercentage = strings.TrimSpace(i.GSTPercentage)
+
+ if len(i.Variants) == 0 {
+ return errors.ErrNoItemVariants
+ }
+
+ var validatedVariants []ItemVariant
+ for _, x := range i.Variants {
+ err := x.validate()
+ if err != nil {
+ return err
+ }
+
+ validatedVariants = append(validatedVariants, x)
+ }
+
+ i.Variants = validatedVariants
+
+ return nil
+}
+
+func (v *ItemVariant) validate() error {
+ v.VariantName = strings.TrimSpace(v.VariantName)
+ v.UnitPrice = strings.TrimSpace(v.UnitPrice)
+ v.GSTPercentage = strings.TrimSpace(v.GSTPercentage)
+ v.QuantityInStock = strings.TrimSpace(v.QuantityInStock)
var err error
// check if UnitPrice is float
- _, err = strconv.ParseFloat(i.UnitPrice, 64)
- if err != nil && strings.TrimSpace(i.UnitPrice) != "" {
+ _, err = strconv.ParseFloat(v.UnitPrice, 64)
+ if err != nil && v.UnitPrice != "" {
return errors.ErrInvalidUnitPrice
}
// check if GSTPercentage is float
- _, err = strconv.ParseFloat(i.GSTPercentage, 64)
- if err != nil && strings.TrimSpace(i.GSTPercentage) != "" {
+ _, err = strconv.ParseFloat(v.GSTPercentage, 64)
+ if err != nil && v.GSTPercentage != "" {
+ return errors.ErrInvalidGSTPercentage
+ }
+
+ // check if QuantityInStock is float
+ _, err = strconv.ParseFloat(v.QuantityInStock, 64)
+ if err != nil && v.QuantityInStock != "" {
return errors.ErrInvalidGSTPercentage
}