Skip to content
Snippets Groups Projects
inventary.go 2.55 KiB
Newer Older
  • Learn to ignore specific revisions
  • meskio's avatar
    meskio committed
    package db
    
    
    meskio's avatar
    meskio committed
    import (
    	"time"
    
    	"gorm.io/gorm"
    	"gorm.io/gorm/clause"
    )
    
    
    meskio's avatar
    meskio committed
    type Supplier struct {
    	gorm.Model
    
    meskio's avatar
    meskio committed
    	Name string `json:"name" gorm:"unique;index"`
    
    meskio's avatar
    meskio committed
    }
    
    
    meskio's avatar
    meskio committed
    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"`
    
    meskio's avatar
    meskio committed
    	SupplierID *uint              `json:"supplier_id"`
    
    meskio's avatar
    meskio committed
    	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
    
    meskio's avatar
    meskio committed
    }
    
    func (d *DB) ListSuppliers() (suppliers []Supplier, err error) {
    	err = d.db.Find(&suppliers).Error
    	return
    }
    
    meskio's avatar
    meskio committed
    
    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)
    
    meskio's avatar
    meskio committed
    			}
    			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
    }
    
    
    meskio's avatar
    meskio committed
    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).
    
    meskio's avatar
    meskio committed
    		Order("date desc").
    
    meskio's avatar
    meskio committed
    		Find(&inventaries).
    		Error
    	return
    }