数据迁移(北京 / 武汉两个 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」,与代码里的清单保持逐条一致 默认组织更名:默认公司组织 → 北京
83 lines
3.1 KiB
Go
83 lines
3.1 KiB
Go
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
|
||
}
|