material_manage_system/internal/repository/organization_defaults.go
文睿 张 3cc783b5ff 物料数据迁移,并让每个公司自带默认单位与仓库
数据迁移(北京 / 武汉两个 SQLite 物料库 → wmms)
- 北京进默认组织、武汉单独建组织:两套分类编码完全相同但含义不同(北京 A01=标准件,
  武汉 A01=机加工件),共存会撞 material_categories 的组织内编码唯一约束
- 199 条物料、37 个企业、45 条变更日志,以及各分类的 code_rules.next_sequence
  (对齐到已导入的最大序号 +1,否则用户新增物料会撞上已有编码)
- 迁移段并入 scripts/init.sql 末尾,空库初始化即得完整数据

公司默认数据
- 新建公司时种入 32 个物料单位 + 默认仓库 + 主库位,与建公司同事务,
  种一半失败会整体回滚(否则留下一个没单位、又占着公司编码的组织)
- 单位在后端按公司隔离(MaterialRepo.IsActiveUnit 要求物料引用的单位属于本公司),
  此前新建的公司连单位下拉都是空的,物料的 base_unit_id 也无处可指
- init.sql 的单位段补齐「块」「Pcs」,与代码里的清单保持逐条一致

默认组织更名:默认公司组织 → 北京
2026-10-14 16:05:36 +08:00

83 lines
3.1 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 repository
import (
"database/sql"
"github.com/wmms/wmms/internal/model"
)
// defaultMaterialUnits 是每个公司开箱可用的物料单位,与 scripts/init.sql 里给默认
// 组织种的那套逐条一致(含后补的「块」与「Pcs」)。
//
// 单位在后端是按公司隔离的:MasterDataRepository.ListUnits 按 organization_id
// 过滤,MaterialRepo.IsActiveUnit 还要求物料引用的单位必须属于同一
// 公司。所以新建公司时必须把这份清单一起种下去,否则新公司连单位下拉都是空的,
// 物料的 base_unit_id 也无处可指。
var defaultMaterialUnits = []model.Unit{
{Code: "个", Name: "个"},
{Code: "件", Name: "件"},
{Code: "只", Name: "只"},
{Code: "支", Name: "支"},
{Code: "根", Name: "根"},
{Code: "条", Name: "条"},
{Code: "片", Name: "片"},
{Code: "张", Name: "张"},
{Code: "套", Name: "套"},
{Code: "台", Name: "台"},
{Code: "对", Name: "对"},
{Code: "双", Name: "双"},
{Code: "包", Name: "包"},
{Code: "袋", Name: "袋"},
{Code: "盒", Name: "盒"},
{Code: "箱", Name: "箱"},
{Code: "瓶", Name: "瓶"},
{Code: "罐", Name: "罐"},
{Code: "桶", Name: "桶"},
{Code: "卷", Name: "卷"},
{Code: "块", Name: "块"},
{Code: "Pcs", Name: "件"},
// 重量、容量、长度、面积保留 3 位小数,计数类单位是整数。
{Code: "g", Name: "克", PrecisionScale: 3},
{Code: "kg", Name: "千克", PrecisionScale: 3},
{Code: "t", Name: "吨", PrecisionScale: 3},
{Code: "mL", Name: "毫升", PrecisionScale: 3},
{Code: "L", Name: "升", PrecisionScale: 3},
{Code: "m³", Name: "立方米", PrecisionScale: 3},
{Code: "mm", Name: "毫米", PrecisionScale: 3},
{Code: "cm", Name: "厘米", PrecisionScale: 3},
{Code: "m", Name: "米", PrecisionScale: 3},
{Code: "m²", Name: "平方米", PrecisionScale: 3},
}
// seedOrganizationDefaultsTx 给新公司种上开箱可用的主数据:上面那份物料单位,
// 外加一个默认仓库和一个主库位。仓库与库位各只允许一个(init.sql 里有对应的唯一键
// uk_warehouses_organization / uk_warehouse_locations_warehouse),所以固定给一对。
//
// 走事务是为了和 organizations 的插入同生共死:种一半失败会留下一个既没单位、
// 又已经占用了公司编码的组织,用户重试还会撞 uk_organizations_code。
func seedOrganizationDefaultsTx(tx *sql.Tx, organizationID int64) error {
for _, unit := range defaultMaterialUnits {
if _, err := tx.Exec(
`INSERT INTO units (organization_id, code, name, precision_scale, status) VALUES (?, ?, ?, ?, 'active')`,
organizationID, unit.Code, unit.Name, unit.PrecisionScale); err != nil {
return err
}
}
result, err := tx.Exec(
`INSERT INTO warehouses (organization_id, code, name, status) VALUES (?, 'DEFAULT', '默认仓库', 'active')`,
organizationID)
if err != nil {
return err
}
warehouseID, err := result.LastInsertId()
if err != nil {
return err
}
_, err = tx.Exec(
`INSERT INTO warehouse_locations (warehouse_id, code, name, status) VALUES (?, 'MAIN', '主库位', 'active')`,
warehouseID)
return err
}