diff options
author | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-13 01:32:27 +0530 |
---|---|---|
committer | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-13 01:32:27 +0530 |
commit | 0f435049cb3cc6900d881c5dce43bec3a1e60e2e (patch) | |
tree | 374950fba5605ea8411da428ac94b1deef4e2809 | |
parent | fb9ba155438100f295fdb563ad955151ee038ad3 (diff) |
-rw-r--r-- | errors/errors.go | 1 | ||||
-rw-r--r-- | errors/status.go | 1 | ||||
-rw-r--r-- | invoice/invoice.go | 1 | ||||
-rw-r--r-- | item/hooks.go | 24 | ||||
-rw-r--r-- | item/item.go | 29 | ||||
-rw-r--r-- | item/service.go | 4 | ||||
-rw-r--r-- | item/validators.go | 44 | ||||
-rw-r--r-- | main.go | 2 | ||||
-rw-r--r-- | util/address.go | 26 |
9 files changed, 84 insertions, 48 deletions
diff --git a/errors/errors.go b/errors/errors.go index de18bf4..3c37e08 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -44,6 +44,7 @@ var ( ErrUsernameTooShort = errors.New("Username Is Too Short") ErrUsernameTooLong = errors.New("Username Is Too Long") ErrInvalidLoginMethod = errors.New("Login Method Can Only Be 'email' Or 'username'") + ErrNoItemVariants = errors.New("An item should have at least one variant") // 401 ErrWrongPassword = errors.New("Wrong Password") diff --git a/errors/status.go b/errors/status.go index 306ea27..0bbb7ba 100644 --- a/errors/status.go +++ b/errors/status.go @@ -41,6 +41,7 @@ func StatusCodeFromErr(err error) int { errors.Is(err, ErrPasswordTooShort) || errors.Is(err, ErrPasswordTooLong) || errors.Is(err, ErrInvalidLoginMethod) || + errors.Is(err, ErrNoItemVariants) || errors.Is(err, ErrInvalidGSTPercentage) { return http.StatusBadRequest } diff --git a/invoice/invoice.go b/invoice/invoice.go index 9cbc4e7..786f6a2 100644 --- a/invoice/invoice.go +++ b/invoice/invoice.go @@ -21,7 +21,6 @@ import ( "gorm.io/gorm" "time" d "vidhukant.com/openbills/db" - u "vidhukant.com/openbills/util" ) var db *gorm.DB 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 } @@ -38,7 +38,7 @@ import ( "log" ) -const OPENBILLS_VERSION = "v0.21.0" +const OPENBILLS_VERSION = "v0.22.0" func init() { if !viper.GetBool("debug_mode") { diff --git a/util/address.go b/util/address.go deleted file mode 100644 index 45c80c9..0000000 --- a/util/address.go +++ /dev/null @@ -1,26 +0,0 @@ -/* openbills - Server for web based Libre Billing Software - * Copyright (C) 2023-2024 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -package util - -type Address struct { - AddressText string - City string - State string - PostalCode string - Country string -} |