package service import ( "fmt" "github.com/wmms/wmms/internal/model" "github.com/wmms/wmms/internal/repository" ) // inventoryScopeActiveStatus 是仓库、库位"启用"的取值,与 scripts/init.sql 的 // status 默认值一致。只有启用状态的这一组维度才允许改变库存。 const inventoryScopeActiveStatus = "active" // ResolveInventoryScope 由数据库解析当前公司唯一的仓库和库位,作为库存读写的服务端 // 维度来源,不接受前端传入的仓库、库位 ID。 // // requireActive=true 用于会改变库存的操作(入出库、审批自动出库、库存预警调整): // 仓库和库位都必须存在且启用,否则返回包着 ErrInventoryScopeUnavailable 的错误, // 由 Handler 映射为 409 并给出具体配置提示(缺仓库 / 缺库位 / 仓库停用 / 库位停用)。 // // requireActive=false 只用于只读校验场景:停用的仓库、库位仍返回其维度,便于核验 // 已确认的历史数据。读取列表、流水等方法不调用本函数——未配置或停用仓库、库位时, // 它们仍按公司条件返回已有数据或空列表,不借用其他公司的仓库、库位,也不回退 // 历史默认编码(DEFAULT / MAIN / ID 1)。 func ResolveInventoryScope(organizationID int64, requireActive bool) (model.InventoryScope, error) { // 一个公司最多一个仓库、一个仓库最多一个库位由数据库唯一约束保证;Summary 在 // 违反该不变量时返回错误,而不是随意取第一条。 summary, err := repository.NewWarehouseRepository().Summary(organizationID) if err != nil { return model.InventoryScope{}, err } if summary == nil { return model.InventoryScope{}, fmt.Errorf("%w:请先配置本公司仓库", ErrInventoryScopeUnavailable) } if requireActive && summary.Status != inventoryScopeActiveStatus { return model.InventoryScope{}, fmt.Errorf("%w:本公司仓库已停用", ErrInventoryScopeUnavailable) } if summary.Location == nil { return model.InventoryScope{}, fmt.Errorf("%w:请先配置本公司仓库的库位", ErrInventoryScopeUnavailable) } if requireActive && summary.Location.Status != inventoryScopeActiveStatus { return model.InventoryScope{}, fmt.Errorf("%w:本公司库位已停用", ErrInventoryScopeUnavailable) } return model.InventoryScope{ OrganizationID: organizationID, WarehouseID: summary.ID, LocationID: summary.Location.ID, }, nil }