Forked from
meskio / cicer
33 commits behind the upstream repository.
inventary.go 2.55 KiB
package db
import (
"time"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type Supplier struct {
gorm.Model
Name string `json:"name" gorm:"unique;index"`
}
type Inventary struct {
gorm.Model
MemberNum int `json:"-" gorm:"column:member"`
Member *Member `json:"member,omitempty" gorm:"foreignKey:MemberNum;references:Num"`
Date time.Time `json:"date"`
SupplierID *uint `json:"supplier_id"`
Supplier *Supplier `json:"supplier"`
Comment string `json:"comment"`
Products []InventaryProduct `json:"products"`
}
type InventaryProduct struct {
gorm.Model
InventaryID uint `json:"-"`
ProductCode int `json:"code" gorm:"column:product"`
Product *Product `json:"product" gorm:"foreignKey:ProductCode;references:Code"`
StockUpdate *int `json:"stock"`
Price *int `json:"price"`
}
func (d *DB) AddSupplier(supplier *Supplier) error {
return d.db.Create(supplier).Error
}
func (d *DB) ListSuppliers() (suppliers []Supplier, err error) {
err = d.db.Find(&suppliers).Error
return
}
func (d *DB) AddInventary(num int, inventary *Inventary) error {
inventary.Date = time.Now()
inventary.MemberNum = num
return d.db.Transaction(func(tx *gorm.DB) error {
for _, product := range inventary.Products {
query := tx.Model(&Product{}).
Where("code = ?", product.ProductCode)
if product.StockUpdate != nil {
query = query.Update("stock", gorm.Expr("stock + ?", *product.StockUpdate))
}
if product.Price != nil {
price, err := d.inventaryNewPrice(product)
if err != nil {
return err
}
query = query.Update("price", price)
}
err := query.Error
if err != nil {
return err
}
}
return tx.Create(inventary).Error
})
}
func (d *DB) inventaryNewPrice(product InventaryProduct) (int, error) {
if product.StockUpdate == nil || *product.StockUpdate == 0 {
return *product.Price, nil
}
existingProduct, err := d.GetProduct(product.ProductCode)
if err != nil {
return 0, err
}
price := ((existingProduct.Price * existingProduct.Stock) + (*product.Price * *product.StockUpdate)) / (existingProduct.Stock + *product.StockUpdate)
return price, nil
}
func (d *DB) GetInventary(id int) (inventary Inventary, err error) {
err = d.db.Preload("Products.Product").
Preload(clause.Associations).
First(&inventary, id).
Error
return
}
func (d *DB) ListInventary() (inventaries []Inventary, err error) {
err = d.db.Preload("Products.Product").
Preload(clause.Associations).
Order("date desc").
Find(&inventaries).
Error
return
}