manifest.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package godown
  2. import (
  3. "errors"
  4. "fmt"
  5. "gorm.io/gorm"
  6. "server/global"
  7. )
  8. type Manifest struct {
  9. global.GVA_MODEL
  10. ManifestGenre string `json:"manifestGenre" gorm:"comment:'货单类型'"`
  11. Title string `json:"title" gorm:"comment:'标题'"`
  12. Cargos []Cargo `json:"cargos" gorm:"foreignKey:ManifestId"`
  13. Custodian string `json:"custodian" gorm:"comment:负责人"`
  14. Remarks string `json:"remarks" gorm:"comment:'备注'"`
  15. }
  16. func (Manifest) TableName() string {
  17. return "manifest"
  18. }
  19. func QueryAllManifest() (manifests []Manifest, err error) {
  20. err = global.GVA_DB.Model(&Manifest{}).Find(&manifests).Error
  21. return
  22. }
  23. func QueryManifestList(limit, offset int, genre, title string) (manifests []Manifest, total int64, err error) {
  24. // 创建db
  25. db := global.GVA_DB.Model(&Manifest{})
  26. // 如果有条件搜索 下方会自动创建搜索语句
  27. if genre != "" {
  28. db = db.Where("manifest_genre LIKE ?", "%"+genre+"%")
  29. }
  30. if title != "" {
  31. db = db.Where("title LIKE ?", "%"+title+"%")
  32. }
  33. err = db.Count(&total).Error
  34. if err != nil {
  35. return
  36. }
  37. err = db.Order("id desc").Limit(limit).Offset(offset).Preload("Cargos").Preload("Cargos.Commodity").Preload("Cargos.Warehouse").Find(&manifests).Error
  38. return manifests, total, err
  39. }
  40. func (m Manifest) CreateManifest() error {
  41. return global.GVA_DB.Create(&m).Error
  42. }
  43. func (m Manifest) UpdateManifest() error {
  44. return global.GVA_DB.Where("id = ?", m.ID).Updates(&m).Error
  45. }
  46. func DeleteManifest(id int) error {
  47. return global.GVA_DB.Where("id = ?", id).Unscoped().Delete(&Manifest{}).Error
  48. }
  49. // CreateInboundManifest 入库
  50. func CreateInboundManifest(manifestGenre, title, custodian string, cargos []Cargo) error {
  51. // 开启事务
  52. return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  53. // 1. 创建入库货单
  54. manifest := Manifest{
  55. ManifestGenre: manifestGenre, // 如 "采购入库"
  56. Title: title,
  57. Custodian: custodian,
  58. Cargos: cargos,
  59. }
  60. if err := tx.Create(&manifest).Error; err != nil {
  61. return fmt.Errorf("创建货单失败: %v", err)
  62. }
  63. // 2. 更新库存(逐个货物处理)
  64. for _, cargo := range manifest.Cargos {
  65. // 检查是否已存在相同商品、仓库、库区、库位的记录
  66. var goods Goods
  67. err := tx.Where("good_id = ?",
  68. cargo.GoodsId).
  69. First(&goods).Error
  70. if err == nil {
  71. // 存在记录:增加数量
  72. goods.Number += cargo.Number
  73. if err := tx.Save(&goods).Error; err != nil {
  74. return fmt.Errorf("更新库存失败: %v", err)
  75. }
  76. } else if errors.Is(err, gorm.ErrRecordNotFound) {
  77. // 不存在记录
  78. return fmt.Errorf("查询库存失败: %v", err)
  79. } else {
  80. return fmt.Errorf("查询库存失败: %v", err)
  81. }
  82. }
  83. return nil
  84. })
  85. }
  86. // CreateOutboundManifest 出库
  87. func CreateOutboundManifest(manifestGenre, title, custodian string, cargos []Cargo) error {
  88. // 开启事务
  89. return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
  90. // 1. 检查库存是否充足(预扣减检查)
  91. for _, cargo := range cargos {
  92. var goods Goods
  93. if err := tx.Where("good_id = ?",
  94. cargo.GoodsId).
  95. First(&goods).Error; err != nil {
  96. return fmt.Errorf("库存记录不存在: %v", err)
  97. }
  98. if goods.Number < cargo.Number {
  99. return fmt.Errorf("商品 %v 库存不足(当前: %d,需要: %d)",
  100. cargo.Goods.Name, goods.Number, cargo.Number)
  101. }
  102. }
  103. // 2. 创建出库货单
  104. manifest := Manifest{
  105. ManifestGenre: manifestGenre, // 如 "销售出库"
  106. Title: title,
  107. Custodian: custodian,
  108. Cargos: cargos,
  109. }
  110. if err := tx.Create(&manifest).Error; err != nil {
  111. return fmt.Errorf("创建货单失败: %v", err)
  112. }
  113. // 3. 扣减库存
  114. for _, cargo := range manifest.Cargos {
  115. if err := tx.Model(&Goods{}).
  116. Where("goods_id = ?",
  117. cargo.GoodsId).
  118. Update("number", gorm.Expr("number - ?", cargo.Number)).
  119. Error; err != nil {
  120. return fmt.Errorf("扣减库存失败: %v", err)
  121. }
  122. }
  123. return nil
  124. })
  125. }