material_manage_system/internal/service/inventory_scope.go
2026-10-09 11:10:13 +08:00

50 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}