Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
a15d1d93c8
@ -1477,9 +1477,15 @@ func (s *ProcessService) CreateSalesOrderWithDetail(req systemReq.SalesOrderCrea
|
|||||||
return fmt.Errorf("批量创建销售订单明细失败: %v", err)
|
return fmt.Errorf("批量创建销售订单明细失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 锁定库存
|
||||||
|
//for _, itemReq := range req.Items {
|
||||||
|
// if err := s.lockInventory(tx, invWarehouseID, itemReq.ProductID, itemReq.Quantity, now); err != nil {
|
||||||
|
// return fmt.Errorf("锁定库存失败[商品ID=%d]: %v", itemReq.ProductID, err)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
// 锁定库存
|
// 锁定库存
|
||||||
for _, itemReq := range req.Items {
|
for _, itemReq := range req.Items {
|
||||||
if err := s.lockInventory(tx, invWarehouseID, itemReq.ProductID, itemReq.Quantity, now); err != nil {
|
if err := s.lockInventoryByAppearance(tx, invWarehouseID, itemReq.ProductID, itemReq.Quantity, now); err != nil {
|
||||||
return fmt.Errorf("锁定库存失败[商品ID=%d]: %v", itemReq.ProductID, err)
|
return fmt.Errorf("锁定库存失败[商品ID=%d]: %v", itemReq.ProductID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3653,6 +3659,77 @@ func (s *ProcessService) processInventoryDetailOperationForAdjustment(tx *gorm.D
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lockInventoryByAppearance 按品相+ISBN匹配所有商品的库存进行锁定
|
||||||
|
func (s *ProcessService) lockInventoryByAppearance(tx *gorm.DB, warehouseID, productID, quantity int64, now int64) error {
|
||||||
|
var product models.Product
|
||||||
|
if err := tx.Where("id = ? AND is_del = 0", productID).First(&product).Error; err != nil {
|
||||||
|
return fmt.Errorf("查询商品信息失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchingProductIDs []int64
|
||||||
|
if err := tx.Model(&models.Product{}).
|
||||||
|
Where("barcode = ? AND appearance = ? AND is_del = 0", product.Barcode, product.Appearance).
|
||||||
|
Pluck("id", &matchingProductIDs).Error; err != nil {
|
||||||
|
return fmt.Errorf("查询同品相商品失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(matchingProductIDs) == 0 {
|
||||||
|
return fmt.Errorf("无匹配的商品记录")
|
||||||
|
}
|
||||||
|
|
||||||
|
var inventories []models.Inventory
|
||||||
|
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||||
|
Where("warehouse_id = ? AND product_id IN ? AND is_del = 0 AND quantity > locked_quantity",
|
||||||
|
warehouseID, matchingProductIDs).
|
||||||
|
Order("product_id ASC, expiry_date ASC, created_at ASC").
|
||||||
|
Find(&inventories).Error; err != nil {
|
||||||
|
return fmt.Errorf("查询可用库存失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(inventories) == 0 {
|
||||||
|
return fmt.Errorf("商品(barcode=%s,appearance=%d)在仓库ID=%d中无可用库存", product.Barcode, product.Appearance, warehouseID)
|
||||||
|
}
|
||||||
|
|
||||||
|
remainingLock := quantity
|
||||||
|
for i := range inventories {
|
||||||
|
if remainingLock <= 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
availableQty := inventories[i].Quantity - inventories[i].LockedQuantity
|
||||||
|
if availableQty <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
lockQty := availableQty
|
||||||
|
if lockQty > remainingLock {
|
||||||
|
lockQty = remainingLock
|
||||||
|
}
|
||||||
|
|
||||||
|
result := tx.Model(&inventories[i]).
|
||||||
|
Where("quantity - locked_quantity >= ?", lockQty).
|
||||||
|
UpdateColumns(map[string]interface{}{
|
||||||
|
"locked_quantity": gorm.Expr("locked_quantity + ?", lockQty),
|
||||||
|
"updated_at": now,
|
||||||
|
})
|
||||||
|
|
||||||
|
if result.Error != nil {
|
||||||
|
return fmt.Errorf("锁定库存失败: %v", result.Error)
|
||||||
|
}
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
return fmt.Errorf("库存已被其他事务修改,请重试")
|
||||||
|
}
|
||||||
|
|
||||||
|
remainingLock -= lockQty
|
||||||
|
}
|
||||||
|
|
||||||
|
if remainingLock > 0 {
|
||||||
|
return fmt.Errorf("可用库存不足,还需锁定:%d", remainingLock)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 执行事务(使用指定数据库)
|
// 执行事务(使用指定数据库)
|
||||||
func executeInTransactionWithDB(db *gorm.DB, txFunc func(*gorm.DB) error) error {
|
func executeInTransactionWithDB(db *gorm.DB, txFunc func(*gorm.DB) error) error {
|
||||||
tx := db.Begin()
|
tx := db.Begin()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user