package godown import ( "errors" "fmt" "gorm.io/gorm" "server/global" ) type Manifest struct { global.GVA_MODEL ManifestGenre string `json:"manifestGenre" gorm:"comment:'货单类型'"` Title string `json:"title" gorm:"comment:'标题'"` Cargos []Cargo `json:"cargos" gorm:"foreignKey:ManifestId"` Custodian string `json:"custodian" gorm:"comment:负责人"` Remarks string `json:"remarks" gorm:"comment:'备注'"` } func (Manifest) TableName() string { return "manifest" } func QueryAllManifest() (manifests []Manifest, err error) { err = global.GVA_DB.Model(&Manifest{}).Find(&manifests).Error return } func QueryManifestList(limit, offset int, genre, title string) (manifests []Manifest, total int64, err error) { // 创建db db := global.GVA_DB.Model(&Manifest{}) // 如果有条件搜索 下方会自动创建搜索语句 if genre != "" { db = db.Where("manifest_genre LIKE ?", "%"+genre+"%") } if title != "" { db = db.Where("title LIKE ?", "%"+title+"%") } err = db.Count(&total).Error if err != nil { return } err = db.Order("id desc").Limit(limit).Offset(offset).Preload("Cargos").Preload("Cargos.Commodity").Preload("Cargos.Warehouse").Find(&manifests).Error return manifests, total, err } func (m Manifest) CreateManifest() error { return global.GVA_DB.Create(&m).Error } func (m Manifest) UpdateManifest() error { return global.GVA_DB.Where("id = ?", m.ID).Updates(&m).Error } func DeleteManifest(id int) error { return global.GVA_DB.Where("id = ?", id).Unscoped().Delete(&Manifest{}).Error } // CreateInboundManifest 入库 func CreateInboundManifest(manifestGenre, title, custodian string, cargos []Cargo) error { // 开启事务 return global.GVA_DB.Transaction(func(tx *gorm.DB) error { // 1. 创建入库货单 manifest := Manifest{ ManifestGenre: manifestGenre, // 如 "采购入库" Title: title, Custodian: custodian, Cargos: cargos, } if err := tx.Create(&manifest).Error; err != nil { return fmt.Errorf("创建货单失败: %v", err) } // 2. 更新库存(逐个货物处理) for _, cargo := range manifest.Cargos { // 检查是否已存在相同商品、仓库、库区、库位的记录 var goods Goods err := tx.Where("good_id = ?", cargo.GoodsId). First(&goods).Error if err == nil { // 存在记录:增加数量 goods.Number += cargo.Number if err := tx.Save(&goods).Error; err != nil { return fmt.Errorf("更新库存失败: %v", err) } } else if errors.Is(err, gorm.ErrRecordNotFound) { // 不存在记录 return fmt.Errorf("查询库存失败: %v", err) } else { return fmt.Errorf("查询库存失败: %v", err) } } return nil }) } // CreateOutboundManifest 出库 func CreateOutboundManifest(manifestGenre, title, custodian string, cargos []Cargo) error { // 开启事务 return global.GVA_DB.Transaction(func(tx *gorm.DB) error { // 1. 检查库存是否充足(预扣减检查) for _, cargo := range cargos { var goods Goods if err := tx.Where("good_id = ?", cargo.GoodsId). First(&goods).Error; err != nil { return fmt.Errorf("库存记录不存在: %v", err) } if goods.Number < cargo.Number { return fmt.Errorf("商品 %v 库存不足(当前: %d,需要: %d)", cargo.Goods.Name, goods.Number, cargo.Number) } } // 2. 创建出库货单 manifest := Manifest{ ManifestGenre: manifestGenre, // 如 "销售出库" Title: title, Custodian: custodian, Cargos: cargos, } if err := tx.Create(&manifest).Error; err != nil { return fmt.Errorf("创建货单失败: %v", err) } // 3. 扣减库存 for _, cargo := range manifest.Cargos { if err := tx.Model(&Goods{}). Where("goods_id = ?", cargo.GoodsId). Update("number", gorm.Expr("number - ?", cargo.Number)). Error; err != nil { return fmt.Errorf("扣减库存失败: %v", err) } } return nil }) }